github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/soliton/chunk/chunk_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package chunk 15 16 import ( 17 "bytes" 18 "fmt" 19 "io/ioutil" 20 "math" 21 "os" 22 "strconv" 23 "strings" 24 "sync" 25 "testing" 26 "time" 27 "unsafe" 28 29 "github.com/cznic/mathutil" 30 "github.com/whtcorpsinc/check" 31 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 32 "github.com/whtcorpsinc/milevadb/config" 33 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 34 "github.com/whtcorpsinc/milevadb/types" 35 "github.com/whtcorpsinc/milevadb/types/json" 36 ) 37 38 func TestT(t *testing.T) { 39 path, _ := ioutil.TemFIDelir("", "oom-use-tmp-storage") 40 config.UFIDelateGlobal(func(conf *config.Config) { 41 conf.TempStoragePath = path 42 }) 43 _ = os.RemoveAll(path) // clean the uncleared temp file during the last run. 44 _ = os.MkdirAll(path, 0755) 45 check.TestingT(t) 46 } 47 48 var _ = check.Suite(&testChunkSuite{}) 49 50 type testChunkSuite struct{} 51 52 func (s *testChunkSuite) TestChunk(c *check.C) { 53 numDefCauss := 6 54 numRows := 10 55 chk := newChunk(8, 8, 0, 0, 40, 0) 56 strFmt := "%d.12345" 57 for i := 0; i < numRows; i++ { 58 chk.AppendNull(0) 59 chk.AppendInt64(1, int64(i)) 60 str := fmt.Sprintf(strFmt, i) 61 chk.AppendString(2, str) 62 chk.AppendBytes(3, []byte(str)) 63 chk.AppendMyDecimal(4, types.NewDecFromStringForTest(str)) 64 chk.AppendJSON(5, json.CreateBinary(str)) 65 } 66 c.Assert(chk.NumDefCauss(), check.Equals, numDefCauss) 67 c.Assert(chk.NumRows(), check.Equals, numRows) 68 for i := 0; i < numRows; i++ { 69 event := chk.GetRow(i) 70 c.Assert(event.GetInt64(0), check.Equals, int64(0)) 71 c.Assert(event.IsNull(0), check.IsTrue) 72 c.Assert(event.GetInt64(1), check.Equals, int64(i)) 73 str := fmt.Sprintf(strFmt, i) 74 c.Assert(event.IsNull(2), check.IsFalse) 75 c.Assert(event.GetString(2), check.Equals, str) 76 c.Assert(event.IsNull(3), check.IsFalse) 77 c.Assert(event.GetBytes(3), check.BytesEquals, []byte(str)) 78 c.Assert(event.IsNull(4), check.IsFalse) 79 c.Assert(event.GetMyDecimal(4).String(), check.Equals, str) 80 c.Assert(event.IsNull(5), check.IsFalse) 81 c.Assert(string(event.GetJSON(5).GetString()), check.Equals, str) 82 } 83 84 chk2 := newChunk(8, 8, 0, 0, 40, 0) 85 for i := 0; i < numRows; i++ { 86 event := chk.GetRow(i) 87 chk2.AppendRow(event) 88 } 89 for i := 0; i < numDefCauss; i++ { 90 defCaus2, defCaus1 := chk2.defCausumns[i], chk.defCausumns[i] 91 defCaus2.elemBuf, defCaus1.elemBuf = nil, nil 92 c.Assert(defCaus2, check.DeepEquals, defCaus1) 93 } 94 95 chk = newChunk(4, 8, 16, 16, 0, 0) 96 f32Val := float32(1.2) 97 chk.AppendFloat32(0, f32Val) 98 f64Val := 1.3 99 chk.AppendFloat64(1, f64Val) 100 tVal := types.TimeFromDays(1) 101 chk.AppendTime(2, tVal) 102 durVal := types.Duration{Duration: time.Hour, Fsp: 6} 103 chk.AppendDuration(3, durVal) 104 enumVal := types.Enum{Name: "abc", Value: 100} 105 chk.AppendEnum(4, enumVal) 106 setVal := types.Set{Name: "def", Value: 101} 107 chk.AppendSet(5, setVal) 108 109 event := chk.GetRow(0) 110 c.Assert(event.GetFloat32(0), check.Equals, f32Val) 111 c.Assert(event.GetTime(2).Compare(tVal), check.Equals, 0) 112 // fsp is no longer maintained in chunk 113 c.Assert(event.GetDuration(3, 0).Duration, check.DeepEquals, durVal.Duration) 114 c.Assert(event.GetEnum(4), check.DeepEquals, enumVal) 115 c.Assert(event.GetSet(5), check.DeepEquals, setVal) 116 117 // AppendPartialRow can be different number of defCausumns, useful for join. 118 chk = newChunk(8, 8) 119 chk2 = newChunk(8) 120 chk2.AppendInt64(0, 1) 121 chk2.AppendInt64(0, -1) 122 chk.AppendPartialRow(0, chk2.GetRow(0)) 123 chk.AppendPartialRow(1, chk2.GetRow(0)) 124 c.Assert(chk.GetRow(0).GetInt64(0), check.Equals, int64(1)) 125 c.Assert(chk.GetRow(0).GetInt64(1), check.Equals, int64(1)) 126 c.Assert(chk.NumRows(), check.Equals, 1) 127 128 // AppendRowByDefCausIdxs and AppendPartialRowByDefCausIdxs can do projection from event. 129 chk = newChunk(8, 8) 130 event = MutRowFromValues(0, 1, 2, 3).ToRow() 131 chk.AppendRowByDefCausIdxs(event, []int{3}) 132 chk.AppendRowByDefCausIdxs(event, []int{1}) 133 chk.AppendRowByDefCausIdxs(event, []int{}) 134 c.Assert(chk.DeferredCauset(0).Int64s(), check.DeepEquals, []int64{3, 1}) 135 c.Assert(chk.numVirtualRows, check.Equals, 3) 136 chk.AppendPartialRowByDefCausIdxs(1, event, []int{2}) 137 chk.AppendPartialRowByDefCausIdxs(1, event, []int{0}) 138 chk.AppendPartialRowByDefCausIdxs(0, event, []int{1, 3}) 139 c.Assert(chk.DeferredCauset(0).Int64s(), check.DeepEquals, []int64{3, 1, 1}) 140 c.Assert(chk.DeferredCauset(1).Int64s(), check.DeepEquals, []int64{2, 0, 3}) 141 c.Assert(chk.numVirtualRows, check.Equals, 3) 142 143 // Test Reset. 144 chk = newChunk(0) 145 chk.AppendString(0, "abcd") 146 chk.Reset() 147 chk.AppendString(0, "def") 148 c.Assert(chk.GetRow(0).GetString(0), check.Equals, "def") 149 150 // Test float32 151 chk = newChunk(4) 152 chk.AppendFloat32(0, 1) 153 chk.AppendFloat32(0, 1) 154 chk.AppendFloat32(0, 1) 155 c.Assert(chk.GetRow(2).GetFloat32(0), check.Equals, float32(1)) 156 } 157 158 func (s *testChunkSuite) TestAppend(c *check.C) { 159 fieldTypes := make([]*types.FieldType, 0, 3) 160 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 161 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeVarchar}) 162 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeJSON}) 163 164 jsonObj, err := json.ParseBinaryFromString("{\"k1\":\"v1\"}") 165 c.Assert(err, check.IsNil) 166 167 src := NewChunkWithCapacity(fieldTypes, 32) 168 dst := NewChunkWithCapacity(fieldTypes, 32) 169 170 src.AppendFloat32(0, 12.8) 171 src.AppendString(1, "abc") 172 src.AppendJSON(2, jsonObj) 173 src.AppendNull(0) 174 src.AppendNull(1) 175 src.AppendNull(2) 176 177 dst.Append(src, 0, 2) 178 dst.Append(src, 0, 2) 179 dst.Append(src, 0, 2) 180 dst.Append(src, 0, 2) 181 dst.Append(dst, 2, 6) 182 dst.Append(dst, 6, 6) 183 184 c.Assert(len(dst.defCausumns), check.Equals, 3) 185 186 c.Assert(dst.defCausumns[0].length, check.Equals, 12) 187 c.Assert(dst.defCausumns[0].nullCount(), check.Equals, 6) 188 c.Assert(string(dst.defCausumns[0].nullBitmap), check.Equals, string([]byte{0x55, 0x05})) 189 c.Assert(len(dst.defCausumns[0].offsets), check.Equals, 0) 190 c.Assert(len(dst.defCausumns[0].data), check.Equals, 4*12) 191 c.Assert(len(dst.defCausumns[0].elemBuf), check.Equals, 4) 192 193 c.Assert(dst.defCausumns[1].length, check.Equals, 12) 194 c.Assert(dst.defCausumns[1].nullCount(), check.Equals, 6) 195 c.Assert(string(dst.defCausumns[0].nullBitmap), check.Equals, string([]byte{0x55, 0x05})) 196 c.Assert(fmt.Sprintf("%v", dst.defCausumns[1].offsets), check.Equals, fmt.Sprintf("%v", []int64{0, 3, 3, 6, 6, 9, 9, 12, 12, 15, 15, 18, 18})) 197 c.Assert(string(dst.defCausumns[1].data), check.Equals, "abcabcabcabcabcabc") 198 c.Assert(len(dst.defCausumns[1].elemBuf), check.Equals, 0) 199 200 c.Assert(dst.defCausumns[2].length, check.Equals, 12) 201 c.Assert(dst.defCausumns[2].nullCount(), check.Equals, 6) 202 c.Assert(string(dst.defCausumns[0].nullBitmap), check.Equals, string([]byte{0x55, 0x05})) 203 c.Assert(len(dst.defCausumns[2].offsets), check.Equals, 13) 204 c.Assert(len(dst.defCausumns[2].data), check.Equals, 150) 205 c.Assert(len(dst.defCausumns[2].elemBuf), check.Equals, 0) 206 for i := 0; i < 12; i += 2 { 207 jsonElem := dst.GetRow(i).GetJSON(2) 208 cmpRes := json.CompareBinary(jsonElem, jsonObj) 209 c.Assert(cmpRes, check.Equals, 0) 210 } 211 } 212 213 func (s *testChunkSuite) TestTruncateTo(c *check.C) { 214 fieldTypes := make([]*types.FieldType, 0, 3) 215 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 216 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeVarchar}) 217 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeJSON}) 218 219 jsonObj, err := json.ParseBinaryFromString("{\"k1\":\"v1\"}") 220 c.Assert(err, check.IsNil) 221 222 src := NewChunkWithCapacity(fieldTypes, 32) 223 224 for i := 0; i < 8; i++ { 225 src.AppendFloat32(0, 12.8) 226 src.AppendString(1, "abc") 227 src.AppendJSON(2, jsonObj) 228 src.AppendNull(0) 229 src.AppendNull(1) 230 src.AppendNull(2) 231 } 232 233 src.TruncateTo(16) 234 src.TruncateTo(16) 235 src.TruncateTo(14) 236 src.TruncateTo(12) 237 c.Assert(len(src.defCausumns), check.Equals, 3) 238 239 c.Assert(src.defCausumns[0].length, check.Equals, 12) 240 c.Assert(src.defCausumns[0].nullCount(), check.Equals, 6) 241 c.Assert(string(src.defCausumns[0].nullBitmap), check.Equals, string([]byte{0x55, 0x05})) 242 c.Assert(len(src.defCausumns[0].offsets), check.Equals, 0) 243 c.Assert(len(src.defCausumns[0].data), check.Equals, 4*12) 244 c.Assert(len(src.defCausumns[0].elemBuf), check.Equals, 4) 245 246 c.Assert(src.defCausumns[1].length, check.Equals, 12) 247 c.Assert(src.defCausumns[1].nullCount(), check.Equals, 6) 248 c.Assert(string(src.defCausumns[0].nullBitmap), check.Equals, string([]byte{0x55, 0x05})) 249 c.Assert(fmt.Sprintf("%v", src.defCausumns[1].offsets), check.Equals, fmt.Sprintf("%v", []int64{0, 3, 3, 6, 6, 9, 9, 12, 12, 15, 15, 18, 18})) 250 c.Assert(string(src.defCausumns[1].data), check.Equals, "abcabcabcabcabcabc") 251 c.Assert(len(src.defCausumns[1].elemBuf), check.Equals, 0) 252 253 c.Assert(src.defCausumns[2].length, check.Equals, 12) 254 c.Assert(src.defCausumns[2].nullCount(), check.Equals, 6) 255 c.Assert(string(src.defCausumns[0].nullBitmap), check.Equals, string([]byte{0x55, 0x05})) 256 c.Assert(len(src.defCausumns[2].offsets), check.Equals, 13) 257 c.Assert(len(src.defCausumns[2].data), check.Equals, 150) 258 c.Assert(len(src.defCausumns[2].elemBuf), check.Equals, 0) 259 for i := 0; i < 12; i += 2 { 260 event := src.GetRow(i) 261 jsonElem := event.GetJSON(2) 262 cmpRes := json.CompareBinary(jsonElem, jsonObj) 263 c.Assert(cmpRes, check.Equals, 0) 264 } 265 chk := NewChunkWithCapacity(fieldTypes[:1], 1) 266 chk.AppendFloat32(0, 1.0) 267 chk.AppendFloat32(0, 1.0) 268 chk.TruncateTo(1) 269 chk.AppendNull(0) 270 c.Assert(chk.GetRow(1).IsNull(0), check.IsTrue) 271 } 272 273 func (s *testChunkSuite) TestChunkSizeControl(c *check.C) { 274 maxChunkSize := 10 275 chk := New([]*types.FieldType{types.NewFieldType(allegrosql.TypeLong)}, maxChunkSize, maxChunkSize) 276 c.Assert(chk.RequiredRows(), check.Equals, maxChunkSize) 277 278 for i := 0; i < maxChunkSize; i++ { 279 chk.AppendInt64(0, 1) 280 } 281 maxChunkSize += maxChunkSize / 3 282 chk.GrowAndReset(maxChunkSize) 283 c.Assert(chk.RequiredRows(), check.Equals, maxChunkSize) 284 285 maxChunkSize2 := maxChunkSize + maxChunkSize/3 286 chk2 := Renew(chk, maxChunkSize2) 287 c.Assert(chk2.RequiredRows(), check.Equals, maxChunkSize2) 288 289 chk.Reset() 290 for i := 1; i < maxChunkSize*2; i++ { 291 chk.SetRequiredRows(i, maxChunkSize) 292 c.Assert(chk.RequiredRows(), check.Equals, mathutil.Min(maxChunkSize, i)) 293 } 294 295 chk.SetRequiredRows(1, maxChunkSize). 296 SetRequiredRows(2, maxChunkSize). 297 SetRequiredRows(3, maxChunkSize) 298 c.Assert(chk.RequiredRows(), check.Equals, 3) 299 300 chk.SetRequiredRows(-1, maxChunkSize) 301 c.Assert(chk.RequiredRows(), check.Equals, maxChunkSize) 302 303 chk.SetRequiredRows(5, maxChunkSize) 304 chk.AppendInt64(0, 1) 305 chk.AppendInt64(0, 1) 306 chk.AppendInt64(0, 1) 307 chk.AppendInt64(0, 1) 308 c.Assert(chk.NumRows(), check.Equals, 4) 309 c.Assert(chk.IsFull(), check.IsFalse) 310 311 chk.AppendInt64(0, 1) 312 c.Assert(chk.NumRows(), check.Equals, 5) 313 c.Assert(chk.IsFull(), check.IsTrue) 314 315 chk.AppendInt64(0, 1) 316 chk.AppendInt64(0, 1) 317 chk.AppendInt64(0, 1) 318 c.Assert(chk.NumRows(), check.Equals, 8) 319 c.Assert(chk.IsFull(), check.IsTrue) 320 321 chk.SetRequiredRows(maxChunkSize, maxChunkSize) 322 c.Assert(chk.NumRows(), check.Equals, 8) 323 c.Assert(chk.IsFull(), check.IsFalse) 324 } 325 326 // newChunk creates a new chunk and initialize defCausumns with element length. 327 // 0 adds an varlen DeferredCauset, positive len add a fixed length DeferredCauset, negative len adds a interface DeferredCauset. 328 func newChunk(elemLen ...int) *Chunk { 329 chk := &Chunk{} 330 for _, l := range elemLen { 331 if l > 0 { 332 chk.defCausumns = append(chk.defCausumns, newFixedLenDeferredCauset(l, 0)) 333 } else { 334 chk.defCausumns = append(chk.defCausumns, newVarLenDeferredCauset(0, nil)) 335 } 336 } 337 return chk 338 } 339 340 func newChunkWithInitCap(cap int, elemLen ...int) *Chunk { 341 chk := &Chunk{} 342 for _, l := range elemLen { 343 if l > 0 { 344 chk.defCausumns = append(chk.defCausumns, newFixedLenDeferredCauset(l, cap)) 345 } else { 346 chk.defCausumns = append(chk.defCausumns, newVarLenDeferredCauset(cap, nil)) 347 } 348 } 349 return chk 350 } 351 352 var allTypes = []*types.FieldType{ 353 types.NewFieldType(allegrosql.TypeTiny), 354 types.NewFieldType(allegrosql.TypeShort), 355 types.NewFieldType(allegrosql.TypeInt24), 356 types.NewFieldType(allegrosql.TypeLong), 357 types.NewFieldType(allegrosql.TypeLonglong), 358 { 359 Tp: allegrosql.TypeLonglong, 360 Flen: types.UnspecifiedLength, 361 Decimal: types.UnspecifiedLength, 362 Flag: allegrosql.UnsignedFlag, 363 }, 364 types.NewFieldType(allegrosql.TypeYear), 365 types.NewFieldType(allegrosql.TypeFloat), 366 types.NewFieldType(allegrosql.TypeDouble), 367 types.NewFieldType(allegrosql.TypeString), 368 types.NewFieldType(allegrosql.TypeVarString), 369 types.NewFieldType(allegrosql.TypeVarchar), 370 types.NewFieldType(allegrosql.TypeBlob), 371 types.NewFieldType(allegrosql.TypeTinyBlob), 372 types.NewFieldType(allegrosql.TypeMediumBlob), 373 types.NewFieldType(allegrosql.TypeLongBlob), 374 types.NewFieldType(allegrosql.TypeDate), 375 types.NewFieldType(allegrosql.TypeDatetime), 376 types.NewFieldType(allegrosql.TypeTimestamp), 377 types.NewFieldType(allegrosql.TypeDuration), 378 types.NewFieldType(allegrosql.TypeNewDecimal), 379 { 380 Tp: allegrosql.TypeSet, 381 Flen: types.UnspecifiedLength, 382 Decimal: types.UnspecifiedLength, 383 Flag: allegrosql.UnsignedFlag, 384 Elems: []string{"a", "b"}, 385 }, 386 { 387 Tp: allegrosql.TypeEnum, 388 Flen: types.UnspecifiedLength, 389 Decimal: types.UnspecifiedLength, 390 Flag: allegrosql.UnsignedFlag, 391 Elems: []string{"a", "b"}, 392 }, 393 types.NewFieldType(allegrosql.TypeBit), 394 types.NewFieldType(allegrosql.TypeJSON), 395 } 396 397 func (s *testChunkSuite) TestCompare(c *check.C) { 398 chunk := NewChunkWithCapacity(allTypes, 32) 399 for i := 0; i < len(allTypes); i++ { 400 chunk.AppendNull(i) 401 } 402 for i := 0; i < len(allTypes); i++ { 403 switch allTypes[i].Tp { 404 case allegrosql.TypeTiny, allegrosql.TypeShort, allegrosql.TypeInt24, allegrosql.TypeLong, allegrosql.TypeLonglong, allegrosql.TypeYear: 405 if allegrosql.HasUnsignedFlag(allTypes[i].Flag) { 406 chunk.AppendUint64(i, 0) 407 } else { 408 chunk.AppendInt64(i, -1) 409 } 410 case allegrosql.TypeFloat: 411 chunk.AppendFloat32(i, 0) 412 case allegrosql.TypeDouble: 413 chunk.AppendFloat64(i, 0) 414 case allegrosql.TypeString, allegrosql.TypeVarString, allegrosql.TypeVarchar, 415 allegrosql.TypeBlob, allegrosql.TypeTinyBlob, allegrosql.TypeMediumBlob, allegrosql.TypeLongBlob: 416 chunk.AppendString(i, "0") 417 case allegrosql.TypeDate, allegrosql.TypeDatetime, allegrosql.TypeTimestamp: 418 chunk.AppendTime(i, types.TimeFromDays(2000*365)) 419 case allegrosql.TypeDuration: 420 chunk.AppendDuration(i, types.ZeroDuration) 421 case allegrosql.TypeNewDecimal: 422 chunk.AppendMyDecimal(i, types.NewDecFromInt(0)) 423 case allegrosql.TypeSet: 424 chunk.AppendSet(i, types.Set{Name: "a", Value: 0}) 425 case allegrosql.TypeEnum: 426 chunk.AppendEnum(i, types.Enum{Name: "a", Value: 0}) 427 case allegrosql.TypeBit: 428 chunk.AppendBytes(i, []byte{0}) 429 case allegrosql.TypeJSON: 430 chunk.AppendJSON(i, json.CreateBinary(int64(0))) 431 default: 432 c.FailNow() 433 } 434 } 435 for i := 0; i < len(allTypes); i++ { 436 switch allTypes[i].Tp { 437 case allegrosql.TypeTiny, allegrosql.TypeShort, allegrosql.TypeInt24, allegrosql.TypeLong, allegrosql.TypeLonglong, allegrosql.TypeYear: 438 if allegrosql.HasUnsignedFlag(allTypes[i].Flag) { 439 chunk.AppendUint64(i, math.MaxUint64) 440 } else { 441 chunk.AppendInt64(i, 1) 442 } 443 case allegrosql.TypeFloat: 444 chunk.AppendFloat32(i, 1) 445 case allegrosql.TypeDouble: 446 chunk.AppendFloat64(i, 1) 447 case allegrosql.TypeString, allegrosql.TypeVarString, allegrosql.TypeVarchar, 448 allegrosql.TypeBlob, allegrosql.TypeTinyBlob, allegrosql.TypeMediumBlob, allegrosql.TypeLongBlob: 449 chunk.AppendString(i, "1") 450 case allegrosql.TypeDate, allegrosql.TypeDatetime, allegrosql.TypeTimestamp: 451 chunk.AppendTime(i, types.TimeFromDays(2001*365)) 452 case allegrosql.TypeDuration: 453 chunk.AppendDuration(i, types.Duration{Duration: time.Second}) 454 case allegrosql.TypeNewDecimal: 455 chunk.AppendMyDecimal(i, types.NewDecFromInt(1)) 456 case allegrosql.TypeSet: 457 chunk.AppendSet(i, types.Set{Name: "b", Value: 1}) 458 case allegrosql.TypeEnum: 459 chunk.AppendEnum(i, types.Enum{Name: "b", Value: 1}) 460 case allegrosql.TypeBit: 461 chunk.AppendBytes(i, []byte{1}) 462 case allegrosql.TypeJSON: 463 chunk.AppendJSON(i, json.CreateBinary(int64(1))) 464 default: 465 c.FailNow() 466 } 467 } 468 rowNull := chunk.GetRow(0) 469 rowSmall := chunk.GetRow(1) 470 rowBig := chunk.GetRow(2) 471 for i := 0; i < len(allTypes); i++ { 472 cmpFunc := GetCompareFunc(allTypes[i]) 473 c.Assert(cmpFunc(rowNull, i, rowNull, i), check.Equals, 0) 474 c.Assert(cmpFunc(rowNull, i, rowSmall, i), check.Equals, -1) 475 c.Assert(cmpFunc(rowSmall, i, rowNull, i), check.Equals, 1) 476 c.Assert(cmpFunc(rowSmall, i, rowSmall, i), check.Equals, 0) 477 c.Assert(cmpFunc(rowSmall, i, rowBig, i), check.Equals, -1, check.Commentf("%d", allTypes[i].Tp)) 478 c.Assert(cmpFunc(rowBig, i, rowSmall, i), check.Equals, 1) 479 c.Assert(cmpFunc(rowBig, i, rowBig, i), check.Equals, 0) 480 } 481 } 482 483 func (s *testChunkSuite) TestCopyTo(c *check.C) { 484 chunk := NewChunkWithCapacity(allTypes, 101) 485 for i := 0; i < len(allTypes); i++ { 486 chunk.AppendNull(i) 487 } 488 for k := 0; k < 100; k++ { 489 for i := 0; i < len(allTypes); i++ { 490 switch allTypes[i].Tp { 491 case allegrosql.TypeTiny, allegrosql.TypeShort, allegrosql.TypeInt24, allegrosql.TypeLong, allegrosql.TypeLonglong, allegrosql.TypeYear: 492 if allegrosql.HasUnsignedFlag(allTypes[i].Flag) { 493 chunk.AppendUint64(i, uint64(k)) 494 } else { 495 chunk.AppendInt64(i, int64(k)) 496 } 497 case allegrosql.TypeFloat: 498 chunk.AppendFloat32(i, float32(k)) 499 case allegrosql.TypeDouble: 500 chunk.AppendFloat64(i, float64(k)) 501 case allegrosql.TypeString, allegrosql.TypeVarString, allegrosql.TypeVarchar, 502 allegrosql.TypeBlob, allegrosql.TypeTinyBlob, allegrosql.TypeMediumBlob, allegrosql.TypeLongBlob: 503 chunk.AppendString(i, fmt.Sprintf("%v", k)) 504 case allegrosql.TypeDate, allegrosql.TypeDatetime, allegrosql.TypeTimestamp: 505 chunk.AppendTime(i, types.TimeFromDays(2000*365+int64(k))) 506 case allegrosql.TypeDuration: 507 chunk.AppendDuration(i, types.Duration{Duration: time.Second * time.Duration(k), Fsp: types.DefaultFsp}) 508 case allegrosql.TypeNewDecimal: 509 chunk.AppendMyDecimal(i, types.NewDecFromInt(int64(k))) 510 case allegrosql.TypeSet: 511 chunk.AppendSet(i, types.Set{Name: "a", Value: uint64(k)}) 512 case allegrosql.TypeEnum: 513 chunk.AppendEnum(i, types.Enum{Name: "a", Value: uint64(k)}) 514 case allegrosql.TypeBit: 515 chunk.AppendBytes(i, []byte{byte(k)}) 516 case allegrosql.TypeJSON: 517 chunk.AppendJSON(i, json.CreateBinary(int64(k))) 518 default: 519 c.FailNow() 520 } 521 } 522 } 523 524 ck1 := chunk.CopyConstruct() 525 526 for k := 0; k < 101; k++ { 527 event := chunk.GetRow(k) 528 r1 := ck1.GetRow(k) 529 for i := 0; i < len(allTypes); i++ { 530 cmpFunc := GetCompareFunc(allTypes[i]) 531 c.Assert(cmpFunc(event, i, r1, i), check.Equals, 0) 532 } 533 534 } 535 } 536 537 func (s *testChunkSuite) TestGetDecimalCauset(c *check.C) { 538 causet := types.NewCauset(1.01) 539 decType := types.NewFieldType(allegrosql.TypeNewDecimal) 540 decType.Flen = 4 541 decType.Decimal = 2 542 sc := new(stmtctx.StatementContext) 543 decCauset, err := causet.ConvertTo(sc, decType) 544 c.Assert(err, check.IsNil) 545 chk := NewChunkWithCapacity([]*types.FieldType{decType}, 32) 546 chk.AppendMyDecimal(0, decCauset.GetMysqlDecimal()) 547 decFromChk := chk.GetRow(0).GetCauset(0, decType) 548 c.Assert(decCauset.Length(), check.Equals, decFromChk.Length()) 549 c.Assert(decCauset.Frac(), check.Equals, decFromChk.Frac()) 550 } 551 552 func (s *testChunkSuite) TestChunkMemoryUsage(c *check.C) { 553 fieldTypes := make([]*types.FieldType, 0, 5) 554 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 555 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeVarchar}) 556 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeJSON}) 557 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeDatetime}) 558 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeDuration}) 559 560 initCap := 10 561 chk := NewChunkWithCapacity(fieldTypes, initCap) 562 563 //cap(c.nullBitmap) + cap(c.offsets)*4 + cap(c.data) + cap(c.elemBuf) 564 defCausUsage := make([]int, len(fieldTypes)) 565 defCausUsage[0] = (initCap+7)>>3 + 0 + initCap*4 + 4 566 defCausUsage[1] = (initCap+7)>>3 + (initCap+1)*4 + initCap*8 + 0 567 defCausUsage[2] = (initCap+7)>>3 + (initCap+1)*4 + initCap*8 + 0 568 defCausUsage[3] = (initCap+7)>>3 + 0 + initCap*sizeTime + sizeTime 569 defCausUsage[4] = (initCap+7)>>3 + 0 + initCap*8 + 8 570 571 expectedUsage := 0 572 for i := range defCausUsage { 573 expectedUsage += defCausUsage[i] + int(unsafe.Sizeof(*chk.defCausumns[i])) 574 } 575 memUsage := chk.MemoryUsage() 576 c.Assert(memUsage, check.Equals, int64(expectedUsage)) 577 578 jsonObj, err := json.ParseBinaryFromString("1") 579 c.Assert(err, check.IsNil) 580 timeObj := types.NewTime(types.FromGoTime(time.Now()), allegrosql.TypeDatetime, 0) 581 durationObj := types.Duration{Duration: math.MaxInt64, Fsp: 0} 582 583 chk.AppendFloat32(0, 12.4) 584 chk.AppendString(1, "123") 585 chk.AppendJSON(2, jsonObj) 586 chk.AppendTime(3, timeObj) 587 chk.AppendDuration(4, durationObj) 588 589 memUsage = chk.MemoryUsage() 590 c.Assert(memUsage, check.Equals, int64(expectedUsage)) 591 592 chk.AppendFloat32(0, 12.4) 593 chk.AppendString(1, "123111111111111111111111111111111111111111111111") 594 chk.AppendJSON(2, jsonObj) 595 chk.AppendTime(3, timeObj) 596 chk.AppendDuration(4, durationObj) 597 598 memUsage = chk.MemoryUsage() 599 defCausUsage[1] = (initCap+7)>>3 + (initCap+1)*4 + cap(chk.defCausumns[1].data) + 0 600 expectedUsage = 0 601 for i := range defCausUsage { 602 expectedUsage += defCausUsage[i] + int(unsafe.Sizeof(*chk.defCausumns[i])) 603 } 604 c.Assert(memUsage, check.Equals, int64(expectedUsage)) 605 } 606 607 func (s *testChunkSuite) TestSwapDeferredCauset(c *check.C) { 608 fieldTypes := make([]*types.FieldType, 0, 2) 609 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 610 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 611 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 612 613 // chk1: defCausumn1 refers to defCausumn0 614 chk1 := NewChunkWithCapacity(fieldTypes, 1) 615 chk1.AppendFloat32(0, 1) 616 chk1.MakeRef(0, 1) 617 chk1.AppendFloat32(2, 3) 618 619 // chk2: defCausumn1 refers to defCausumn0 620 chk2 := NewChunkWithCapacity(fieldTypes, 1) 621 chk2.AppendFloat32(0, 1) 622 chk2.MakeRef(0, 1) 623 chk2.AppendFloat32(2, 3) 624 625 c.Assert(chk1.defCausumns[0] == chk1.defCausumns[1], check.IsTrue) 626 c.Assert(chk2.defCausumns[0] == chk2.defCausumns[1], check.IsTrue) 627 628 checkRef := func() { 629 c.Assert(chk1.defCausumns[0] == chk1.defCausumns[1], check.IsTrue) 630 c.Assert(chk1.defCausumns[0] == chk2.defCausumns[0], check.IsFalse) 631 c.Assert(chk2.defCausumns[0] == chk2.defCausumns[1], check.IsTrue) 632 } 633 634 chk1.SwapDeferredCauset(0, chk2, 0) 635 checkRef() 636 637 chk1.SwapDeferredCauset(0, chk2, 1) 638 checkRef() 639 640 chk2.SwapDeferredCauset(1, chk2, 0) 641 checkRef() 642 643 chk2.SwapDeferredCauset(1, chk2, 1) 644 checkRef() 645 646 chk2.SwapDeferredCauset(1, chk2, 2) 647 checkRef() 648 649 chk2.SwapDeferredCauset(2, chk2, 0) 650 checkRef() 651 } 652 653 func (s *testChunkSuite) TestPreAlloc4RowAndInsert(c *check.C) { 654 fieldTypes := make([]*types.FieldType, 0, 4) 655 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 656 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeLonglong}) 657 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeNewDecimal}) 658 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeVarchar}) 659 660 srcChk := NewChunkWithCapacity(fieldTypes, 10) 661 for i := int64(0); i < 10; i++ { 662 srcChk.AppendFloat32(0, float32(i)) 663 srcChk.AppendInt64(1, i) 664 srcChk.AppendMyDecimal(2, types.NewDecFromInt(i)) 665 srcChk.AppendString(3, strings.Repeat(strconv.FormatInt(i, 10), int(i))) 666 } 667 668 destChk := NewChunkWithCapacity(fieldTypes, 3) 669 670 // Test Chunk.PreAlloc. 671 for i := 0; i < srcChk.NumRows(); i++ { 672 c.Assert(destChk.NumRows(), check.Equals, i) 673 destChk.preAlloc(srcChk.GetRow(i)) 674 } 675 for i, srcDefCaus := range srcChk.defCausumns { 676 destDefCaus := destChk.defCausumns[i] 677 c.Assert(len(srcDefCaus.elemBuf), check.Equals, len(destDefCaus.elemBuf)) 678 c.Assert(len(srcDefCaus.data), check.Equals, len(destDefCaus.data)) 679 c.Assert(len(srcDefCaus.offsets), check.Equals, len(destDefCaus.offsets)) 680 c.Assert(len(srcDefCaus.nullBitmap), check.Equals, len(destDefCaus.nullBitmap)) 681 c.Assert(srcDefCaus.length, check.Equals, destDefCaus.length) 682 c.Assert(srcDefCaus.nullCount(), check.Equals, destDefCaus.nullCount()) 683 684 for _, val := range destDefCaus.data { 685 c.Assert(val == 0, check.IsTrue) 686 } 687 for j, val := range srcDefCaus.offsets { 688 c.Assert(val, check.Equals, destDefCaus.offsets[j]) 689 } 690 for j, val := range srcDefCaus.nullBitmap { 691 c.Assert(val, check.Equals, destDefCaus.nullBitmap[j]) 692 } 693 for _, val := range destDefCaus.elemBuf { 694 c.Assert(val == 0, check.IsTrue) 695 } 696 } 697 698 // Test Chunk.Insert. 699 for i := srcChk.NumRows() - 1; i >= 0; i-- { 700 destChk.insert(i, srcChk.GetRow(i)) 701 } 702 for i, srcDefCaus := range srcChk.defCausumns { 703 destDefCaus := destChk.defCausumns[i] 704 705 for j, val := range srcDefCaus.data { 706 c.Assert(val, check.Equals, destDefCaus.data[j]) 707 } 708 for j, val := range srcDefCaus.offsets { 709 c.Assert(val, check.Equals, destDefCaus.offsets[j]) 710 } 711 for j, val := range srcDefCaus.nullBitmap { 712 c.Assert(val, check.Equals, destDefCaus.nullBitmap[j]) 713 } 714 for _, val := range destDefCaus.elemBuf { 715 c.Assert(val == 0, check.IsTrue) 716 } 717 } 718 719 // Test parallel Chunk.Insert. 720 destChk.Reset() 721 startWg, endWg := &sync.WaitGroup{}, &sync.WaitGroup{} 722 startWg.Add(1) 723 for i := 0; i < srcChk.NumRows(); i++ { 724 destChk.preAlloc(srcChk.GetRow(i)) 725 endWg.Add(1) 726 go func(rowIdx int) { 727 defer func() { 728 endWg.Done() 729 }() 730 startWg.Wait() 731 destChk.insert(rowIdx, srcChk.GetRow(rowIdx)) 732 }(i) 733 } 734 startWg.Done() 735 endWg.Wait() 736 for i, srcDefCaus := range srcChk.defCausumns { 737 destDefCaus := destChk.defCausumns[i] 738 739 for j, val := range srcDefCaus.data { 740 c.Assert(val, check.Equals, destDefCaus.data[j]) 741 } 742 for j, val := range srcDefCaus.offsets { 743 c.Assert(val, check.Equals, destDefCaus.offsets[j]) 744 } 745 for j, val := range srcDefCaus.nullBitmap { 746 c.Assert(val, check.Equals, destDefCaus.nullBitmap[j]) 747 } 748 for _, val := range destDefCaus.elemBuf { 749 c.Assert(val == 0, check.IsTrue) 750 } 751 } 752 } 753 754 func (s *testChunkSuite) TestAppendSel(c *check.C) { 755 tll := &types.FieldType{Tp: allegrosql.TypeLonglong} 756 chk := NewChunkWithCapacity([]*types.FieldType{tll}, 1024) 757 sel := make([]int, 0, 1024/2) 758 for i := 0; i < 1024/2; i++ { 759 chk.AppendInt64(0, int64(i)) 760 if i%2 == 0 { 761 sel = append(sel, i) 762 } 763 } 764 chk.SetSel(sel) 765 c.Assert(chk.NumRows(), check.Equals, 1024/2/2) 766 chk.AppendInt64(0, int64(1)) 767 c.Assert(chk.NumRows(), check.Equals, 1024/2/2+1) 768 sel = chk.Sel() 769 c.Assert(sel[len(sel)-1], check.Equals, 1024/2) 770 } 771 772 func (s *testChunkSuite) TestMakeRefTo(c *check.C) { 773 fieldTypes := make([]*types.FieldType, 0, 2) 774 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 775 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 776 777 chk1 := NewChunkWithCapacity(fieldTypes, 1) 778 chk1.AppendFloat32(0, 1) 779 chk1.AppendFloat32(1, 3) 780 781 chk2 := NewChunkWithCapacity(fieldTypes, 1) 782 chk2.MakeRefTo(0, chk1, 1) 783 chk2.MakeRefTo(1, chk1, 0) 784 785 c.Assert(chk2.defCausumns[0] == chk1.defCausumns[1], check.IsTrue) 786 c.Assert(chk2.defCausumns[1] == chk1.defCausumns[0], check.IsTrue) 787 } 788 789 func BenchmarkAppendInt(b *testing.B) { 790 b.ReportAllocs() 791 chk := newChunk(8) 792 for i := 0; i < b.N; i++ { 793 appendInt(chk) 794 } 795 } 796 797 func appendInt(chk *Chunk) { 798 chk.Reset() 799 for i := 0; i < 1000; i++ { 800 chk.AppendInt64(0, int64(i)) 801 } 802 } 803 804 func BenchmarkAppendString(b *testing.B) { 805 b.ReportAllocs() 806 chk := newChunk(0) 807 for i := 0; i < b.N; i++ { 808 appendString(chk) 809 } 810 } 811 812 func appendString(chk *Chunk) { 813 chk.Reset() 814 for i := 0; i < 1000; i++ { 815 chk.AppendString(0, "abcd") 816 } 817 } 818 819 func BenchmarkAppendRow(b *testing.B) { 820 b.ReportAllocs() 821 rowChk := newChunk(8, 8, 0, 0) 822 rowChk.AppendNull(0) 823 rowChk.AppendInt64(1, 1) 824 rowChk.AppendString(2, "abcd") 825 rowChk.AppendBytes(3, []byte("abcd")) 826 827 chk := newChunk(8, 8, 0, 0) 828 for i := 0; i < b.N; i++ { 829 appendRow(chk, rowChk.GetRow(0)) 830 } 831 } 832 833 func appendRow(chk *Chunk, event Row) { 834 chk.Reset() 835 for i := 0; i < 1000; i++ { 836 chk.AppendRow(event) 837 } 838 } 839 840 func BenchmarkAppendBytes1024(b *testing.B) { 841 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 842 var bs = make([]byte, 256) 843 for i := 0; i < b.N; i++ { 844 appendBytes(chk, bs, 1024) 845 } 846 } 847 848 func BenchmarkAppendBytes512(b *testing.B) { 849 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 850 var bs = make([]byte, 256) 851 for i := 0; i < b.N; i++ { 852 appendBytes(chk, bs, 512) 853 } 854 } 855 856 func BenchmarkAppendBytes256(b *testing.B) { 857 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 858 var bs = make([]byte, 256) 859 for i := 0; i < b.N; i++ { 860 appendBytes(chk, bs, 256) 861 } 862 } 863 864 func BenchmarkAppendBytes128(b *testing.B) { 865 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 866 var bs = make([]byte, 256) 867 for i := 0; i < b.N; i++ { 868 appendBytes(chk, bs, 128) 869 } 870 } 871 872 func BenchmarkAppendBytes64(b *testing.B) { 873 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 874 var bs = make([]byte, 256) 875 for i := 0; i < b.N; i++ { 876 appendBytes(chk, bs, 64) 877 } 878 } 879 880 func BenchmarkAppendBytes32(b *testing.B) { 881 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 882 var bs = make([]byte, 256) 883 for i := 0; i < b.N; i++ { 884 appendBytes(chk, bs, 32) 885 } 886 } 887 888 func BenchmarkAppendBytes16(b *testing.B) { 889 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 890 var bs = make([]byte, 256) 891 for i := 0; i < b.N; i++ { 892 appendBytes(chk, bs, 16) 893 } 894 } 895 896 func BenchmarkAppendBytes8(b *testing.B) { 897 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 898 var bs = make([]byte, 256) 899 for i := 0; i < b.N; i++ { 900 appendBytes(chk, bs, 8) 901 } 902 } 903 904 func BenchmarkAppendBytes4(b *testing.B) { 905 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 906 var bs = make([]byte, 256) 907 for i := 0; i < b.N; i++ { 908 appendBytes(chk, bs, 4) 909 } 910 } 911 912 func BenchmarkAppendBytes2(b *testing.B) { 913 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 914 var bs = make([]byte, 256) 915 for i := 0; i < b.N; i++ { 916 appendBytes(chk, bs, 2) 917 } 918 } 919 920 func BenchmarkAppendBytes1(b *testing.B) { 921 chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeString)}, 32) 922 var bs = make([]byte, 256) 923 for i := 0; i < b.N; i++ { 924 appendBytes(chk, bs, 1) 925 } 926 } 927 928 func appendBytes(chk *Chunk, bs []byte, times int) { 929 chk.Reset() 930 for i := 0; i < times; i++ { 931 chk.AppendBytes(0, bs) 932 } 933 } 934 935 func BenchmarkAccess(b *testing.B) { 936 b.StopTimer() 937 rowChk := newChunk(8) 938 for i := 0; i < 8192; i++ { 939 rowChk.AppendInt64(0, math.MaxUint16) 940 } 941 b.StartTimer() 942 var sum int64 943 for i := 0; i < b.N; i++ { 944 for j := 0; j < 8192; j++ { 945 sum += rowChk.GetRow(j).GetInt64(0) 946 } 947 } 948 fmt.Println(sum) 949 } 950 951 func BenchmarkChunkMemoryUsage(b *testing.B) { 952 fieldTypes := make([]*types.FieldType, 0, 4) 953 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeFloat}) 954 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeVarchar}) 955 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeDatetime}) 956 fieldTypes = append(fieldTypes, &types.FieldType{Tp: allegrosql.TypeDuration}) 957 958 initCap := 10 959 chk := NewChunkWithCapacity(fieldTypes, initCap) 960 timeObj := types.NewTime(types.FromGoTime(time.Now()), allegrosql.TypeDatetime, 0) 961 durationObj := types.Duration{Duration: math.MaxInt64, Fsp: 0} 962 963 for i := 0; i < initCap; i++ { 964 chk.AppendFloat64(0, 123.123) 965 chk.AppendString(1, "123") 966 chk.AppendTime(2, timeObj) 967 chk.AppendDuration(3, durationObj) 968 } 969 b.ResetTimer() 970 for i := 0; i < b.N; i++ { 971 chk.MemoryUsage() 972 } 973 } 974 975 type seqNumberGenerateInterDirc struct { 976 seq int 977 genCountSize int 978 } 979 980 func (x *seqNumberGenerateInterDirc) Next(chk *Chunk, resize bool) { 981 if resize { 982 chk.GrowAndReset(1024) 983 } else { 984 chk.Reset() 985 } 986 for chk.NumRows() < chk.Capacity() { 987 x.seq++ 988 if x.seq > x.genCountSize { 989 break 990 } 991 chk.AppendInt64(0, 1) 992 } 993 } 994 995 type benchChunkGrowCase struct { 996 tag string 997 reuse bool 998 newReset bool 999 cntPerCall int 1000 initCap int 1001 maxCap int 1002 } 1003 1004 func (b *benchChunkGrowCase) String() string { 1005 var buff bytes.Buffer 1006 if b.reuse { 1007 buff.WriteString("renew,") 1008 } else { 1009 buff.WriteString("reset,") 1010 } 1011 buff.WriteString("cntPerCall:" + strconv.Itoa(b.cntPerCall) + ",") 1012 buff.WriteString("cap from:" + strconv.Itoa(b.initCap) + " to " + strconv.Itoa(b.maxCap) + ",") 1013 if b.tag != "" { 1014 buff.WriteString("[" + b.tag + "]") 1015 } 1016 return buff.String() 1017 } 1018 1019 func BenchmarkChunkGrowSuit(b *testing.B) { 1020 tests := []benchChunkGrowCase{ 1021 {reuse: true, newReset: false, cntPerCall: 10000000, initCap: 1024, maxCap: 1024}, 1022 {reuse: true, newReset: false, cntPerCall: 10000000, initCap: 32, maxCap: 32}, 1023 {reuse: true, newReset: true, cntPerCall: 10000000, initCap: 32, maxCap: 1024, tag: "grow"}, 1024 {reuse: false, newReset: false, cntPerCall: 10000000, initCap: 1024, maxCap: 1024}, 1025 {reuse: false, newReset: false, cntPerCall: 10000000, initCap: 32, maxCap: 32}, 1026 {reuse: false, newReset: true, cntPerCall: 10000000, initCap: 32, maxCap: 1024, tag: "grow"}, 1027 {reuse: true, newReset: false, cntPerCall: 10, initCap: 1024, maxCap: 1024}, 1028 {reuse: true, newReset: false, cntPerCall: 10, initCap: 32, maxCap: 32}, 1029 {reuse: true, newReset: true, cntPerCall: 10, initCap: 32, maxCap: 1024, tag: "grow"}, 1030 {reuse: false, newReset: false, cntPerCall: 10, initCap: 1024, maxCap: 1024}, 1031 {reuse: false, newReset: false, cntPerCall: 10, initCap: 32, maxCap: 32}, 1032 {reuse: false, newReset: true, cntPerCall: 10, initCap: 32, maxCap: 1024, tag: "grow"}, 1033 } 1034 for _, test := range tests { 1035 b.Run(test.String(), benchmarkChunkGrow(test)) 1036 } 1037 } 1038 1039 func benchmarkChunkGrow(t benchChunkGrowCase) func(b *testing.B) { 1040 return func(b *testing.B) { 1041 b.ReportAllocs() 1042 chk := New([]*types.FieldType{{Tp: allegrosql.TypeLong}}, t.initCap, t.maxCap) 1043 b.ResetTimer() 1044 for i := 0; i < b.N; i++ { 1045 e := &seqNumberGenerateInterDirc{genCountSize: t.cntPerCall} 1046 for { 1047 e.Next(chk, t.newReset) 1048 if chk.NumRows() == 0 { 1049 break 1050 } 1051 if !t.reuse { 1052 if t.newReset { 1053 chk = Renew(chk, t.maxCap) 1054 } else { 1055 chk = New([]*types.FieldType{{Tp: allegrosql.TypeLong}}, t.initCap, t.maxCap) 1056 } 1057 } 1058 } 1059 } 1060 } 1061 }