github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/internal/arenaskl/skl_test.go (about) 1 /* 2 * Copyright 2017 Dgraph Labs, Inc. and Contributors 3 * Modifications copyright (C) 2017 Andy Kimball and Contributors 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 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package arenaskl 19 20 import ( 21 "bytes" 22 "encoding/binary" 23 "fmt" 24 "strconv" 25 "sync" 26 "sync/atomic" 27 "testing" 28 "time" 29 30 "github.com/cockroachdb/pebble/internal/base" 31 "github.com/stretchr/testify/require" 32 "golang.org/x/exp/rand" 33 ) 34 35 const arenaSize = 1 << 20 36 37 // iterAdapter adapts the new Iterator API which returns the key and value from 38 // positioning methods (Seek*, First, Last, Next, Prev) to the old API which 39 // returned a boolean corresponding to Valid. Only used by test code. 40 type iterAdapter struct { 41 *Iterator 42 key *base.InternalKey 43 val []byte 44 } 45 46 func newIterAdapter(iter *Iterator) *iterAdapter { 47 return &iterAdapter{ 48 Iterator: iter, 49 } 50 } 51 52 func (i *iterAdapter) update(key *base.InternalKey, val base.LazyValue) bool { 53 i.key = key 54 i.val = val.InPlaceValue() 55 return i.key != nil 56 } 57 58 func (i *iterAdapter) String() string { 59 return "iter-adapter" 60 } 61 62 func (i *iterAdapter) SeekGE(key []byte, flags base.SeekGEFlags) bool { 63 return i.update(i.Iterator.SeekGE(key, flags)) 64 } 65 66 func (i *iterAdapter) SeekPrefixGE(prefix, key []byte, flags base.SeekGEFlags) bool { 67 return i.update(i.Iterator.SeekPrefixGE(prefix, key, flags)) 68 } 69 70 func (i *iterAdapter) SeekLT(key []byte, flags base.SeekLTFlags) bool { 71 return i.update(i.Iterator.SeekLT(key, flags)) 72 } 73 74 func (i *iterAdapter) First() bool { 75 return i.update(i.Iterator.First()) 76 } 77 78 func (i *iterAdapter) Last() bool { 79 return i.update(i.Iterator.Last()) 80 } 81 82 func (i *iterAdapter) Next() bool { 83 return i.update(i.Iterator.Next()) 84 } 85 86 func (i *iterAdapter) Prev() bool { 87 return i.update(i.Iterator.Prev()) 88 } 89 90 func (i *iterAdapter) Key() base.InternalKey { 91 return *i.key 92 } 93 94 func (i *iterAdapter) Value() []byte { 95 return i.val 96 } 97 98 func (i *iterAdapter) Valid() bool { 99 return i.key != nil 100 } 101 102 func makeIntKey(i int) base.InternalKey { 103 return base.InternalKey{UserKey: []byte(fmt.Sprintf("%05d", i))} 104 } 105 106 func makeKey(s string) []byte { 107 return []byte(s) 108 } 109 110 func makeIkey(s string) base.InternalKey { 111 return base.InternalKey{UserKey: []byte(s)} 112 } 113 114 func makeValue(i int) []byte { 115 return []byte(fmt.Sprintf("v%05d", i)) 116 } 117 118 func makeInserterAdd(s *Skiplist) func(key base.InternalKey, value []byte) error { 119 ins := &Inserter{} 120 return func(key base.InternalKey, value []byte) error { 121 return ins.Add(s, key, value) 122 } 123 } 124 125 // length iterates over skiplist to give exact size. 126 func length(s *Skiplist) int { 127 count := 0 128 129 it := newIterAdapter(s.NewIter(nil, nil)) 130 for valid := it.First(); valid; valid = it.Next() { 131 count++ 132 } 133 134 return count 135 } 136 137 // length iterates over skiplist in reverse order to give exact size. 138 func lengthRev(s *Skiplist) int { 139 count := 0 140 141 it := newIterAdapter(s.NewIter(nil, nil)) 142 for valid := it.Last(); valid; valid = it.Prev() { 143 count++ 144 } 145 146 return count 147 } 148 149 func TestEmpty(t *testing.T) { 150 key := makeKey("aaa") 151 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 152 it := newIterAdapter(l.NewIter(nil, nil)) 153 154 require.False(t, it.Valid()) 155 156 it.First() 157 require.False(t, it.Valid()) 158 159 it.Last() 160 require.False(t, it.Valid()) 161 162 require.False(t, it.SeekGE(key, base.SeekGEFlagsNone)) 163 require.False(t, it.Valid()) 164 } 165 166 func TestFull(t *testing.T) { 167 l := NewSkiplist(newArena(1000), bytes.Compare) 168 169 foundArenaFull := false 170 for i := 0; i < 100; i++ { 171 err := l.Add(makeIntKey(i), makeValue(i)) 172 if err == ErrArenaFull { 173 foundArenaFull = true 174 break 175 } 176 } 177 178 require.True(t, foundArenaFull) 179 180 err := l.Add(makeIkey("someval"), nil) 181 require.Equal(t, ErrArenaFull, err) 182 } 183 184 // TestBasic tests single-threaded seeks and adds. 185 func TestBasic(t *testing.T) { 186 for _, inserter := range []bool{false, true} { 187 t.Run(fmt.Sprintf("inserter=%t", inserter), func(t *testing.T) { 188 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 189 it := newIterAdapter(l.NewIter(nil, nil)) 190 191 add := l.Add 192 if inserter { 193 add = makeInserterAdd(l) 194 } 195 196 // Try adding values. 197 add(makeIkey("key1"), makeValue(1)) 198 add(makeIkey("key3"), makeValue(3)) 199 add(makeIkey("key2"), makeValue(2)) 200 201 require.True(t, it.SeekGE(makeKey("key"), base.SeekGEFlagsNone)) 202 require.True(t, it.Valid()) 203 require.NotEqual(t, "key", it.Key().UserKey) 204 205 require.True(t, it.SeekGE(makeKey("key1"), base.SeekGEFlagsNone)) 206 require.EqualValues(t, "key1", it.Key().UserKey) 207 require.EqualValues(t, makeValue(1), it.Value()) 208 209 require.True(t, it.SeekGE(makeKey("key2"), base.SeekGEFlagsNone)) 210 require.EqualValues(t, "key2", it.Key().UserKey) 211 require.EqualValues(t, makeValue(2), it.Value()) 212 213 require.True(t, it.SeekGE(makeKey("key3"), base.SeekGEFlagsNone)) 214 require.EqualValues(t, "key3", it.Key().UserKey) 215 require.EqualValues(t, makeValue(3), it.Value()) 216 217 key := makeIkey("a") 218 key.SetSeqNum(1) 219 add(key, nil) 220 key.SetSeqNum(2) 221 add(key, nil) 222 223 require.True(t, it.SeekGE(makeKey("a"), base.SeekGEFlagsNone)) 224 require.True(t, it.Valid()) 225 require.EqualValues(t, "a", it.Key().UserKey) 226 require.EqualValues(t, 2, it.Key().SeqNum()) 227 228 require.True(t, it.Next()) 229 require.True(t, it.Valid()) 230 require.EqualValues(t, "a", it.Key().UserKey) 231 require.EqualValues(t, 1, it.Key().SeqNum()) 232 233 key = makeIkey("b") 234 key.SetSeqNum(2) 235 add(key, nil) 236 key.SetSeqNum(1) 237 add(key, nil) 238 239 require.True(t, it.SeekGE(makeKey("b"), base.SeekGEFlagsNone)) 240 require.True(t, it.Valid()) 241 require.EqualValues(t, "b", it.Key().UserKey) 242 require.EqualValues(t, 2, it.Key().SeqNum()) 243 244 require.True(t, it.Next()) 245 require.True(t, it.Valid()) 246 require.EqualValues(t, "b", it.Key().UserKey) 247 require.EqualValues(t, 1, it.Key().SeqNum()) 248 }) 249 } 250 } 251 252 // TestConcurrentBasic tests concurrent writes followed by concurrent reads. 253 func TestConcurrentBasic(t *testing.T) { 254 const n = 1000 255 256 for _, inserter := range []bool{false, true} { 257 t.Run(fmt.Sprintf("inserter=%t", inserter), func(t *testing.T) { 258 // Set testing flag to make it easier to trigger unusual race conditions. 259 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 260 l.testing = true 261 262 var wg sync.WaitGroup 263 for i := 0; i < n; i++ { 264 wg.Add(1) 265 go func(i int) { 266 defer wg.Done() 267 268 if inserter { 269 var ins Inserter 270 ins.Add(l, makeIntKey(i), makeValue(i)) 271 } else { 272 l.Add(makeIntKey(i), makeValue(i)) 273 } 274 }(i) 275 } 276 wg.Wait() 277 278 // Check values. Concurrent reads. 279 for i := 0; i < n; i++ { 280 wg.Add(1) 281 go func(i int) { 282 defer wg.Done() 283 284 it := newIterAdapter(l.NewIter(nil, nil)) 285 require.True(t, it.SeekGE(makeKey(fmt.Sprintf("%05d", i)), base.SeekGEFlagsNone)) 286 require.EqualValues(t, fmt.Sprintf("%05d", i), it.Key().UserKey) 287 }(i) 288 } 289 wg.Wait() 290 require.Equal(t, n, length(l)) 291 require.Equal(t, n, lengthRev(l)) 292 }) 293 } 294 } 295 296 // TestConcurrentOneKey will read while writing to one single key. 297 func TestConcurrentOneKey(t *testing.T) { 298 const n = 100 299 key := makeKey("thekey") 300 ikey := makeIkey("thekey") 301 302 for _, inserter := range []bool{false, true} { 303 t.Run(fmt.Sprintf("inserter=%t", inserter), func(t *testing.T) { 304 // Set testing flag to make it easier to trigger unusual race conditions. 305 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 306 l.testing = true 307 308 var wg sync.WaitGroup 309 writeDone := make(chan struct{}, 1) 310 for i := 0; i < n; i++ { 311 wg.Add(1) 312 go func(i int) { 313 defer func() { 314 wg.Done() 315 select { 316 case writeDone <- struct{}{}: 317 default: 318 } 319 }() 320 321 if inserter { 322 var ins Inserter 323 ins.Add(l, ikey, makeValue(i)) 324 } else { 325 l.Add(ikey, makeValue(i)) 326 } 327 }(i) 328 } 329 // Wait until at least some write made it such that reads return a value. 330 <-writeDone 331 var sawValue atomic.Int32 332 for i := 0; i < n; i++ { 333 wg.Add(1) 334 go func() { 335 defer wg.Done() 336 337 it := newIterAdapter(l.NewIter(nil, nil)) 338 it.SeekGE(key, base.SeekGEFlagsNone) 339 require.True(t, it.Valid()) 340 require.True(t, bytes.Equal(key, it.Key().UserKey)) 341 342 sawValue.Add(1) 343 v, err := strconv.Atoi(string(it.Value()[1:])) 344 require.NoError(t, err) 345 require.True(t, 0 <= v && v < n) 346 }() 347 } 348 wg.Wait() 349 require.Equal(t, int32(n), sawValue.Load()) 350 require.Equal(t, 1, length(l)) 351 require.Equal(t, 1, lengthRev(l)) 352 }) 353 } 354 } 355 356 func TestSkiplistAdd(t *testing.T) { 357 for _, inserter := range []bool{false, true} { 358 t.Run(fmt.Sprintf("inserter=%t", inserter), func(t *testing.T) { 359 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 360 it := newIterAdapter(l.NewIter(nil, nil)) 361 362 add := l.Add 363 if inserter { 364 add = makeInserterAdd(l) 365 } 366 367 // Add nil key and value (treated same as empty). 368 err := add(base.InternalKey{}, nil) 369 require.Nil(t, err) 370 require.True(t, it.SeekGE([]byte{}, base.SeekGEFlagsNone)) 371 require.EqualValues(t, []byte{}, it.Key().UserKey) 372 require.EqualValues(t, []byte{}, it.Value()) 373 374 l = NewSkiplist(newArena(arenaSize), bytes.Compare) 375 it = newIterAdapter(l.NewIter(nil, nil)) 376 377 add = l.Add 378 if inserter { 379 add = makeInserterAdd(l) 380 } 381 382 // Add empty key and value (treated same as nil). 383 err = add(makeIkey(""), []byte{}) 384 require.Nil(t, err) 385 require.True(t, it.SeekGE([]byte{}, base.SeekGEFlagsNone)) 386 require.EqualValues(t, []byte{}, it.Key().UserKey) 387 require.EqualValues(t, []byte{}, it.Value()) 388 389 // Add to empty list. 390 err = add(makeIntKey(2), makeValue(2)) 391 require.Nil(t, err) 392 require.True(t, it.SeekGE(makeKey("00002"), base.SeekGEFlagsNone)) 393 require.EqualValues(t, "00002", it.Key().UserKey) 394 require.EqualValues(t, makeValue(2), it.Value()) 395 396 // Add first element in non-empty list. 397 err = add(makeIntKey(1), makeValue(1)) 398 require.Nil(t, err) 399 require.True(t, it.SeekGE(makeKey("00001"), base.SeekGEFlagsNone)) 400 require.EqualValues(t, "00001", it.Key().UserKey) 401 require.EqualValues(t, makeValue(1), it.Value()) 402 403 // Add last element in non-empty list. 404 err = add(makeIntKey(4), makeValue(4)) 405 require.Nil(t, err) 406 require.True(t, it.SeekGE(makeKey("00004"), base.SeekGEFlagsNone)) 407 require.EqualValues(t, "00004", it.Key().UserKey) 408 require.EqualValues(t, makeValue(4), it.Value()) 409 410 // Add element in middle of list. 411 err = add(makeIntKey(3), makeValue(3)) 412 require.Nil(t, err) 413 require.True(t, it.SeekGE(makeKey("00003"), base.SeekGEFlagsNone)) 414 require.EqualValues(t, "00003", it.Key().UserKey) 415 require.EqualValues(t, makeValue(3), it.Value()) 416 417 // Try to add element that already exists. 418 err = add(makeIntKey(2), nil) 419 require.Equal(t, ErrRecordExists, err) 420 require.EqualValues(t, "00003", it.Key().UserKey) 421 require.EqualValues(t, makeValue(3), it.Value()) 422 423 require.Equal(t, 5, length(l)) 424 require.Equal(t, 5, lengthRev(l)) 425 }) 426 } 427 } 428 429 // TestConcurrentAdd races between adding same nodes. 430 func TestConcurrentAdd(t *testing.T) { 431 for _, inserter := range []bool{false, true} { 432 t.Run(fmt.Sprintf("inserter=%t", inserter), func(t *testing.T) { 433 const n = 100 434 435 // Set testing flag to make it easier to trigger unusual race conditions. 436 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 437 l.testing = true 438 439 start := make([]sync.WaitGroup, n) 440 end := make([]sync.WaitGroup, n) 441 442 for i := 0; i < n; i++ { 443 start[i].Add(1) 444 end[i].Add(2) 445 } 446 447 for f := 0; f < 2; f++ { 448 go func(f int) { 449 it := newIterAdapter(l.NewIter(nil, nil)) 450 add := l.Add 451 if inserter { 452 add = makeInserterAdd(l) 453 } 454 455 for i := 0; i < n; i++ { 456 start[i].Wait() 457 458 key := makeIntKey(i) 459 if add(key, nil) == nil { 460 require.True(t, it.SeekGE(key.UserKey, base.SeekGEFlagsNone)) 461 require.EqualValues(t, key, it.Key()) 462 } 463 464 end[i].Done() 465 } 466 }(f) 467 } 468 469 for i := 0; i < n; i++ { 470 start[i].Done() 471 end[i].Wait() 472 } 473 474 require.Equal(t, n, length(l)) 475 require.Equal(t, n, lengthRev(l)) 476 }) 477 } 478 } 479 480 // TestIteratorNext tests a basic iteration over all nodes from the beginning. 481 func TestIteratorNext(t *testing.T) { 482 const n = 100 483 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 484 it := newIterAdapter(l.NewIter(nil, nil)) 485 486 require.False(t, it.Valid()) 487 488 it.First() 489 require.False(t, it.Valid()) 490 491 for i := n - 1; i >= 0; i-- { 492 l.Add(makeIntKey(i), makeValue(i)) 493 } 494 495 it.First() 496 for i := 0; i < n; i++ { 497 require.True(t, it.Valid()) 498 require.EqualValues(t, makeIntKey(i), it.Key()) 499 require.EqualValues(t, makeValue(i), it.Value()) 500 it.Next() 501 } 502 require.False(t, it.Valid()) 503 } 504 505 // TestIteratorPrev tests a basic iteration over all nodes from the end. 506 func TestIteratorPrev(t *testing.T) { 507 const n = 100 508 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 509 it := newIterAdapter(l.NewIter(nil, nil)) 510 511 require.False(t, it.Valid()) 512 513 it.Last() 514 require.False(t, it.Valid()) 515 516 var ins Inserter 517 for i := 0; i < n; i++ { 518 ins.Add(l, makeIntKey(i), makeValue(i)) 519 } 520 521 it.Last() 522 for i := n - 1; i >= 0; i-- { 523 require.True(t, it.Valid()) 524 require.EqualValues(t, makeIntKey(i), it.Key()) 525 require.EqualValues(t, makeValue(i), it.Value()) 526 it.Prev() 527 } 528 require.False(t, it.Valid()) 529 } 530 531 func TestIteratorSeekGEAndSeekPrefixGE(t *testing.T) { 532 const n = 100 533 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 534 it := newIterAdapter(l.NewIter(nil, nil)) 535 536 require.False(t, it.Valid()) 537 it.First() 538 require.False(t, it.Valid()) 539 // 1000, 1010, 1020, ..., 1990. 540 541 var ins Inserter 542 for i := n - 1; i >= 0; i-- { 543 v := i*10 + 1000 544 ins.Add(l, makeIntKey(v), makeValue(v)) 545 } 546 547 require.True(t, it.SeekGE(makeKey(""), base.SeekGEFlagsNone)) 548 require.True(t, it.Valid()) 549 require.EqualValues(t, "01000", it.Key().UserKey) 550 require.EqualValues(t, "v01000", it.Value()) 551 552 require.True(t, it.SeekGE(makeKey("01000"), base.SeekGEFlagsNone)) 553 require.True(t, it.Valid()) 554 require.EqualValues(t, "01000", it.Key().UserKey) 555 require.EqualValues(t, "v01000", it.Value()) 556 557 require.True(t, it.SeekGE(makeKey("01005"), base.SeekGEFlagsNone)) 558 require.True(t, it.Valid()) 559 require.EqualValues(t, "01010", it.Key().UserKey) 560 require.EqualValues(t, "v01010", it.Value()) 561 562 require.True(t, it.SeekGE(makeKey("01010"), base.SeekGEFlagsNone)) 563 require.True(t, it.Valid()) 564 require.EqualValues(t, "01010", it.Key().UserKey) 565 require.EqualValues(t, "v01010", it.Value()) 566 567 require.False(t, it.SeekGE(makeKey("99999"), base.SeekGEFlagsNone)) 568 require.False(t, it.Valid()) 569 570 // Test SeekGE with trySeekUsingNext optimization. 571 { 572 require.True(t, it.SeekGE(makeKey("01000"), base.SeekGEFlagsNone)) 573 require.True(t, it.Valid()) 574 require.EqualValues(t, "01000", it.Key().UserKey) 575 require.EqualValues(t, "v01000", it.Value()) 576 577 // Seeking to the same key. 578 require.True(t, it.SeekGE(makeKey("01000"), base.SeekGEFlagsNone.EnableTrySeekUsingNext())) 579 require.True(t, it.Valid()) 580 require.EqualValues(t, "01000", it.Key().UserKey) 581 require.EqualValues(t, "v01000", it.Value()) 582 583 // Seeking to a nearby key that can be reached using Next. 584 require.True(t, it.SeekGE(makeKey("01020"), base.SeekGEFlagsNone.EnableTrySeekUsingNext())) 585 require.True(t, it.Valid()) 586 require.EqualValues(t, "01020", it.Key().UserKey) 587 require.EqualValues(t, "v01020", it.Value()) 588 589 // Seeking to a key that cannot be reached using Next. 590 require.True(t, it.SeekGE(makeKey("01200"), base.SeekGEFlagsNone.EnableTrySeekUsingNext())) 591 require.True(t, it.Valid()) 592 require.EqualValues(t, "01200", it.Key().UserKey) 593 require.EqualValues(t, "v01200", it.Value()) 594 595 // Seeking to an earlier key, but the caller lies. Incorrect result. 596 require.True(t, it.SeekGE(makeKey("01100"), base.SeekGEFlagsNone.EnableTrySeekUsingNext())) 597 require.True(t, it.Valid()) 598 require.EqualValues(t, "01200", it.Key().UserKey) 599 require.EqualValues(t, "v01200", it.Value()) 600 601 // Telling the truth works. 602 require.True(t, it.SeekGE(makeKey("01100"), base.SeekGEFlagsNone)) 603 require.True(t, it.Valid()) 604 require.EqualValues(t, "01100", it.Key().UserKey) 605 require.EqualValues(t, "v01100", it.Value()) 606 } 607 608 // Test SeekPrefixGE with trySeekUsingNext optimization. 609 { 610 require.True(t, it.SeekPrefixGE(makeKey("01000"), makeKey("01000"), base.SeekGEFlagsNone)) 611 require.True(t, it.Valid()) 612 require.EqualValues(t, "01000", it.Key().UserKey) 613 require.EqualValues(t, "v01000", it.Value()) 614 615 // Seeking to the same key. 616 require.True(t, it.SeekPrefixGE(makeKey("01000"), makeKey("01000"), base.SeekGEFlagsNone.EnableTrySeekUsingNext())) 617 require.True(t, it.Valid()) 618 require.EqualValues(t, "01000", it.Key().UserKey) 619 require.EqualValues(t, "v01000", it.Value()) 620 621 // Seeking to a nearby key that can be reached using Next. 622 require.True(t, it.SeekPrefixGE(makeKey("01020"), makeKey("01020"), base.SeekGEFlagsNone.EnableTrySeekUsingNext())) 623 require.True(t, it.Valid()) 624 require.EqualValues(t, "01020", it.Key().UserKey) 625 require.EqualValues(t, "v01020", it.Value()) 626 627 // Seeking to a key that cannot be reached using Next. 628 require.True(t, it.SeekPrefixGE(makeKey("01200"), makeKey("01200"), base.SeekGEFlagsNone.EnableTrySeekUsingNext())) 629 require.True(t, it.Valid()) 630 require.EqualValues(t, "01200", it.Key().UserKey) 631 require.EqualValues(t, "v01200", it.Value()) 632 633 // Seeking to an earlier key, but the caller lies. Incorrect result. 634 require.True(t, it.SeekPrefixGE(makeKey("01100"), makeKey("01100"), base.SeekGEFlagsNone.EnableTrySeekUsingNext())) 635 require.True(t, it.Valid()) 636 require.EqualValues(t, "01200", it.Key().UserKey) 637 require.EqualValues(t, "v01200", it.Value()) 638 639 // Telling the truth works. 640 require.True(t, it.SeekPrefixGE(makeKey("01100"), makeKey("01100"), base.SeekGEFlagsNone)) 641 require.True(t, it.Valid()) 642 require.EqualValues(t, "01100", it.Key().UserKey) 643 require.EqualValues(t, "v01100", it.Value()) 644 } 645 646 // Test seek for empty key. 647 ins.Add(l, base.InternalKey{}, nil) 648 require.True(t, it.SeekGE([]byte{}, base.SeekGEFlagsNone)) 649 require.True(t, it.Valid()) 650 require.EqualValues(t, "", it.Key().UserKey) 651 652 require.True(t, it.SeekGE(makeKey(""), base.SeekGEFlagsNone)) 653 require.True(t, it.Valid()) 654 require.EqualValues(t, "", it.Key().UserKey) 655 } 656 657 func TestIteratorSeekLT(t *testing.T) { 658 const n = 100 659 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 660 it := newIterAdapter(l.NewIter(nil, nil)) 661 662 require.False(t, it.Valid()) 663 it.First() 664 require.False(t, it.Valid()) 665 // 1000, 1010, 1020, ..., 1990. 666 var ins Inserter 667 for i := n - 1; i >= 0; i-- { 668 v := i*10 + 1000 669 ins.Add(l, makeIntKey(v), makeValue(v)) 670 } 671 672 require.False(t, it.SeekLT(makeKey(""), base.SeekLTFlagsNone)) 673 require.False(t, it.Valid()) 674 675 require.False(t, it.SeekLT(makeKey("01000"), base.SeekLTFlagsNone)) 676 require.False(t, it.Valid()) 677 678 require.True(t, it.SeekLT(makeKey("01001"), base.SeekLTFlagsNone)) 679 require.True(t, it.Valid()) 680 require.EqualValues(t, "01000", it.Key().UserKey) 681 require.EqualValues(t, "v01000", it.Value()) 682 683 require.True(t, it.SeekLT(makeKey("01005"), base.SeekLTFlagsNone)) 684 require.True(t, it.Valid()) 685 require.EqualValues(t, "01000", it.Key().UserKey) 686 require.EqualValues(t, "v01000", it.Value()) 687 688 require.True(t, it.SeekLT(makeKey("01991"), base.SeekLTFlagsNone)) 689 require.True(t, it.Valid()) 690 require.EqualValues(t, "01990", it.Key().UserKey) 691 require.EqualValues(t, "v01990", it.Value()) 692 693 require.True(t, it.SeekLT(makeKey("99999"), base.SeekLTFlagsNone)) 694 require.True(t, it.Valid()) 695 require.EqualValues(t, "01990", it.Key().UserKey) 696 require.EqualValues(t, "v01990", it.Value()) 697 698 // Test seek for empty key. 699 ins.Add(l, base.InternalKey{}, nil) 700 require.False(t, it.SeekLT([]byte{}, base.SeekLTFlagsNone)) 701 require.False(t, it.Valid()) 702 703 require.True(t, it.SeekLT(makeKey("\x01"), base.SeekLTFlagsNone)) 704 require.True(t, it.Valid()) 705 require.EqualValues(t, "", it.Key().UserKey) 706 } 707 708 // TODO(peter): test First and Last. 709 func TestIteratorBounds(t *testing.T) { 710 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 711 for i := 1; i < 10; i++ { 712 require.NoError(t, l.Add(makeIntKey(i), makeValue(i))) 713 } 714 715 key := func(i int) []byte { 716 return makeIntKey(i).UserKey 717 } 718 719 it := newIterAdapter(l.NewIter(key(3), key(7))) 720 721 // SeekGE within the lower and upper bound succeeds. 722 for i := 3; i <= 6; i++ { 723 k := key(i) 724 require.True(t, it.SeekGE(k, base.SeekGEFlagsNone)) 725 require.EqualValues(t, string(k), string(it.Key().UserKey)) 726 } 727 728 // SeekGE before the lower bound still succeeds (only the upper bound is 729 // checked). 730 for i := 1; i < 3; i++ { 731 k := key(i) 732 require.True(t, it.SeekGE(k, base.SeekGEFlagsNone)) 733 require.EqualValues(t, string(k), string(it.Key().UserKey)) 734 } 735 736 // SeekGE beyond the upper bound fails. 737 for i := 7; i < 10; i++ { 738 require.False(t, it.SeekGE(key(i), base.SeekGEFlagsNone)) 739 } 740 741 require.True(t, it.SeekGE(key(6), base.SeekGEFlagsNone)) 742 require.EqualValues(t, "00006", it.Key().UserKey) 743 require.EqualValues(t, "v00006", it.Value()) 744 745 // Next into the upper bound fails. 746 require.False(t, it.Next()) 747 748 // SeekLT within the lower and upper bound succeeds. 749 for i := 4; i <= 7; i++ { 750 require.True(t, it.SeekLT(key(i), base.SeekLTFlagsNone)) 751 require.EqualValues(t, string(key(i-1)), string(it.Key().UserKey)) 752 } 753 754 // SeekLT beyond the upper bound still succeeds (only the lower bound is 755 // checked). 756 for i := 8; i < 9; i++ { 757 require.True(t, it.SeekLT(key(8), base.SeekLTFlagsNone)) 758 require.EqualValues(t, string(key(i-1)), string(it.Key().UserKey)) 759 } 760 761 // SeekLT before the lower bound fails. 762 for i := 1; i < 4; i++ { 763 require.False(t, it.SeekLT(key(i), base.SeekLTFlagsNone)) 764 } 765 766 require.True(t, it.SeekLT(key(4), base.SeekLTFlagsNone)) 767 require.EqualValues(t, "00003", it.Key().UserKey) 768 require.EqualValues(t, "v00003", it.Value()) 769 770 // Prev into the lower bound fails. 771 require.False(t, it.Prev()) 772 } 773 774 func TestBytesIterated(t *testing.T) { 775 l := NewSkiplist(newArena(arenaSize), bytes.Compare) 776 emptySize := l.arena.Size() 777 for i := 0; i < 200; i++ { 778 bytesIterated := l.bytesIterated(t) 779 expected := uint64(l.arena.Size() - emptySize) 780 if bytesIterated != expected { 781 t.Fatalf("bytesIterated: got %d, want %d", bytesIterated, expected) 782 } 783 l.Add(base.InternalKey{UserKey: []byte{byte(i)}}, nil) 784 } 785 } 786 787 // bytesIterated returns the number of bytes iterated in the skiplist. 788 func (s *Skiplist) bytesIterated(t *testing.T) (bytesIterated uint64) { 789 x := s.NewFlushIter(&bytesIterated) 790 var prevIterated uint64 791 for key, _ := x.First(); key != nil; key, _ = x.Next() { 792 if bytesIterated < prevIterated { 793 t.Fatalf("bytesIterated moved backward: %d < %d", bytesIterated, prevIterated) 794 } 795 prevIterated = bytesIterated 796 } 797 if x.Close() != nil { 798 return 0 799 } 800 return bytesIterated 801 } 802 803 func randomKey(rng *rand.Rand, b []byte) base.InternalKey { 804 key := rng.Uint32() 805 key2 := rng.Uint32() 806 binary.LittleEndian.PutUint32(b, key) 807 binary.LittleEndian.PutUint32(b[4:], key2) 808 return base.InternalKey{UserKey: b} 809 } 810 811 // Standard test. Some fraction is read. Some fraction is write. Writes have 812 // to go through mutex lock. 813 func BenchmarkReadWrite(b *testing.B) { 814 for i := 0; i <= 10; i++ { 815 readFrac := float32(i) / 10.0 816 b.Run(fmt.Sprintf("frac_%d", i*10), func(b *testing.B) { 817 l := NewSkiplist(newArena(uint32((b.N+2)*maxNodeSize)), bytes.Compare) 818 b.ResetTimer() 819 var count int 820 b.RunParallel(func(pb *testing.PB) { 821 it := l.NewIter(nil, nil) 822 rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano()))) 823 buf := make([]byte, 8) 824 825 for pb.Next() { 826 if rng.Float32() < readFrac { 827 key, _ := it.SeekGE(randomKey(rng, buf).UserKey, base.SeekGEFlagsNone) 828 if key != nil { 829 _ = key 830 count++ 831 } 832 } else { 833 _ = l.Add(randomKey(rng, buf), nil) 834 } 835 } 836 }) 837 }) 838 } 839 } 840 841 func BenchmarkOrderedWrite(b *testing.B) { 842 l := NewSkiplist(newArena(8<<20), bytes.Compare) 843 var ins Inserter 844 buf := make([]byte, 8) 845 846 b.ResetTimer() 847 for i := 0; i < b.N; i++ { 848 binary.BigEndian.PutUint64(buf, uint64(i)) 849 if err := ins.Add(l, base.InternalKey{UserKey: buf}, nil); err == ErrArenaFull { 850 b.StopTimer() 851 l = NewSkiplist(newArena(uint32((b.N+2)*maxNodeSize)), bytes.Compare) 852 ins = Inserter{} 853 b.StartTimer() 854 } 855 } 856 } 857 858 func BenchmarkIterNext(b *testing.B) { 859 l := NewSkiplist(newArena(64<<10), bytes.Compare) 860 rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano()))) 861 buf := make([]byte, 8) 862 for { 863 if err := l.Add(randomKey(rng, buf), nil); err == ErrArenaFull { 864 break 865 } 866 } 867 868 it := l.NewIter(nil, nil) 869 b.ResetTimer() 870 for i := 0; i < b.N; i++ { 871 key, _ := it.Next() 872 if key == nil { 873 key, _ = it.First() 874 } 875 _ = key 876 } 877 } 878 879 func BenchmarkIterPrev(b *testing.B) { 880 l := NewSkiplist(newArena(64<<10), bytes.Compare) 881 rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano()))) 882 buf := make([]byte, 8) 883 for { 884 if err := l.Add(randomKey(rng, buf), nil); err == ErrArenaFull { 885 break 886 } 887 } 888 889 it := l.NewIter(nil, nil) 890 _, _ = it.Last() 891 b.ResetTimer() 892 for i := 0; i < b.N; i++ { 893 key, _ := it.Prev() 894 if key == nil { 895 key, _ = it.Last() 896 } 897 _ = key 898 } 899 } 900 901 // BenchmarkSeekPrefixGE looks at the performance of repeated calls to 902 // SeekPrefixGE, with different skip distances and different settings of 903 // trySeekUsingNext. 904 func BenchmarkSeekPrefixGE(b *testing.B) { 905 l := NewSkiplist(newArena(64<<10), bytes.Compare) 906 var count int 907 // count was measured to be 1279. 908 for count = 0; ; count++ { 909 if err := l.Add(makeIntKey(count), makeValue(count)); err == ErrArenaFull { 910 break 911 } 912 } 913 for _, skip := range []int{1, 2, 4, 8, 16} { 914 for _, useNext := range []bool{false, true} { 915 b.Run(fmt.Sprintf("skip=%d/use-next=%t", skip, useNext), func(b *testing.B) { 916 it := l.NewIter(nil, nil) 917 j := 0 918 var k []byte 919 makeKey := func() { 920 k = []byte(fmt.Sprintf("%05d", j)) 921 } 922 makeKey() 923 it.SeekPrefixGE(k, k, base.SeekGEFlagsNone) 924 b.ResetTimer() 925 for i := 0; i < b.N; i++ { 926 j += skip 927 var flags base.SeekGEFlags 928 if useNext { 929 flags = flags.EnableTrySeekUsingNext() 930 } 931 if j >= count { 932 j = 0 933 flags = flags.DisableTrySeekUsingNext() 934 } 935 makeKey() 936 it.SeekPrefixGE(k, k, flags) 937 } 938 }) 939 } 940 } 941 } 942 943 // Standard test. Some fraction is read. Some fraction is write. Writes have 944 // to go through mutex lock. 945 // func BenchmarkReadWriteMap(b *testing.B) { 946 // for i := 0; i <= 10; i++ { 947 // readFrac := float32(i) / 10.0 948 // b.Run(fmt.Sprintf("frac_%d", i*10), func(b *testing.B) { 949 // m := make(map[string]struct{}) 950 // var mutex sync.RWMutex 951 // b.ResetTimer() 952 // var count int 953 // b.RunParallel(func(pb *testing.PB) { 954 // rng := rand.New(rand.NewSource(time.Now().UnixNano())) 955 // for pb.Next() { 956 // if rng.Float32() < readFrac { 957 // mutex.RLock() 958 // _, ok := m[string(randomKey(rng))] 959 // mutex.RUnlock() 960 // if ok { 961 // count++ 962 // } 963 // } else { 964 // mutex.Lock() 965 // m[string(randomKey(rng))] = struct{}{} 966 // mutex.Unlock() 967 // } 968 // } 969 // }) 970 // }) 971 // } 972 // }