@@ -84,9 +84,21 @@ func newGenerators(cfg *models.GenerationConfig) (map[string]*generator.ColumnGe
8484 generators := make (map [string ]* generator.ColumnGenerator )
8585
8686 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 ]]
88101
89- for _ , column := range model .Columns {
90102 dataModelName := modelName
91103 dataModel := model
92104 dataColumn := column
@@ -173,6 +185,8 @@ func (t *Task) WaitError() error {
173185}
174186
175187// generateAndSaveValues function generates values for all model.
188+ //
189+ //nolint:cyclop
176190func (t * Task ) generateAndSaveValues (ctx context.Context ) error {
177191 var err error
178192
@@ -203,6 +217,16 @@ func (t *Task) generateAndSaveValues(ctx context.Context) error {
203217 continue
204218 }
205219
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+
206230 pool .Add (1 )
207231
208232 go func () {
@@ -223,7 +247,11 @@ func (t *Task) generateAndSaveValues(ctx context.Context) error {
223247 generators = append (generators , t .generators [columnKey ].NewBatchGenerator (rowsCount ))
224248 }
225249
226- pool .Submit (ctx , outputSyncer .WorkerSyncer (), model , generators , rowsCount )
250+ pool .Submit (
251+ ctx , outputSyncer .WorkerSyncer (),
252+ modelName , columnsTopologicalOrder , originColumnsIndexes ,
253+ generators , rowsCount ,
254+ )
227255 }
228256 }()
229257 }
@@ -257,7 +285,8 @@ func (t *Task) skipRows() {
257285// generateAndSaveBatch function generate batch of values for selected column and send it to output.
258286func (t * Task ) generateAndSaveBatch (
259287 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 ,
261290) error {
262291 defer outputSync .Done (ctx )
263292
@@ -268,20 +297,15 @@ func (t *Task) generateAndSaveBatch(
268297 }
269298 }
270299
271- originIndexes := make (map [string ]int , len (model .Columns ))
272- for index , column := range model .Columns {
273- originIndexes [column .Name ] = index
274- }
275-
276300 for i := range count {
277- generatedValues := make (map [string ]any )
301+ generatedValues := make (map [string ]any , len ( originColumnsIndexes ) )
278302
279- for _ , columnName := range model . ColumnsTopologicalOrder {
303+ for _ , columnName := range columnsTopologicalOrder {
280304 if common .CtxClosed (ctx ) {
281305 return & common.ContextCancelError {}
282306 }
283307
284- idx := originIndexes [columnName ]
308+ idx := originColumnsIndexes [columnName ]
285309
286310 value , err := generators [idx ].Value (generatedValues )
287311 if err != nil {
@@ -295,12 +319,12 @@ func (t *Task) generateAndSaveBatch(
295319
296320 outputSync .WaitPrevious (ctx )
297321
298- err := t .output .HandleRowsBatch (ctx , model . Name , batch )
322+ err := t .output .HandleRowsBatch (ctx , modelName , batch )
299323 if err != nil {
300324 return errors .WithMessage (err , "failed to save batch to output" )
301325 }
302326
303- t .progress .Add (model . Name , count )
327+ t .progress .Add (modelName , count )
304328
305329 return nil
306330}
0 commit comments