@@ -17,6 +17,8 @@ import (
1717 "fmt"
1818 "math/rand"
1919 "strings"
20+ "sync"
21+ "sync/atomic"
2022 "time"
2123
2224 "github.com/pingcap/log"
@@ -53,7 +55,7 @@ func newRowValues(r *rand.Rand, columnSize int, columnCount int, batchSize int)
5355 if sb .Len () != 0 {
5456 sb .Write ([]byte ("," ))
5557 }
56- index := rand . Int () % numColumnValues
58+ index := r . Intn ( numColumnValues )
5759 columnValue := columns [index ]
5860
5961 sb .WriteByte ('\'' )
@@ -65,16 +67,6 @@ func newRowValues(r *rand.Rand, columnSize int, columnCount int, batchSize int)
6567 return result
6668}
6769
68- func (l * LargeRowWorkload ) getSmallRow () string {
69- index := l .r .Int () % len (l .smallRows )
70- return l .smallRows [index ]
71- }
72-
73- func (l * LargeRowWorkload ) getLargeRow () string {
74- index := l .r .Int () % len (l .largeRows )
75- return l .largeRows [index ]
76- }
77-
7870type LargeRowWorkload struct {
7971 smallRows []string
8072 largeRows []string
@@ -83,26 +75,44 @@ type LargeRowWorkload struct {
8375
8476 columnCount int
8577
86- r * rand.Rand
78+ seed atomic.Int64
79+ randPool sync.Pool
80+ }
81+
82+ func (l * LargeRowWorkload ) getRand () * rand.Rand {
83+ return l .randPool .Get ().(* rand.Rand )
84+ }
85+
86+ func (l * LargeRowWorkload ) putRand (r * rand.Rand ) {
87+ l .randPool .Put (r )
88+ }
89+
90+ func (l * LargeRowWorkload ) getSmallRow (r * rand.Rand ) string {
91+ return l .smallRows [r .Intn (len (l .smallRows ))]
92+ }
93+
94+ func (l * LargeRowWorkload ) getLargeRow (r * rand.Rand ) string {
95+ return l .largeRows [r .Intn (len (l .largeRows ))]
8796}
8897
8998func NewLargeRowWorkload (
9099 normalRowSize , largeRowSize int , largeRatio float64 ,
91100) schema.Workload {
92- columnCount := int (float64 (largeRowSize ) / varcharColumnMaxLen )
93-
94101 r := rand .New (rand .NewSource (time .Now ().UnixNano ()))
102+ columnCount := int (float64 (largeRowSize ) / varcharColumnMaxLen )
95103 smallColumnSize := int (float64 (normalRowSize ) / float64 (columnCount ))
96104
97- return & LargeRowWorkload {
98- r : r ,
99- largeRatio : largeRatio ,
100-
105+ l := & LargeRowWorkload {
106+ largeRatio : largeRatio ,
101107 columnCount : columnCount ,
102-
103- smallRows : newRowValues (r , smallColumnSize , columnCount , 512 ),
104- largeRows : newRowValues (r , varcharColumnMaxLen , columnCount , 128 ),
108+ smallRows : newRowValues (r , smallColumnSize , columnCount , 512 ),
109+ largeRows : newRowValues (r , varcharColumnMaxLen , columnCount , 128 ),
105110 }
111+ l .seed .Store (time .Now ().UnixNano ())
112+ l .randPool .New = func () any {
113+ return rand .New (rand .NewSource (l .seed .Add (1 )))
114+ }
115+ return l
106116}
107117
108118func getTableName (n int ) string {
@@ -124,37 +134,44 @@ func (l *LargeRowWorkload) BuildCreateTableStatement(n int) string {
124134
125135func (l * LargeRowWorkload ) BuildInsertSql (tableN int , batchSize int ) string {
126136 tableName := getTableName (tableN )
127- insertSQL := fmt .Sprintf ("INSERT INTO %s VALUES (%d,%s)" , tableName , rand .Int63 ()% maxValue , l .getSmallRow ())
137+ r := l .getRand ()
138+ defer l .putRand (r )
139+
140+ var sb strings.Builder
141+ sb .WriteString (fmt .Sprintf ("INSERT INTO %s VALUES (%d,%s)" , tableName , r .Int63 ()% maxValue , l .getSmallRow (r )))
128142
129143 var largeRowCount int
130144 for i := 1 ; i < batchSize ; i ++ {
131- if l . r .Float64 () < l .largeRatio {
132- insertSQL = fmt .Sprintf ("%s ,(%d,%s)" , insertSQL , rand .Int63 ()% maxValue , l .getLargeRow ())
145+ if r .Float64 () < l .largeRatio {
146+ sb . WriteString ( fmt .Sprintf (",(%d,%s)" , r .Int63 ()% maxValue , l .getLargeRow (r ) ))
133147 largeRowCount ++
134148 } else {
135- insertSQL = fmt .Sprintf ("%s ,(%d,%s)" , insertSQL , rand .Int63 ()% maxValue , l .getSmallRow ())
149+ sb . WriteString ( fmt .Sprintf (",(%d,%s)" , r .Int63 ()% maxValue , l .getSmallRow (r ) ))
136150 }
137151 }
138152
139153 log .Debug ("large row workload, insert the table" ,
140154 zap .Int ("table" , tableN ), zap .Int ("batchSize" , batchSize ),
141- zap .Int ("largeRowCount" , largeRowCount ), zap .Int ("length" , len ( insertSQL )))
155+ zap .Int ("largeRowCount" , largeRowCount ), zap .Int ("length" , sb . Len ( )))
142156
143- return insertSQL
157+ return sb . String ()
144158}
145159
146160func (l * LargeRowWorkload ) BuildUpdateSql (opts schema.UpdateOption ) string {
147161 tableName := getTableName (opts .TableIndex )
162+ r := l .getRand ()
163+ defer l .putRand (r )
164+
148165 upsertSQL := strings.Builder {}
149- upsertSQL .WriteString (fmt .Sprintf ("INSERT INTO %s VALUES (%d,%s)" , tableName , rand .Int63 ()% maxValue , l .getSmallRow ()))
166+ upsertSQL .WriteString (fmt .Sprintf ("INSERT INTO %s VALUES (%d,%s)" , tableName , r .Int63 ()% maxValue , l .getSmallRow (r )))
150167
151168 var largeRowCount int
152169 for i := 1 ; i < opts .Batch ; i ++ {
153- if l . r .Float64 () < l .largeRatio {
154- upsertSQL .WriteString (fmt .Sprintf (",(%d,%s)" , rand .Int63 ()% maxValue , l .getLargeRow ()))
170+ if r .Float64 () < l .largeRatio {
171+ upsertSQL .WriteString (fmt .Sprintf (",(%d,%s)" , r .Int63 ()% maxValue , l .getLargeRow (r )))
155172 largeRowCount ++
156173 } else {
157- upsertSQL .WriteString (fmt .Sprintf (",(%d,%s)" , rand .Int63 ()% maxValue , l .getSmallRow ()))
174+ upsertSQL .WriteString (fmt .Sprintf (",(%d,%s)" , r .Int63 ()% maxValue , l .getSmallRow (r )))
158175 }
159176 }
160177 upsertSQL .WriteString (" ON DUPLICATE KEY UPDATE col_0=VALUES(col_0)" )
@@ -166,15 +183,18 @@ func (l *LargeRowWorkload) BuildUpdateSql(opts schema.UpdateOption) string {
166183}
167184
168185func (l * LargeRowWorkload ) BuildDeleteSql (opts schema.DeleteOption ) string {
169- deleteType := rand .Intn (3 )
186+ r := l .getRand ()
187+ defer l .putRand (r )
188+
189+ deleteType := r .Intn (3 )
170190 tableName := getTableName (opts .TableIndex )
171191
172192 switch deleteType {
173193 case 0 :
174194 // Strategy 1: Random single/multiple row delete by ID
175195 var buf strings.Builder
176196 for i := 0 ; i < opts .Batch ; i ++ {
177- id := rand .Int63 () % maxValue
197+ id := r .Int63 () % maxValue
178198 if i > 0 {
179199 buf .WriteString (";" )
180200 }
@@ -184,7 +204,7 @@ func (l *LargeRowWorkload) BuildDeleteSql(opts schema.DeleteOption) string {
184204
185205 case 1 :
186206 // Strategy 2: Range delete by ID
187- startID := rand .Int63 () % maxValue
207+ startID := r .Int63 () % maxValue
188208 endID := startID + int64 (opts .Batch * 100 )
189209 if endID > maxValue {
190210 endID = maxValue
@@ -194,7 +214,7 @@ func (l *LargeRowWorkload) BuildDeleteSql(opts schema.DeleteOption) string {
194214
195215 case 2 :
196216 // Strategy 3: Conditional delete by random ID modulo
197- modValue := rand .Intn (1000 )
217+ modValue := r .Intn (1000 )
198218 return fmt .Sprintf ("DELETE FROM %s WHERE id %% 1000 = %d LIMIT %d" ,
199219 tableName , modValue , opts .Batch )
200220
0 commit comments