github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/allegrosql/memdb_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Copyright 2020 Wenbin Xiao 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package ekv 17 18 import ( 19 "context" 20 "encoding/binary" 21 "fmt" 22 "math" 23 "testing" 24 25 . "github.com/whtcorpsinc/check" 26 leveldb "github.com/whtcorpsinc/goleveldb/leveldb/memdb" 27 "github.com/whtcorpsinc/milevadb/soliton/testleak" 28 ) 29 30 func init() { 31 testMode = true 32 } 33 34 func TestT(t *testing.T) { 35 CustomVerboseFlag = true 36 TestingT(t) 37 } 38 39 var ( 40 _ = Suite(&testKVSuite{}) 41 _ = Suite(&testMemDBSuite{}) 42 ) 43 44 type testMemDBSuite struct{} 45 46 // DeleteKey is used in test to verify the `deleteNode` used in `vlog.revertToCheckpoint`. 47 func (EDB *memdb) DeleteKey(key []byte) { 48 x := EDB.traverse(key, false) 49 if x.isNull() { 50 return 51 } 52 EDB.size -= len(EDB.vlog.getValue(x.vptr)) 53 EDB.deleteNode(x) 54 } 55 56 func (s *testMemDBSuite) TestGetSet(c *C) { 57 const cnt = 10000 58 p := s.fillDB(cnt) 59 60 var buf [4]byte 61 for i := 0; i < cnt; i++ { 62 binary.BigEndian.PutUint32(buf[:], uint32(i)) 63 v, err := p.Get(context.TODO(), buf[:]) 64 c.Assert(err, IsNil) 65 c.Assert(v, BytesEquals, buf[:]) 66 } 67 } 68 69 func (s *testMemDBSuite) TestBigKV(c *C) { 70 EDB := newMemDB() 71 EDB.entrySizeLimit = math.MaxUint64 72 EDB.bufferSizeLimit = math.MaxUint64 73 EDB.Set([]byte{1}, make([]byte, 80<<20)) 74 c.Assert(EDB.vlog.blockSize, Equals, maxBlockSize) 75 c.Assert(len(EDB.vlog.blocks), Equals, 1) 76 h := EDB.Staging() 77 EDB.Set([]byte{2}, make([]byte, 127<<20)) 78 EDB.Release(h) 79 c.Assert(EDB.vlog.blockSize, Equals, maxBlockSize) 80 c.Assert(len(EDB.vlog.blocks), Equals, 2) 81 c.Assert(func() { EDB.Set([]byte{3}, make([]byte, maxBlockSize+1)) }, Panics, "alloc size is larger than max causet size") 82 } 83 84 func (s *testMemDBSuite) TestIterator(c *C) { 85 const cnt = 10000 86 EDB := s.fillDB(cnt) 87 88 var buf [4]byte 89 var i int 90 91 for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() { 92 binary.BigEndian.PutUint32(buf[:], uint32(i)) 93 c.Assert([]byte(it.Key()), BytesEquals, buf[:]) 94 c.Assert(it.Value(), BytesEquals, buf[:]) 95 i++ 96 } 97 c.Assert(i, Equals, cnt) 98 99 i-- 100 for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() { 101 binary.BigEndian.PutUint32(buf[:], uint32(i)) 102 c.Assert([]byte(it.Key()), BytesEquals, buf[:]) 103 c.Assert(it.Value(), BytesEquals, buf[:]) 104 i-- 105 } 106 c.Assert(i, Equals, -1) 107 } 108 109 func (s *testMemDBSuite) TestDiscard(c *C) { 110 const cnt = 10000 111 EDB := newMemDB() 112 base := s.deriveAndFill(0, cnt, 0, EDB) 113 sz := EDB.Size() 114 115 EDB.Cleanup(s.deriveAndFill(0, cnt, 1, EDB)) 116 c.Assert(EDB.Len(), Equals, cnt) 117 c.Assert(EDB.Size(), Equals, sz) 118 119 var buf [4]byte 120 121 for i := 0; i < cnt; i++ { 122 binary.BigEndian.PutUint32(buf[:], uint32(i)) 123 v, err := EDB.Get(context.TODO(), buf[:]) 124 c.Assert(err, IsNil) 125 c.Assert(v, BytesEquals, buf[:]) 126 } 127 128 var i int 129 for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() { 130 binary.BigEndian.PutUint32(buf[:], uint32(i)) 131 c.Assert([]byte(it.Key()), BytesEquals, buf[:]) 132 c.Assert(it.Value(), BytesEquals, buf[:]) 133 i++ 134 } 135 c.Assert(i, Equals, cnt) 136 137 i-- 138 for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() { 139 binary.BigEndian.PutUint32(buf[:], uint32(i)) 140 c.Assert([]byte(it.Key()), BytesEquals, buf[:]) 141 c.Assert(it.Value(), BytesEquals, buf[:]) 142 i-- 143 } 144 c.Assert(i, Equals, -1) 145 146 EDB.Cleanup(base) 147 for i := 0; i < cnt; i++ { 148 binary.BigEndian.PutUint32(buf[:], uint32(i)) 149 _, err := EDB.Get(context.TODO(), buf[:]) 150 c.Assert(err, NotNil) 151 } 152 it1, _ := EDB.Iter(nil, nil) 153 it := it1.(*memdbIterator) 154 it.seekToFirst() 155 c.Assert(it.Valid(), IsFalse) 156 it.seekToLast() 157 c.Assert(it.Valid(), IsFalse) 158 it.seek([]byte{0xff}) 159 c.Assert(it.Valid(), IsFalse) 160 } 161 162 func (s *testMemDBSuite) TestFlushOverwrite(c *C) { 163 const cnt = 10000 164 EDB := newMemDB() 165 EDB.Release(s.deriveAndFill(0, cnt, 0, EDB)) 166 sz := EDB.Size() 167 168 EDB.Release(s.deriveAndFill(0, cnt, 1, EDB)) 169 170 c.Assert(EDB.Len(), Equals, cnt) 171 c.Assert(EDB.Size(), Equals, sz) 172 173 var kbuf, vbuf [4]byte 174 175 for i := 0; i < cnt; i++ { 176 binary.BigEndian.PutUint32(kbuf[:], uint32(i)) 177 binary.BigEndian.PutUint32(vbuf[:], uint32(i+1)) 178 v, err := EDB.Get(context.TODO(), kbuf[:]) 179 c.Assert(err, IsNil) 180 c.Assert(v, DeepEquals, vbuf[:]) 181 } 182 183 var i int 184 for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() { 185 binary.BigEndian.PutUint32(kbuf[:], uint32(i)) 186 binary.BigEndian.PutUint32(vbuf[:], uint32(i+1)) 187 c.Assert([]byte(it.Key()), BytesEquals, kbuf[:]) 188 c.Assert(it.Value(), BytesEquals, vbuf[:]) 189 i++ 190 } 191 c.Assert(i, Equals, cnt) 192 193 i-- 194 for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() { 195 binary.BigEndian.PutUint32(kbuf[:], uint32(i)) 196 binary.BigEndian.PutUint32(vbuf[:], uint32(i+1)) 197 c.Assert([]byte(it.Key()), BytesEquals, kbuf[:]) 198 c.Assert(it.Value(), BytesEquals, vbuf[:]) 199 i-- 200 } 201 c.Assert(i, Equals, -1) 202 } 203 204 func (s *testMemDBSuite) TestComplexUFIDelate(c *C) { 205 const ( 206 keep = 3000 207 overwrite = 6000 208 insert = 9000 209 ) 210 211 EDB := newMemDB() 212 EDB.Release(s.deriveAndFill(0, overwrite, 0, EDB)) 213 c.Assert(EDB.Len(), Equals, overwrite) 214 EDB.Release(s.deriveAndFill(keep, insert, 1, EDB)) 215 c.Assert(EDB.Len(), Equals, insert) 216 217 var kbuf, vbuf [4]byte 218 219 for i := 0; i < insert; i++ { 220 binary.BigEndian.PutUint32(kbuf[:], uint32(i)) 221 binary.BigEndian.PutUint32(vbuf[:], uint32(i)) 222 if i >= keep { 223 binary.BigEndian.PutUint32(vbuf[:], uint32(i+1)) 224 } 225 v, err := EDB.Get(context.TODO(), kbuf[:]) 226 c.Assert(err, IsNil) 227 c.Assert(v, BytesEquals, vbuf[:]) 228 } 229 } 230 231 func (s *testMemDBSuite) TestNestedSandbox(c *C) { 232 EDB := newMemDB() 233 h0 := s.deriveAndFill(0, 200, 0, EDB) 234 h1 := s.deriveAndFill(0, 100, 1, EDB) 235 h2 := s.deriveAndFill(50, 150, 2, EDB) 236 h3 := s.deriveAndFill(100, 120, 3, EDB) 237 h4 := s.deriveAndFill(0, 150, 4, EDB) 238 EDB.Cleanup(h4) // Discard (0..150 -> 4) 239 EDB.Release(h3) // Flush (100..120 -> 3) 240 EDB.Cleanup(h2) // Discard (100..120 -> 3) & (50..150 -> 2) 241 EDB.Release(h1) // Flush (0..100 -> 1) 242 EDB.Release(h0) // Flush (0..100 -> 1) & (0..200 -> 0) 243 // The final result should be (0..100 -> 1) & (101..200 -> 0) 244 245 var kbuf, vbuf [4]byte 246 247 for i := 0; i < 200; i++ { 248 binary.BigEndian.PutUint32(kbuf[:], uint32(i)) 249 binary.BigEndian.PutUint32(vbuf[:], uint32(i)) 250 if i < 100 { 251 binary.BigEndian.PutUint32(vbuf[:], uint32(i+1)) 252 } 253 v, err := EDB.Get(context.TODO(), kbuf[:]) 254 c.Assert(err, IsNil) 255 c.Assert(v, BytesEquals, vbuf[:]) 256 } 257 258 var i int 259 260 for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() { 261 binary.BigEndian.PutUint32(kbuf[:], uint32(i)) 262 binary.BigEndian.PutUint32(vbuf[:], uint32(i)) 263 if i < 100 { 264 binary.BigEndian.PutUint32(vbuf[:], uint32(i+1)) 265 } 266 c.Assert([]byte(it.Key()), BytesEquals, kbuf[:]) 267 c.Assert(it.Value(), BytesEquals, vbuf[:]) 268 i++ 269 } 270 c.Assert(i, Equals, 200) 271 272 i-- 273 for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() { 274 binary.BigEndian.PutUint32(kbuf[:], uint32(i)) 275 binary.BigEndian.PutUint32(vbuf[:], uint32(i)) 276 if i < 100 { 277 binary.BigEndian.PutUint32(vbuf[:], uint32(i+1)) 278 } 279 c.Assert([]byte(it.Key()), BytesEquals, kbuf[:]) 280 c.Assert(it.Value(), BytesEquals, vbuf[:]) 281 i-- 282 } 283 c.Assert(i, Equals, -1) 284 } 285 286 func (s *testMemDBSuite) TestOverwrite(c *C) { 287 const cnt = 10000 288 EDB := s.fillDB(cnt) 289 var buf [4]byte 290 291 sz := EDB.Size() 292 for i := 0; i < cnt; i += 3 { 293 var newBuf [4]byte 294 binary.BigEndian.PutUint32(buf[:], uint32(i)) 295 binary.BigEndian.PutUint32(newBuf[:], uint32(i*10)) 296 EDB.Set(buf[:], newBuf[:]) 297 } 298 c.Assert(EDB.Len(), Equals, cnt) 299 c.Assert(EDB.Size(), Equals, sz) 300 301 for i := 0; i < cnt; i++ { 302 binary.BigEndian.PutUint32(buf[:], uint32(i)) 303 val, _ := EDB.Get(context.TODO(), buf[:]) 304 v := binary.BigEndian.Uint32(val) 305 if i%3 == 0 { 306 c.Assert(v, Equals, uint32(i*10)) 307 } else { 308 c.Assert(v, Equals, uint32(i)) 309 } 310 } 311 312 var i int 313 314 for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() { 315 binary.BigEndian.PutUint32(buf[:], uint32(i)) 316 c.Assert([]byte(it.Key()), BytesEquals, buf[:]) 317 v := binary.BigEndian.Uint32(it.Value()) 318 if i%3 == 0 { 319 c.Assert(v, Equals, uint32(i*10)) 320 } else { 321 c.Assert(v, Equals, uint32(i)) 322 } 323 i++ 324 } 325 c.Assert(i, Equals, cnt) 326 327 i-- 328 for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() { 329 binary.BigEndian.PutUint32(buf[:], uint32(i)) 330 c.Assert([]byte(it.Key()), BytesEquals, buf[:]) 331 v := binary.BigEndian.Uint32(it.Value()) 332 if i%3 == 0 { 333 c.Assert(v, Equals, uint32(i*10)) 334 } else { 335 c.Assert(v, Equals, uint32(i)) 336 } 337 i-- 338 } 339 c.Assert(i, Equals, -1) 340 } 341 342 func (s *testMemDBSuite) TestKVLargeThanBlock(c *C) { 343 EDB := newMemDB() 344 EDB.Set([]byte{1}, make([]byte, 1)) 345 EDB.Set([]byte{2}, make([]byte, 4096)) 346 c.Assert(len(EDB.vlog.blocks), Equals, 2) 347 EDB.Set([]byte{3}, make([]byte, 3000)) 348 c.Assert(len(EDB.vlog.blocks), Equals, 2) 349 val, err := EDB.Get(context.TODO(), []byte{3}) 350 c.Assert(err, IsNil) 351 c.Assert(len(val), Equals, 3000) 352 } 353 354 func (s *testMemDBSuite) TestEmptyDB(c *C) { 355 EDB := newMemDB() 356 _, err := EDB.Get(context.TODO(), []byte{0}) 357 c.Assert(err, NotNil) 358 it1, _ := EDB.Iter(nil, nil) 359 it := it1.(*memdbIterator) 360 it.seekToFirst() 361 c.Assert(it.Valid(), IsFalse) 362 it.seekToLast() 363 c.Assert(it.Valid(), IsFalse) 364 it.seek([]byte{0xff}) 365 c.Assert(it.Valid(), IsFalse) 366 } 367 368 func (s *testMemDBSuite) TestReset(c *C) { 369 EDB := s.fillDB(1000) 370 EDB.Reset() 371 _, err := EDB.Get(context.TODO(), []byte{0, 0, 0, 0}) 372 c.Assert(err, NotNil) 373 it1, _ := EDB.Iter(nil, nil) 374 it := it1.(*memdbIterator) 375 it.seekToFirst() 376 c.Assert(it.Valid(), IsFalse) 377 it.seekToLast() 378 c.Assert(it.Valid(), IsFalse) 379 it.seek([]byte{0xff}) 380 c.Assert(it.Valid(), IsFalse) 381 } 382 383 func (s *testMemDBSuite) TestInspectStage(c *C) { 384 EDB := newMemDB() 385 h1 := s.deriveAndFill(0, 1000, 0, EDB) 386 h2 := s.deriveAndFill(500, 1000, 1, EDB) 387 for i := 500; i < 1500; i++ { 388 var kbuf [4]byte 389 // don't uFIDelate in place 390 var vbuf [5]byte 391 binary.BigEndian.PutUint32(kbuf[:], uint32(i)) 392 binary.BigEndian.PutUint32(vbuf[:], uint32(i+2)) 393 EDB.Set(kbuf[:], vbuf[:]) 394 } 395 h3 := s.deriveAndFill(1000, 2000, 3, EDB) 396 397 EDB.InspectStage(h3, func(key Key, _ KeyFlags, val []byte) { 398 k := int(binary.BigEndian.Uint32(key)) 399 v := int(binary.BigEndian.Uint32(val)) 400 401 c.Assert(k >= 1000 && k < 2000, IsTrue) 402 c.Assert(v-k, DeepEquals, 3) 403 }) 404 405 EDB.InspectStage(h2, func(key Key, _ KeyFlags, val []byte) { 406 k := int(binary.BigEndian.Uint32(key)) 407 v := int(binary.BigEndian.Uint32(val)) 408 409 c.Assert(k >= 500 && k < 2000, IsTrue) 410 if k < 1000 { 411 c.Assert(v-k, Equals, 2) 412 } else { 413 c.Assert(v-k, Equals, 3) 414 } 415 }) 416 417 EDB.Cleanup(h3) 418 EDB.Release(h2) 419 420 EDB.InspectStage(h1, func(key Key, _ KeyFlags, val []byte) { 421 k := int(binary.BigEndian.Uint32(key)) 422 v := int(binary.BigEndian.Uint32(val)) 423 424 c.Assert(k >= 0 && k < 1500, IsTrue) 425 if k < 500 { 426 c.Assert(v-k, Equals, 0) 427 } else { 428 c.Assert(v-k, Equals, 2) 429 } 430 }) 431 432 EDB.Release(h1) 433 } 434 435 func (s *testMemDBSuite) TestDirty(c *C) { 436 EDB := newMemDB() 437 EDB.Set([]byte{1}, []byte{1}) 438 c.Assert(EDB.Dirty(), IsTrue) 439 440 EDB = newMemDB() 441 h := EDB.Staging() 442 EDB.Set([]byte{1}, []byte{1}) 443 EDB.Cleanup(h) 444 c.Assert(EDB.Dirty(), IsFalse) 445 446 h = EDB.Staging() 447 EDB.Set([]byte{1}, []byte{1}) 448 EDB.Release(h) 449 c.Assert(EDB.Dirty(), IsTrue) 450 451 // persistent flags will make memdb dirty. 452 EDB = newMemDB() 453 h = EDB.Staging() 454 EDB.SetWithFlags([]byte{1}, []byte{1}, SetKeyLocked) 455 EDB.Cleanup(h) 456 c.Assert(EDB.Dirty(), IsTrue) 457 458 // non-persistent flags will not make memdb dirty. 459 EDB = newMemDB() 460 h = EDB.Staging() 461 EDB.SetWithFlags([]byte{1}, []byte{1}, SetPresumeKeyNotExists) 462 EDB.Cleanup(h) 463 c.Assert(EDB.Dirty(), IsFalse) 464 } 465 466 func (s *testMemDBSuite) TestFlags(c *C) { 467 const cnt = 10000 468 EDB := newMemDB() 469 h := EDB.Staging() 470 for i := uint32(0); i < cnt; i++ { 471 var buf [4]byte 472 binary.BigEndian.PutUint32(buf[:], i) 473 if i%2 == 0 { 474 EDB.SetWithFlags(buf[:], buf[:], SetPresumeKeyNotExists, SetKeyLocked) 475 } else { 476 EDB.SetWithFlags(buf[:], buf[:], SetPresumeKeyNotExists) 477 } 478 } 479 EDB.Cleanup(h) 480 481 for i := uint32(0); i < cnt; i++ { 482 var buf [4]byte 483 binary.BigEndian.PutUint32(buf[:], i) 484 _, err := EDB.Get(context.TODO(), buf[:]) 485 c.Assert(err, NotNil) 486 flags, err := EDB.GetFlags(buf[:]) 487 if i%2 == 0 { 488 c.Assert(err, IsNil) 489 c.Assert(flags.HasLocked(), IsTrue) 490 c.Assert(flags.HasPresumeKeyNotExists(), IsFalse) 491 } else { 492 c.Assert(err, NotNil) 493 } 494 } 495 496 c.Assert(EDB.Len(), Equals, 5000) 497 c.Assert(EDB.Size(), Equals, 20000) 498 499 it1, _ := EDB.Iter(nil, nil) 500 it := it1.(*memdbIterator) 501 c.Assert(it.Valid(), IsFalse) 502 503 it.includeFlags = true 504 it.init() 505 506 for ; it.Valid(); it.Next() { 507 k := binary.BigEndian.Uint32(it.Key()) 508 c.Assert(k%2 == 0, IsTrue) 509 } 510 511 for i := uint32(0); i < cnt; i++ { 512 var buf [4]byte 513 binary.BigEndian.PutUint32(buf[:], i) 514 EDB.UFIDelateFlags(buf[:], DelKeyLocked) 515 } 516 for i := uint32(0); i < cnt; i++ { 517 var buf [4]byte 518 binary.BigEndian.PutUint32(buf[:], i) 519 _, err := EDB.Get(context.TODO(), buf[:]) 520 c.Assert(err, NotNil) 521 522 // UFIDelateFlags will create missing node. 523 flags, err := EDB.GetFlags(buf[:]) 524 c.Assert(err, IsNil) 525 c.Assert(flags.HasLocked(), IsFalse) 526 } 527 } 528 529 func (s *testMemDBSuite) checkConsist(c *C, p1 *memdb, p2 *leveldb.EDB) { 530 c.Assert(p1.Len(), Equals, p2.Len()) 531 c.Assert(p1.Size(), Equals, p2.Size()) 532 533 it1, _ := p1.Iter(nil, nil) 534 it2 := p2.NewIterator(nil) 535 536 var prevKey, prevVal []byte 537 for it2.First(); it2.Valid(); it2.Next() { 538 v, err := p1.Get(context.TODO(), it2.Key()) 539 c.Assert(err, IsNil) 540 c.Assert(v, BytesEquals, it2.Value()) 541 542 c.Assert([]byte(it1.Key()), BytesEquals, it2.Key()) 543 c.Assert(it1.Value(), BytesEquals, it2.Value()) 544 545 it, _ := p1.Iter(it2.Key(), nil) 546 c.Assert([]byte(it.Key()), BytesEquals, it2.Key()) 547 c.Assert(it.Value(), BytesEquals, it2.Value()) 548 549 if prevKey != nil { 550 it, _ = p1.IterReverse(it2.Key()) 551 c.Assert([]byte(it.Key()), BytesEquals, prevKey) 552 c.Assert(it.Value(), BytesEquals, prevVal) 553 } 554 555 it1.Next() 556 prevKey = it2.Key() 557 prevVal = it2.Value() 558 } 559 560 it1, _ = p1.IterReverse(nil) 561 for it2.Last(); it2.Valid(); it2.Prev() { 562 c.Assert([]byte(it1.Key()), BytesEquals, it2.Key()) 563 c.Assert(it1.Value(), BytesEquals, it2.Value()) 564 it1.Next() 565 } 566 } 567 568 func (s *testMemDBSuite) fillDB(cnt int) *memdb { 569 EDB := newMemDB() 570 h := s.deriveAndFill(0, cnt, 0, EDB) 571 EDB.Release(h) 572 return EDB 573 } 574 575 func (s *testMemDBSuite) deriveAndFill(start, end, valueBase int, EDB *memdb) StagingHandle { 576 h := EDB.Staging() 577 var kbuf, vbuf [4]byte 578 for i := start; i < end; i++ { 579 binary.BigEndian.PutUint32(kbuf[:], uint32(i)) 580 binary.BigEndian.PutUint32(vbuf[:], uint32(i+valueBase)) 581 EDB.Set(kbuf[:], vbuf[:]) 582 } 583 return h 584 } 585 586 const ( 587 startIndex = 0 588 testCount = 2 589 indexStep = 2 590 ) 591 592 type testKVSuite struct { 593 bs []MemBuffer 594 } 595 596 func (s *testKVSuite) SetUpSuite(c *C) { 597 s.bs = make([]MemBuffer, 1) 598 s.bs[0] = newMemDB() 599 } 600 601 func (s *testKVSuite) ResetMembuffers() { 602 s.bs[0] = newMemDB() 603 } 604 605 func insertData(c *C, buffer MemBuffer) { 606 for i := startIndex; i < testCount; i++ { 607 val := encodeInt(i * indexStep) 608 err := buffer.Set(val, val) 609 c.Assert(err, IsNil) 610 } 611 } 612 613 func encodeInt(n int) []byte { 614 return []byte(fmt.Sprintf("%010d", n)) 615 } 616 617 func decodeInt(s []byte) int { 618 var n int 619 fmt.Sscanf(string(s), "%010d", &n) 620 return n 621 } 622 623 func valToStr(c *C, iter Iterator) string { 624 val := iter.Value() 625 return string(val) 626 } 627 628 func checkNewIterator(c *C, buffer MemBuffer) { 629 for i := startIndex; i < testCount; i++ { 630 val := encodeInt(i * indexStep) 631 iter, err := buffer.Iter(val, nil) 632 c.Assert(err, IsNil) 633 c.Assert([]byte(iter.Key()), BytesEquals, val) 634 c.Assert(decodeInt([]byte(valToStr(c, iter))), Equals, i*indexStep) 635 iter.Close() 636 } 637 638 // Test iterator Next() 639 for i := startIndex; i < testCount-1; i++ { 640 val := encodeInt(i * indexStep) 641 iter, err := buffer.Iter(val, nil) 642 c.Assert(err, IsNil) 643 c.Assert([]byte(iter.Key()), BytesEquals, val) 644 c.Assert(valToStr(c, iter), Equals, string(val)) 645 646 err = iter.Next() 647 c.Assert(err, IsNil) 648 c.Assert(iter.Valid(), IsTrue) 649 650 val = encodeInt((i + 1) * indexStep) 651 c.Assert([]byte(iter.Key()), BytesEquals, val) 652 c.Assert(valToStr(c, iter), Equals, string(val)) 653 iter.Close() 654 } 655 656 // Non exist and beyond maximum seek test 657 iter, err := buffer.Iter(encodeInt(testCount*indexStep), nil) 658 c.Assert(err, IsNil) 659 c.Assert(iter.Valid(), IsFalse) 660 661 // Non exist but between existing keys seek test, 662 // it returns the smallest key that larger than the one we are seeking 663 inBetween := encodeInt((testCount-1)*indexStep - 1) 664 last := encodeInt((testCount - 1) * indexStep) 665 iter, err = buffer.Iter(inBetween, nil) 666 c.Assert(err, IsNil) 667 c.Assert(iter.Valid(), IsTrue) 668 c.Assert([]byte(iter.Key()), Not(BytesEquals), inBetween) 669 c.Assert([]byte(iter.Key()), BytesEquals, last) 670 iter.Close() 671 } 672 673 func mustGet(c *C, buffer MemBuffer) { 674 for i := startIndex; i < testCount; i++ { 675 s := encodeInt(i * indexStep) 676 val, err := buffer.Get(context.TODO(), s) 677 c.Assert(err, IsNil) 678 c.Assert(string(val), Equals, string(s)) 679 } 680 } 681 682 func (s *testKVSuite) TestGetSet(c *C) { 683 defer testleak.AfterTest(c)() 684 for _, buffer := range s.bs { 685 insertData(c, buffer) 686 mustGet(c, buffer) 687 } 688 s.ResetMembuffers() 689 } 690 691 func (s *testKVSuite) TestNewIterator(c *C) { 692 defer testleak.AfterTest(c)() 693 for _, buffer := range s.bs { 694 // should be invalid 695 iter, err := buffer.Iter(nil, nil) 696 c.Assert(err, IsNil) 697 c.Assert(iter.Valid(), IsFalse) 698 699 insertData(c, buffer) 700 checkNewIterator(c, buffer) 701 } 702 s.ResetMembuffers() 703 } 704 705 func (s *testKVSuite) TestIterNextUntil(c *C) { 706 defer testleak.AfterTest(c)() 707 buffer := newMemDB() 708 insertData(c, buffer) 709 710 iter, err := buffer.Iter(nil, nil) 711 c.Assert(err, IsNil) 712 713 err = NextUntil(iter, func(k Key) bool { 714 return false 715 }) 716 c.Assert(err, IsNil) 717 c.Assert(iter.Valid(), IsFalse) 718 } 719 720 func (s *testKVSuite) TestBasicNewIterator(c *C) { 721 defer testleak.AfterTest(c)() 722 for _, buffer := range s.bs { 723 it, err := buffer.Iter([]byte("2"), nil) 724 c.Assert(err, IsNil) 725 c.Assert(it.Valid(), IsFalse) 726 } 727 } 728 729 func (s *testKVSuite) TestNewIteratorMin(c *C) { 730 defer testleak.AfterTest(c)() 731 ekvs := []struct { 732 key string 733 value string 734 }{ 735 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001", "dagger-version"}, 736 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001_0002", "1"}, 737 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001_0003", "hello"}, 738 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002", "dagger-version"}, 739 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002_0002", "2"}, 740 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002_0003", "hello"}, 741 } 742 for _, buffer := range s.bs { 743 for _, ekv := range ekvs { 744 err := buffer.Set([]byte(ekv.key), []byte(ekv.value)) 745 c.Assert(err, IsNil) 746 } 747 748 cnt := 0 749 it, err := buffer.Iter(nil, nil) 750 c.Assert(err, IsNil) 751 for it.Valid() { 752 cnt++ 753 err := it.Next() 754 c.Assert(err, IsNil) 755 } 756 c.Assert(cnt, Equals, 6) 757 758 it, err = buffer.Iter([]byte("DATA_test_main_db_tbl_tbl_test_record__00000000000000000000"), nil) 759 c.Assert(err, IsNil) 760 c.Assert(string([]byte(it.Key())), Equals, "DATA_test_main_db_tbl_tbl_test_record__00000000000000000001") 761 } 762 s.ResetMembuffers() 763 } 764 765 func (s *testKVSuite) TestMemDBStaging(c *C) { 766 buffer := newMemDB() 767 err := buffer.Set([]byte("x"), make([]byte, 2)) 768 c.Assert(err, IsNil) 769 770 h1 := buffer.Staging() 771 err = buffer.Set([]byte("x"), make([]byte, 3)) 772 c.Assert(err, IsNil) 773 774 h2 := buffer.Staging() 775 err = buffer.Set([]byte("yz"), make([]byte, 1)) 776 c.Assert(err, IsNil) 777 778 v, _ := buffer.Get(context.Background(), []byte("x")) 779 c.Assert(len(v), Equals, 3) 780 781 buffer.Release(h2) 782 783 v, _ = buffer.Get(context.Background(), []byte("yz")) 784 c.Assert(len(v), Equals, 1) 785 786 buffer.Cleanup(h1) 787 788 v, _ = buffer.Get(context.Background(), []byte("x")) 789 c.Assert(len(v), Equals, 2) 790 } 791 792 func (s *testKVSuite) TestBufferLimit(c *C) { 793 buffer := newMemDB() 794 buffer.bufferSizeLimit = 1000 795 buffer.entrySizeLimit = 500 796 797 err := buffer.Set([]byte("x"), make([]byte, 500)) 798 c.Assert(err, NotNil) // entry size limit 799 800 err = buffer.Set([]byte("x"), make([]byte, 499)) 801 c.Assert(err, IsNil) 802 err = buffer.Set([]byte("yz"), make([]byte, 499)) 803 c.Assert(err, NotNil) // buffer size limit 804 805 err = buffer.Delete(make([]byte, 499)) 806 c.Assert(err, IsNil) 807 808 err = buffer.Delete(make([]byte, 500)) 809 c.Assert(err, NotNil) 810 } 811 812 func (s *testKVSuite) TestBufferBatchGetter(c *C) { 813 snap := &mockSnapshot{causetstore: newMemDB()} 814 ka := []byte("a") 815 kb := []byte("b") 816 kc := []byte("c") 817 kd := []byte("d") 818 snap.causetstore.Set(ka, ka) 819 snap.causetstore.Set(kb, kb) 820 snap.causetstore.Set(kc, kc) 821 snap.causetstore.Set(kd, kd) 822 823 // midbse value is the same as snap 824 midbse := newMemDB() 825 midbse.Set(ka, []byte("a1")) 826 midbse.Set(kc, []byte("c1")) 827 828 buffer := newMemDB() 829 buffer.Set(ka, []byte("a2")) 830 buffer.Delete(kb) 831 832 batchGetter := NewBufferBatchGetter(buffer, midbse, snap) 833 result, err := batchGetter.BatchGet(context.Background(), []Key{ka, kb, kc, kd}) 834 c.Assert(err, IsNil) 835 c.Assert(len(result), Equals, 3) 836 c.Assert(string(result[string(ka)]), Equals, "a2") 837 c.Assert(string(result[string(kc)]), Equals, "c1") 838 c.Assert(string(result[string(kd)]), Equals, "d") 839 }