@@ -51,7 +51,7 @@ type RangeGen interface {
51
51
// Generate returns an updated state, given the initial state, seed and
52
52
// simulation settings provided. In the updated state, ranges will have been
53
53
// created, replicas and leases assigned to stores in the cluster.
54
- Generate (seed int64 , settings * config.SimulationSettings , s state.State ) state.State
54
+ Generate (seed int64 , settings * config.SimulationSettings , s state.State ) ( state.State , string )
55
55
String () string
56
56
}
57
57
@@ -65,11 +65,13 @@ func GenerateSimulation(
65
65
settingsGen SettingsGen ,
66
66
eventGen EventGen ,
67
67
seed int64 ,
68
+ buf * strings.Builder ,
68
69
) * asim.Simulator {
69
70
settings := settingsGen .Generate (seed )
70
71
s := clusterGen .Generate (seed , & settings )
71
- s = rangeGen .Generate (seed , & settings , s )
72
+ s , rangeStateStr : = rangeGen .Generate (seed , & settings , s )
72
73
eventExecutor := eventGen .Generate (seed , & settings )
74
+ generateClusterVisualization (buf , s , loadGen , eventGen , rangeStateStr )
73
75
return asim .NewSimulator (
74
76
duration ,
75
77
loadGen .Generate (seed , & settings ),
@@ -102,8 +104,11 @@ var _ LoadGen = MultiLoad{}
102
104
103
105
func (ml MultiLoad ) String () string {
104
106
var str string
105
- for _ , load := range ml {
106
- str += fmt .Sprintf ("%s\n " , load .String ())
107
+ for i , load := range ml {
108
+ if i > 0 {
109
+ str += "\n "
110
+ }
111
+ str += load .String ()
107
112
}
108
113
return str
109
114
}
@@ -131,11 +136,36 @@ type BasicLoad struct {
131
136
var _ LoadGen = BasicLoad {}
132
137
133
138
func (bl BasicLoad ) String () string {
134
- return fmt .Sprintf (
135
- "basic load with rw_ratio=%0.2f, rate=%0.2f, skewed_access=%t, min_block_size=%d, max_block_size=%d, " +
136
- "min_key=%d, max_key=%d, request_cpu_per_access=%d, raft_cpu_per_write=%d" ,
137
- bl .RWRatio , bl .Rate , bl .SkewedAccess , bl .MinBlockSize , bl .MaxBlockSize ,
138
- bl .MinKey , bl .MaxKey , bl .RequestCPUPerAccess , bl .RaftCPUPerWrite )
139
+ var buf strings.Builder
140
+ fmt .Fprintf (& buf , "\t [%d,%d): " , bl .MinKey , bl .MaxKey )
141
+ if bl .RWRatio == 1 {
142
+ _ , _ = fmt .Fprint (& buf , "read-only" )
143
+ } else if bl .RWRatio == 0 {
144
+ _ , _ = fmt .Fprint (& buf , "write-only" )
145
+ } else {
146
+ _ , _ = fmt .Fprintf (& buf , "%d%%r" , int (bl .RWRatio * 100 ))
147
+ }
148
+ if bl .RequestCPUPerAccess > 0 {
149
+ _ , _ = fmt .Fprint (& buf , " high-cpu" )
150
+ }
151
+ if bl .MinBlockSize > 1 && bl .MaxBlockSize > 1 {
152
+ _ , _ = fmt .Fprint (& buf , " large-block" )
153
+ }
154
+ _ , _ = fmt .Fprint (& buf , " [" )
155
+
156
+ if bl .RequestCPUPerAccess > 0 {
157
+ _ , _ = fmt .Fprintf (& buf , "%.2fcpu-us/op, " , float64 (bl .RequestCPUPerAccess / time .Microsecond .Nanoseconds ()))
158
+ }
159
+ if bl .RaftCPUPerWrite > 0 {
160
+ _ , _ = fmt .Fprintf (& buf , "%.2fcpu-us/write(raft), " , float64 (bl .RaftCPUPerWrite / time .Microsecond .Nanoseconds ()))
161
+ }
162
+ if bl .MinBlockSize == bl .MaxBlockSize {
163
+ _ , _ = fmt .Fprintf (& buf , "%dB/op, " , bl .MinBlockSize )
164
+ } else {
165
+ _ , _ = fmt .Fprintf (& buf , "%d-%dB/op, " , bl .MinBlockSize , bl .MaxBlockSize )
166
+ }
167
+ fmt .Fprintf (& buf , "%gops/s]" , bl .Rate )
168
+ return buf .String ()
139
169
}
140
170
141
171
// Generate returns a new list of workload generators where the generator
@@ -184,7 +214,7 @@ func (lc LoadedCluster) Generate(seed int64, settings *config.SimulationSettings
184
214
}
185
215
186
216
func (lc LoadedCluster ) String () string {
187
- return fmt .Sprintf ("loaded cluster with \n %v " , lc .Info )
217
+ return fmt .Sprintf ("cluster: %s " , lc .Info . String () )
188
218
}
189
219
190
220
func (lc LoadedCluster ) Regions () []state.Region {
@@ -204,11 +234,12 @@ type BasicCluster struct {
204
234
func (bc BasicCluster ) String () string {
205
235
var b strings.Builder
206
236
_ , _ = fmt .Fprintf (& b ,
207
- "basic cluster with nodes= %d, stores_per_node= %d, store_byte_capacity=%d, node_cpu_rate_capacity=%d " ,
208
- bc .Nodes , bc .StoresPerNode , bc .StoreByteCapacity , bc .NodeCPURateCapacity )
237
+ "[ nodes: %d, stores_per_node: %d, store_disk_capacity: %dGiB, node_capacity: %dcpu-sec/sec " ,
238
+ bc .Nodes , bc .StoresPerNode , bc .StoreByteCapacity >> 30 , bc .NodeCPURateCapacity / time . Second . Nanoseconds () )
209
239
if len (bc .Region ) != 0 {
210
- _ , _ = fmt .Fprintf (& b , ", region= %v, nodes_per_region= %v" , bc .Region , bc .NodesPerRegion )
240
+ _ , _ = fmt .Fprintf (& b , ", region: %v, nodes_per_region: %v" , bc .Region , bc .NodesPerRegion )
211
241
}
242
+ b .WriteString ("]" )
212
243
return b .String ()
213
244
}
214
245
@@ -325,15 +356,11 @@ type BaseRanges struct {
325
356
ReplicaPlacement state.ReplicaPlacement
326
357
}
327
358
328
- func (b BaseRanges ) String () string {
329
- return fmt .Sprintf ("ranges=%d, min_key=%d, max_key=%d, replication_factor=%d, bytes=%d" , b .Ranges , b .MinKey , b .MaxKey , b .ReplicationFactor , b .Bytes )
330
- }
331
-
332
359
// GetRangesInfo generates and distributes ranges across stores based on
333
360
// PlacementType while using other BaseRanges fields for range configuration.
334
361
func (b BaseRanges ) GetRangesInfo (
335
362
pType PlacementType , numOfStores int , randSource * rand.Rand , weightedRandom []float64 ,
336
- ) state.RangesInfo {
363
+ ) ( state.RangesInfo , string ) {
337
364
switch pType {
338
365
case Even :
339
366
return state .RangesInfoEvenDistribution (numOfStores , b .Ranges , b .MinKey , b .MaxKey , b .ReplicationFactor , b .Bytes )
@@ -369,21 +396,24 @@ type BasicRanges struct {
369
396
}
370
397
371
398
func (br BasicRanges ) String () string {
372
- return fmt .Sprintf ("basic ranges with placement_type=%v, %v" , br .PlacementType , br .BaseRanges )
399
+ return fmt .Sprintf ("[%d,%d): %d(rf=%d), %dMiB" ,
400
+ br .MinKey , br .MaxKey , br .Ranges , br .ReplicationFactor , br .Bytes >> 20 )
373
401
}
374
402
375
403
// Generate returns an updated simulator state, where the cluster is loaded with
376
404
// ranges generated based on the parameters specified in the fields of
377
405
// BasicRanges.
378
406
func (br BasicRanges ) Generate (
379
407
seed int64 , settings * config.SimulationSettings , s state.State ,
380
- ) state.State {
408
+ ) ( state.State , string ) {
381
409
if br .PlacementType == Random || br .PlacementType == WeightedRandom {
382
410
panic ("BasicRanges generate only uniform or skewed distributions" )
383
411
}
384
- rangesInfo := br .GetRangesInfo (br .PlacementType , len (s .Stores ()), nil , []float64 {})
412
+ rangesInfo , str := br .GetRangesInfo (br .PlacementType , len (s .Stores ()), nil , []float64 {})
385
413
br .LoadRangeInfo (s , rangesInfo )
386
- return s
414
+ var buf strings.Builder
415
+ _ , _ = fmt .Fprintf (& buf , "\t %s, %s" , br , str )
416
+ return s , buf .String ()
387
417
}
388
418
389
419
// MultiRanges implements the RangeGen interface, supporting multiple
@@ -402,12 +432,18 @@ func (mr MultiRanges) String() string {
402
432
403
433
func (mr MultiRanges ) Generate (
404
434
seed int64 , settings * config.SimulationSettings , s state.State ,
405
- ) state.State {
435
+ ) ( state.State , string ) {
406
436
var rangeInfos []state.RangeInfo
437
+ var rangeInfoStrings []string
407
438
for _ , ranges := range mr {
408
- rangeInfos = append (rangeInfos ,
409
- ranges .GetRangesInfo (ranges .PlacementType , len (s .Stores ()), nil , []float64 {})... )
439
+ rangeInfo , rangeInfoStr := ranges .GetRangesInfo (ranges .PlacementType , len (s .Stores ()), nil , []float64 {})
440
+ rangeInfos = append (rangeInfos , rangeInfo ... )
441
+ rangeInfoStrings = append (rangeInfoStrings , fmt .Sprintf ("\t %s, %s" , ranges .String (), rangeInfoStr ))
410
442
}
411
443
state .LoadRangeInfo (s , rangeInfos ... )
412
- return s
444
+ var buf strings.Builder
445
+ for _ , str := range rangeInfoStrings {
446
+ _ , _ = fmt .Fprintf (& buf , "%s\n " , str )
447
+ }
448
+ return s , buf .String ()
413
449
}
0 commit comments