@@ -5,6 +5,7 @@ use crate::order_stat::OrderStatTest;
5
5
use crate :: payment:: PaymentTest ;
6
6
use crate :: rt_hist:: RtHist ;
7
7
use crate :: slev:: SlevTest ;
8
+ use crate :: utils:: SeqGen ;
8
9
use clap:: Parser ;
9
10
use fnck_sql:: db:: { DBTransaction , DataBaseBuilder } ;
10
11
use fnck_sql:: errors:: DatabaseError ;
@@ -20,8 +21,16 @@ mod order_stat;
20
21
mod payment;
21
22
mod rt_hist;
22
23
mod slev;
24
+ mod utils;
23
25
24
26
pub ( crate ) const ALLOW_MULTI_WAREHOUSE_TX : bool = true ;
27
+ pub ( crate ) const RT_LIMITS : [ Duration ; 5 ] = [
28
+ Duration :: from_millis ( 500 ) ,
29
+ Duration :: from_millis ( 500 ) ,
30
+ Duration :: from_millis ( 500 ) ,
31
+ Duration :: from_secs ( 8 ) ,
32
+ Duration :: from_secs ( 2 ) ,
33
+ ] ;
25
34
26
35
pub ( crate ) trait TpccTransaction < S : Storage > {
27
36
type Args ;
@@ -54,7 +63,7 @@ struct Args {
54
63
path : String ,
55
64
#[ clap( long, default_value = "5" ) ]
56
65
max_retry : usize ,
57
- #[ clap( long, default_value = "1080 " ) ]
66
+ #[ clap( long, default_value = "720 " ) ]
58
67
measure_time : u64 ,
59
68
#[ clap( long, default_value = "1" ) ]
60
69
num_ware : usize ,
@@ -72,6 +81,9 @@ fn main() -> Result<(), TpccError> {
72
81
Load :: load_ord ( & mut rng, & database, args. num_ware ) ?;
73
82
74
83
let mut rt_hist = RtHist :: new ( ) ;
84
+ let mut success = [ 0usize ; 5 ] ;
85
+ let mut late = [ 0usize ; 5 ] ;
86
+ let mut failure = [ 0usize ; 5 ] ;
75
87
let tests = vec ! [
76
88
Box :: new( NewOrdTest ) as Box <dyn TpccTest <_>>,
77
89
Box :: new( PaymentTest ) ,
@@ -81,64 +93,145 @@ fn main() -> Result<(), TpccError> {
81
93
] ;
82
94
let tpcc_args = TpccArgs { joins : args. joins } ;
83
95
84
- let tpcc_start = Instant :: now ( ) ;
85
96
let duration = Duration :: new ( args. measure_time , 0 ) ;
86
97
let mut round_count = 0 ;
98
+ let mut seq_gen = SeqGen :: new ( 10 , 10 , 1 , 1 , 1 ) ;
99
+ let tpcc_start = Instant :: now ( ) ;
87
100
88
101
while tpcc_start. elapsed ( ) < duration {
89
- for ( i, tpcc_test) in tests. iter ( ) . enumerate ( ) {
90
- let mut is_succeed = false ;
91
- for j in 0 ..args. max_retry + 1 {
92
- let transaction_start = Instant :: now ( ) ;
93
- let mut tx = database. new_transaction ( ) ?;
94
-
95
- if let Err ( err) =
96
- tpcc_test. do_transaction ( & mut rng, & mut tx, args. num_ware , & tpcc_args)
97
- {
98
- eprintln ! (
99
- "[{}] Error while doing transaction: {}" ,
100
- tpcc_test. name( ) ,
101
- err
102
- ) ;
102
+ let i = seq_gen. get ( ) ;
103
+ let tpcc_test = & tests[ i] ;
104
+
105
+ let mut is_succeed = false ;
106
+ for j in 0 ..args. max_retry + 1 {
107
+ let transaction_start = Instant :: now ( ) ;
108
+ let mut tx = database. new_transaction ( ) ?;
109
+
110
+ if let Err ( err) = tpcc_test. do_transaction ( & mut rng, & mut tx, args. num_ware , & tpcc_args)
111
+ {
112
+ failure[ i] += 1 ;
113
+ eprintln ! (
114
+ "[{}] Error while doing transaction: {}" ,
115
+ tpcc_test. name( ) ,
116
+ err
117
+ ) ;
118
+ } else {
119
+ let rt = transaction_start. elapsed ( ) ;
120
+ rt_hist. hist_inc ( i, rt) ;
121
+ is_succeed = true ;
122
+
123
+ if rt <= RT_LIMITS [ i] {
124
+ success[ i] += 1 ;
103
125
} else {
104
- rt_hist. hist_inc ( i, transaction_start. elapsed ( ) ) ;
105
- is_succeed = true ;
106
- break ;
107
- }
108
- if j < args. max_retry {
109
- println ! ( "[{}] Retry for the {}th time" , tpcc_test. name( ) , j + 1 ) ;
126
+ late[ i] += 1 ;
110
127
}
128
+ break ;
111
129
}
112
- if !is_succeed {
113
- return Err ( TpccError :: MaxRetry ) ;
130
+ if j < args . max_retry {
131
+ println ! ( "[{}] Retry for the {}th time" , tpcc_test . name ( ) , j + 1 ) ;
114
132
}
115
133
}
116
- if round_count != 0 && round_count % 4 == 0 {
134
+ if !is_succeed {
135
+ return Err ( TpccError :: MaxRetry ) ;
136
+ }
137
+ if round_count != 0 && round_count % 8 == 0 {
117
138
println ! (
118
- "============ TPCC CheckPoint {} on round {round_count}: ===============" ,
119
- round_count / 4
139
+ "[TPCC CheckPoint {} on round {round_count}][{}]: 90th Percentile RT: {:.3}" ,
140
+ round_count / 4 ,
141
+ tpcc_test. name( ) ,
142
+ rt_hist. hist_ckp( i)
120
143
) ;
121
- for ( i, name) in vec ! [
122
- "New-Order" ,
123
- "Payment" ,
124
- "Order-Status" ,
125
- "Delivery" ,
126
- "Stock-Level" ,
127
- ]
128
- . into_iter ( )
129
- . enumerate ( )
130
- {
131
- println ! ( "{name} 90th Percentile RT: {:.3}" , rt_hist. hist_ckp( i) ) ;
132
- }
133
- println ! ( "==========================================================" ) ;
134
144
}
135
145
round_count += 1 ;
136
146
}
147
+ let actual_tpcc_time = tpcc_start. elapsed ( ) ;
148
+ println ! ( "---------------------------------------------------" ) ;
149
+ // Raw Results
150
+ print_transaction ( & success, & late, & failure, |name, success, late, failure| {
151
+ println ! ( "|{}| sc: {} lt: {} fl: {}" , name, success, late, failure)
152
+ } ) ;
153
+ println ! ( "in {} sec." , actual_tpcc_time. as_secs( ) ) ;
154
+ println ! ( "<Constraint Check> (all must be [OK])" ) ;
155
+ println ! ( "[transaction percentage]" ) ;
156
+
157
+ let mut j = 0.0 ;
158
+ for i in 0 ..5 {
159
+ j += ( success[ i] + late[ i] ) as f64 ;
160
+ }
161
+ // Payment
162
+ let f = ( ( success[ 1 ] + late[ 1 ] ) as f64 / j) * 100.0 ;
163
+ print ! ( " Payment: {:.1}% (>=43.0%)" , f) ;
164
+ if f >= 43.0 {
165
+ println ! ( " [Ok]" ) ;
166
+ } else {
167
+ println ! ( " [NG]" ) ;
168
+ }
169
+ // Order-Status
170
+ let f = ( ( success[ 2 ] + late[ 2 ] ) as f64 / j) * 100.0 ;
171
+ print ! ( " Order-Status: {:.1}% (>=4.0%)" , f) ;
172
+ if f >= 4.0 {
173
+ println ! ( " [Ok]" ) ;
174
+ } else {
175
+ println ! ( " [NG]" ) ;
176
+ }
177
+ // Delivery
178
+ let f = ( ( success[ 3 ] + late[ 3 ] ) as f64 / j) * 100.0 ;
179
+ print ! ( " Order-Status: {:.1}% (>=4.0%)" , f) ;
180
+ if f >= 4.0 {
181
+ println ! ( " [Ok]" ) ;
182
+ } else {
183
+ println ! ( " [NG]" ) ;
184
+ }
185
+ // Stock-Level
186
+ let f = ( ( success[ 4 ] + late[ 4 ] ) as f64 / j) * 100.0 ;
187
+ print ! ( " Order-Status: {:.1}% (>=4.0%)" , f) ;
188
+ if f >= 4.0 {
189
+ println ! ( " [Ok]" ) ;
190
+ } else {
191
+ println ! ( " [NG]" ) ;
192
+ }
193
+ println ! ( "[response time (at least 90%% passed)]" ) ;
194
+ print_transaction ( & success, & late, & failure, |name, success, late, _| {
195
+ let f = ( success as f64 / ( success + late) as f64 ) * 100.0 ;
196
+ print ! ( " {}: {:.1}" , name, f) ;
197
+ if f >= 90.0 {
198
+ println ! ( " [OK]" ) ;
199
+ } else {
200
+ println ! ( " [NG]" ) ;
201
+ }
202
+ } ) ;
203
+ print_transaction ( & success, & late, & failure, |name, success, late, _| {
204
+ println ! ( " {} Total: {}" , name, success + late)
205
+ } ) ;
206
+ println ! ( ) ;
137
207
rt_hist. hist_report ( ) ;
208
+ println ! ( "<TpmC>" ) ;
209
+ let tpmc = ( success[ 0 ] + late[ 0 ] ) as f64 / ( actual_tpcc_time. as_secs_f64 ( ) / 60.0 ) ;
210
+ println ! ( "{} Tpmc" , tpmc) ;
138
211
139
212
Ok ( ( ) )
140
213
}
141
214
215
+ fn print_transaction < F : Fn ( & str , usize , usize , usize ) > (
216
+ success : & [ usize ] ,
217
+ late : & [ usize ] ,
218
+ failure : & [ usize ] ,
219
+ fn_print : F ,
220
+ ) {
221
+ for ( i, name) in vec ! [
222
+ "New-Order" ,
223
+ "Payment" ,
224
+ "Order-Status" ,
225
+ "Delivery" ,
226
+ "Stock-Level" ,
227
+ ]
228
+ . into_iter ( )
229
+ . enumerate ( )
230
+ {
231
+ fn_print ( name, success[ i] , late[ i] , failure[ i] ) ;
232
+ }
233
+ }
234
+
142
235
fn other_ware ( rng : & mut ThreadRng , home_ware : usize , num_ware : usize ) -> usize {
143
236
if num_ware == 1 {
144
237
return home_ware;
0 commit comments