@@ -84,9 +84,21 @@ func newGenerators(cfg *models.GenerationConfig) (map[string]*generator.ColumnGe
84
84
generators := make (map [string ]* generator.ColumnGenerator )
85
85
86
86
for modelName , model := range cfg .Models {
87
- distinctValuesCountByColumn := make (map [string ]uint64 )
87
+ distinctValuesCountByColumn := make (map [string ]uint64 , len (model .Columns ))
88
+
89
+ sortedColumns , err := models .TopologicalSort (model .Columns )
90
+ if err != nil {
91
+ return nil , errors .WithMessagef (err , "failed to sorting columns by dependencies for model %q" , modelName )
92
+ }
93
+
94
+ originIndexes := make (map [string ]int , len (model .Columns ))
95
+ for index , column := range model .Columns {
96
+ originIndexes [column .Name ] = index
97
+ }
98
+
99
+ for _ , columnName := range sortedColumns {
100
+ column := model.Columns [originIndexes [columnName ]]
88
101
89
- for _ , column := range model .Columns {
90
102
dataModelName := modelName
91
103
dataModel := model
92
104
dataColumn := column
@@ -173,6 +185,8 @@ func (t *Task) WaitError() error {
173
185
}
174
186
175
187
// generateAndSaveValues function generates values for all model.
188
+ //
189
+ //nolint:cyclop
176
190
func (t * Task ) generateAndSaveValues (ctx context.Context ) error {
177
191
var err error
178
192
@@ -203,6 +217,16 @@ func (t *Task) generateAndSaveValues(ctx context.Context) error {
203
217
continue
204
218
}
205
219
220
+ columnsTopologicalOrder , err := models .TopologicalSort (model .Columns )
221
+ if err != nil {
222
+ return errors .WithMessagef (err , "failed to sorting columns by dependencies for model %q" , modelName )
223
+ }
224
+
225
+ originColumnsIndexes := make (map [string ]int , len (model .Columns ))
226
+ for index , column := range model .Columns {
227
+ originColumnsIndexes [column .Name ] = index
228
+ }
229
+
206
230
pool .Add (1 )
207
231
208
232
go func () {
@@ -223,7 +247,11 @@ func (t *Task) generateAndSaveValues(ctx context.Context) error {
223
247
generators = append (generators , t .generators [columnKey ].NewBatchGenerator (rowsCount ))
224
248
}
225
249
226
- pool .Submit (ctx , outputSyncer .WorkerSyncer (), model , generators , rowsCount )
250
+ pool .Submit (
251
+ ctx , outputSyncer .WorkerSyncer (),
252
+ modelName , columnsTopologicalOrder , originColumnsIndexes ,
253
+ generators , rowsCount ,
254
+ )
227
255
}
228
256
}()
229
257
}
@@ -257,7 +285,8 @@ func (t *Task) skipRows() {
257
285
// generateAndSaveBatch function generate batch of values for selected column and send it to output.
258
286
func (t * Task ) generateAndSaveBatch (
259
287
ctx context.Context , outputSync * common.WorkerSyncer ,
260
- model * models.Model , generators []* generator.BatchGenerator , count uint64 ,
288
+ modelName string , columnsTopologicalOrder []string , originColumnsIndexes map [string ]int ,
289
+ generators []* generator.BatchGenerator , count uint64 ,
261
290
) error {
262
291
defer outputSync .Done (ctx )
263
292
@@ -268,20 +297,15 @@ func (t *Task) generateAndSaveBatch(
268
297
}
269
298
}
270
299
271
- originIndexes := make (map [string ]int , len (model .Columns ))
272
- for index , column := range model .Columns {
273
- originIndexes [column .Name ] = index
274
- }
275
-
276
300
for i := range count {
277
- generatedValues := make (map [string ]any )
301
+ generatedValues := make (map [string ]any , len ( originColumnsIndexes ) )
278
302
279
- for _ , columnName := range model . ColumnsTopologicalOrder {
303
+ for _ , columnName := range columnsTopologicalOrder {
280
304
if common .CtxClosed (ctx ) {
281
305
return & common.ContextCancelError {}
282
306
}
283
307
284
- idx := originIndexes [columnName ]
308
+ idx := originColumnsIndexes [columnName ]
285
309
286
310
value , err := generators [idx ].Value (generatedValues )
287
311
if err != nil {
@@ -295,12 +319,12 @@ func (t *Task) generateAndSaveBatch(
295
319
296
320
outputSync .WaitPrevious (ctx )
297
321
298
- err := t .output .HandleRowsBatch (ctx , model . Name , batch )
322
+ err := t .output .HandleRowsBatch (ctx , modelName , batch )
299
323
if err != nil {
300
324
return errors .WithMessage (err , "failed to save batch to output" )
301
325
}
302
326
303
- t .progress .Add (model . Name , count )
327
+ t .progress .Add (modelName , count )
304
328
305
329
return nil
306
330
}
0 commit comments