github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/internal/batchskl/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 batchskl 19 20 import ( 21 "bytes" 22 "encoding/binary" 23 "fmt" 24 "testing" 25 "time" 26 27 "github.com/petermattis/pebble/internal/base" 28 "github.com/stretchr/testify/require" 29 "golang.org/x/exp/rand" 30 ) 31 32 // iterAdapter adapts the new Iterator API which returns the key and value from 33 // positioning methods (Seek*, First, Last, Next, Prev) to the old API which 34 // returned a boolean corresponding to Valid. Only used by test code. 35 type iterAdapter struct { 36 Iterator 37 } 38 39 func (i *iterAdapter) verify(key *base.InternalKey) bool { 40 valid := key != nil 41 if valid != i.Valid() { 42 panic(fmt.Sprintf("inconsistent valid: %t != %t", valid, i.Valid())) 43 } 44 if valid { 45 if base.InternalCompare(bytes.Compare, *key, i.Key()) != 0 { 46 panic(fmt.Sprintf("inconsistent key: %s != %s", *key, i.Key())) 47 } 48 } 49 return valid 50 } 51 52 func (i *iterAdapter) SeekGE(key []byte) bool { 53 return i.verify(i.Iterator.SeekGE(key)) 54 } 55 56 func (i *iterAdapter) SeekLT(key []byte) bool { 57 return i.verify(i.Iterator.SeekLT(key)) 58 } 59 60 func (i *iterAdapter) First() bool { 61 return i.verify(i.Iterator.First()) 62 } 63 64 func (i *iterAdapter) Last() bool { 65 return i.verify(i.Iterator.Last()) 66 } 67 68 func (i *iterAdapter) Next() bool { 69 return i.verify(i.Iterator.Next()) 70 } 71 72 func (i *iterAdapter) Prev() bool { 73 return i.verify(i.Iterator.Prev()) 74 } 75 76 func (i *iterAdapter) Key() base.InternalKey { 77 return *i.Iterator.Key() 78 } 79 80 // length iterates over skiplist to give exact size. 81 func length(s *Skiplist) int { 82 count := 0 83 84 it := iterAdapter{s.NewIter(nil, nil)} 85 for valid := it.First(); valid; valid = it.Next() { 86 count++ 87 } 88 89 return count 90 } 91 92 // length iterates over skiplist in reverse order to give exact size. 93 func lengthRev(s *Skiplist) int { 94 count := 0 95 96 it := iterAdapter{s.NewIter(nil, nil)} 97 for valid := it.Last(); valid; valid = it.Prev() { 98 count++ 99 } 100 101 return count 102 } 103 104 func makeKey(s string) []byte { 105 return []byte(s) 106 } 107 108 type testStorage struct { 109 keys [][]byte 110 } 111 112 func (d *testStorage) add(key string) uint32 { 113 offset := uint32(len(d.keys)) 114 d.keys = append(d.keys, []byte(key)) 115 return offset 116 } 117 118 func (d *testStorage) Get(offset uint32) base.InternalKey { 119 return base.InternalKey{UserKey: d.keys[offset]} 120 } 121 122 func (d *testStorage) AbbreviatedKey(key []byte) uint64 { 123 return base.DefaultComparer.AbbreviatedKey(key) 124 } 125 126 func (d *testStorage) Compare(a []byte, b uint32) int { 127 return bytes.Compare(a, d.keys[b]) 128 } 129 130 func TestEmpty(t *testing.T) { 131 key := makeKey("aaa") 132 l := NewSkiplist(&testStorage{}, 0) 133 it := iterAdapter{l.NewIter(nil, nil)} 134 135 require.False(t, it.Valid()) 136 137 it.First() 138 require.False(t, it.Valid()) 139 140 it.Last() 141 require.False(t, it.Valid()) 142 143 require.False(t, it.SeekGE(key)) 144 require.False(t, it.Valid()) 145 } 146 147 // TestBasic tests seeks and adds. 148 func TestBasic(t *testing.T) { 149 d := &testStorage{} 150 l := NewSkiplist(d, 0) 151 it := iterAdapter{l.NewIter(nil, nil)} 152 153 // Try adding values. 154 require.Nil(t, l.Add(d.add("key1"))) 155 require.Nil(t, l.Add(d.add("key2"))) 156 require.Nil(t, l.Add(d.add("key3"))) 157 158 require.True(t, it.SeekGE(makeKey("key"))) 159 require.EqualValues(t, "key1", it.Key().UserKey) 160 161 require.True(t, it.SeekGE(makeKey("key1"))) 162 require.EqualValues(t, "key1", it.Key().UserKey) 163 164 require.True(t, it.SeekGE(makeKey("key2"))) 165 require.EqualValues(t, "key2", it.Key().UserKey) 166 167 require.True(t, it.SeekGE(makeKey("key3"))) 168 require.EqualValues(t, "key3", it.Key().UserKey) 169 170 require.True(t, it.SeekGE(makeKey("key2"))) 171 require.True(t, it.SeekGE(makeKey("key3"))) 172 } 173 174 func TestSkiplistAdd(t *testing.T) { 175 d := &testStorage{} 176 l := NewSkiplist(d, 0) 177 it := iterAdapter{l.NewIter(nil, nil)} 178 179 // Add empty key. 180 require.Nil(t, l.Add(d.add(""))) 181 require.EqualValues(t, []byte(nil), it.Key().UserKey) 182 require.True(t, it.First()) 183 require.EqualValues(t, []byte{}, it.Key().UserKey) 184 185 // Add to empty list. 186 require.Nil(t, l.Add(d.add("00002"))) 187 require.True(t, it.SeekGE(makeKey("00002"))) 188 require.EqualValues(t, "00002", it.Key().UserKey) 189 190 // Add first element in non-empty list. 191 require.Nil(t, l.Add(d.add("00001"))) 192 require.True(t, it.SeekGE(makeKey("00001"))) 193 require.EqualValues(t, "00001", it.Key().UserKey) 194 195 // Add last element in non-empty list. 196 require.Nil(t, l.Add(d.add("00004"))) 197 require.True(t, it.SeekGE(makeKey("00004"))) 198 require.EqualValues(t, "00004", it.Key().UserKey) 199 200 // Add element in middle of list. 201 require.Nil(t, l.Add(d.add("00003"))) 202 require.True(t, it.SeekGE(makeKey("00003"))) 203 require.EqualValues(t, "00003", it.Key().UserKey) 204 205 // Try to add element that already exists. 206 require.Equal(t, ErrExists, l.Add(d.add("00002"))) 207 require.Equal(t, 5, length(l)) 208 require.Equal(t, 5, lengthRev(l)) 209 } 210 211 // TestIteratorNext tests a basic iteration over all nodes from the beginning. 212 func TestIteratorNext(t *testing.T) { 213 const n = 100 214 d := &testStorage{} 215 l := NewSkiplist(d, 0) 216 it := iterAdapter{l.NewIter(nil, nil)} 217 218 require.False(t, it.Valid()) 219 220 it.First() 221 require.False(t, it.Valid()) 222 223 for i := n - 1; i >= 0; i-- { 224 require.Nil(t, l.Add(d.add(fmt.Sprintf("%05d", i)))) 225 } 226 227 it.First() 228 for i := 0; i < n; i++ { 229 require.True(t, it.Valid()) 230 require.EqualValues(t, fmt.Sprintf("%05d", i), it.Key().UserKey) 231 it.Next() 232 } 233 require.False(t, it.Valid()) 234 } 235 236 // // TestIteratorPrev tests a basic iteration over all nodes from the end. 237 func TestIteratorPrev(t *testing.T) { 238 const n = 100 239 d := &testStorage{} 240 l := NewSkiplist(d, 0) 241 it := iterAdapter{l.NewIter(nil, nil)} 242 243 require.False(t, it.Valid()) 244 245 it.Last() 246 require.False(t, it.Valid()) 247 248 for i := 0; i < n; i++ { 249 l.Add(d.add(fmt.Sprintf("%05d", i))) 250 } 251 252 it.Last() 253 for i := n - 1; i >= 0; i-- { 254 require.True(t, it.Valid()) 255 require.EqualValues(t, fmt.Sprintf("%05d", i), string(it.Key().UserKey)) 256 it.Prev() 257 } 258 require.False(t, it.Valid()) 259 } 260 261 func TestIteratorSeekGE(t *testing.T) { 262 const n = 1000 263 d := &testStorage{} 264 l := NewSkiplist(d, 0) 265 it := iterAdapter{l.NewIter(nil, nil)} 266 267 require.False(t, it.Valid()) 268 it.First() 269 require.False(t, it.Valid()) 270 // 1000, 1010, 1020, ..., 1990. 271 for i := n - 1; i >= 0; i-- { 272 require.Nil(t, l.Add(d.add(fmt.Sprintf("%05d", i*10+1000)))) 273 } 274 275 require.True(t, it.SeekGE(makeKey(""))) 276 require.True(t, it.Valid()) 277 require.EqualValues(t, "01000", it.Key().UserKey) 278 279 require.True(t, it.SeekGE(makeKey("01000"))) 280 require.True(t, it.Valid()) 281 require.EqualValues(t, "01000", it.Key().UserKey) 282 283 require.True(t, it.SeekGE(makeKey("01005"))) 284 require.True(t, it.Valid()) 285 require.EqualValues(t, "01010", it.Key().UserKey) 286 287 require.True(t, it.SeekGE(makeKey("01010"))) 288 require.True(t, it.Valid()) 289 require.EqualValues(t, "01010", it.Key().UserKey) 290 291 require.False(t, it.SeekGE(makeKey("99999"))) 292 require.False(t, it.Valid()) 293 294 // Test seek for empty key. 295 require.Nil(t, l.Add(d.add(""))) 296 require.True(t, it.SeekGE([]byte{})) 297 require.True(t, it.Valid()) 298 299 require.True(t, it.SeekGE(makeKey(""))) 300 require.True(t, it.Valid()) 301 } 302 303 func TestIteratorSeekLT(t *testing.T) { 304 const n = 100 305 d := &testStorage{} 306 l := NewSkiplist(d, 0) 307 it := iterAdapter{l.NewIter(nil, nil)} 308 309 require.False(t, it.Valid()) 310 it.First() 311 require.False(t, it.Valid()) 312 // 1000, 1010, 1020, ..., 1990. 313 for i := n - 1; i >= 0; i-- { 314 require.Nil(t, l.Add(d.add(fmt.Sprintf("%05d", i*10+1000)))) 315 } 316 317 require.False(t, it.SeekLT(makeKey(""))) 318 require.False(t, it.Valid()) 319 320 require.False(t, it.SeekLT(makeKey("01000"))) 321 require.False(t, it.Valid()) 322 323 require.True(t, it.SeekLT(makeKey("01001"))) 324 require.EqualValues(t, "01000", it.Key().UserKey) 325 require.True(t, it.Valid()) 326 327 require.True(t, it.SeekLT(makeKey("01005"))) 328 require.EqualValues(t, "01000", it.Key().UserKey) 329 require.True(t, it.Valid()) 330 331 require.True(t, it.SeekLT(makeKey("01991"))) 332 require.EqualValues(t, "01990", it.Key().UserKey) 333 require.True(t, it.Valid()) 334 335 require.True(t, it.SeekLT(makeKey("99999"))) 336 require.True(t, it.Valid()) 337 require.EqualValues(t, "01990", it.Key().UserKey) 338 339 // Test seek for empty key. 340 require.Nil(t, l.Add(d.add(""))) 341 require.False(t, it.SeekLT([]byte{})) 342 require.False(t, it.Valid()) 343 require.True(t, it.SeekLT(makeKey("\x01"))) 344 require.True(t, it.Valid()) 345 require.EqualValues(t, "", it.Key().UserKey) 346 } 347 348 // TODO(peter): test First and Last. 349 func TestIteratorBounds(t *testing.T) { 350 d := &testStorage{} 351 l := NewSkiplist(d, 0) 352 for i := 1; i < 10; i++ { 353 err := l.Add(d.add(fmt.Sprintf("%05d", i))) 354 if err != nil { 355 t.Fatal(err) 356 } 357 } 358 359 it := iterAdapter{l.NewIter(makeKey("00003"), makeKey("00007"))} 360 361 // SeekGE within the lower and upper bound succeeds. 362 for i := 3; i <= 6; i++ { 363 key := makeKey(fmt.Sprintf("%05d", i)) 364 require.True(t, it.SeekGE(key)) 365 require.EqualValues(t, string(key), string(it.Key().UserKey)) 366 } 367 368 // SeekGE before the lower bound still succeeds (only the upper bound is 369 // checked). 370 for i := 1; i < 3; i++ { 371 key := makeKey(fmt.Sprintf("%05d", i)) 372 require.True(t, it.SeekGE(key)) 373 require.EqualValues(t, string(key), string(it.Key().UserKey)) 374 } 375 376 // SeekGE beyond the upper bound fails. 377 for i := 7; i < 10; i++ { 378 key := makeKey(fmt.Sprintf("%05d", i)) 379 require.False(t, it.SeekGE(key)) 380 } 381 382 require.True(t, it.SeekGE(makeKey("00006"))) 383 require.EqualValues(t, "00006", it.Key().UserKey) 384 385 // Next into the upper bound fails. 386 require.False(t, it.Next()) 387 388 // SeekLT within the lower and upper bound succeeds. 389 for i := 4; i <= 7; i++ { 390 key := makeKey(fmt.Sprintf("%05d", i)) 391 require.True(t, it.SeekLT(key)) 392 require.EqualValues(t, fmt.Sprintf("%05d", i-1), string(it.Key().UserKey)) 393 } 394 395 // SeekLT beyond the upper bound still succeeds (only the lower bound is 396 // checked). 397 for i := 8; i < 9; i++ { 398 key := makeKey(fmt.Sprintf("%05d", i)) 399 require.True(t, it.SeekLT(key)) 400 require.EqualValues(t, fmt.Sprintf("%05d", i-1), string(it.Key().UserKey)) 401 } 402 403 // SeekLT before the lower bound fails. 404 for i := 1; i < 4; i++ { 405 key := makeKey(fmt.Sprintf("%05d", i)) 406 require.False(t, it.SeekLT(key)) 407 } 408 409 require.True(t, it.SeekLT(makeKey("00004"))) 410 require.EqualValues(t, "00003", it.Key().UserKey) 411 412 // Prev into the lower bound fails. 413 require.False(t, it.Prev()) 414 } 415 416 func randomKey(rng *rand.Rand, b []byte) []byte { 417 key := rng.Uint32() 418 key2 := rng.Uint32() 419 binary.LittleEndian.PutUint32(b, key) 420 binary.LittleEndian.PutUint32(b[4:], key2) 421 return b 422 } 423 424 // Standard test. Some fraction is read. Some fraction is write. Writes have 425 // to go through mutex lock. 426 func BenchmarkReadWrite(b *testing.B) { 427 for i := 0; i <= 10; i++ { 428 readFrac := float32(i) / 10.0 429 b.Run(fmt.Sprintf("frac_%d", i*10), func(b *testing.B) { 430 buf := make([]byte, b.N*8) 431 d := &testStorage{ 432 keys: make([][]byte, 0, b.N), 433 } 434 l := NewSkiplist(d, 0) 435 it := l.NewIter(nil, nil) 436 rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano()))) 437 438 b.ResetTimer() 439 for i := 0; i < b.N; i++ { 440 key := randomKey(rng, buf[i*8:(i+1)*8]) 441 if rng.Float32() < readFrac { 442 _ = it.SeekGE(key) 443 } else { 444 offset := uint32(len(d.keys)) 445 d.keys = append(d.keys, key) 446 _ = l.Add(offset) 447 } 448 } 449 b.StopTimer() 450 }) 451 } 452 } 453 454 func BenchmarkIterNext(b *testing.B) { 455 buf := make([]byte, 64<<10) 456 d := &testStorage{ 457 keys: make([][]byte, 0, (64<<10)/8), 458 } 459 l := NewSkiplist(d, 0) 460 461 rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano()))) 462 for i := 0; i < len(buf); i += 8 { 463 key := randomKey(rng, buf[i:i+8]) 464 offset := uint32(len(d.keys)) 465 d.keys = append(d.keys, key) 466 _ = l.Add(offset) 467 } 468 469 it := l.NewIter(nil, nil) 470 b.ResetTimer() 471 for i := 0; i < b.N; i++ { 472 if !it.Valid() { 473 it.First() 474 } 475 it.Next() 476 } 477 } 478 479 func BenchmarkIterPrev(b *testing.B) { 480 buf := make([]byte, 64<<10) 481 d := &testStorage{ 482 keys: make([][]byte, 0, (64<<10)/8), 483 } 484 l := NewSkiplist(d, 0) 485 486 rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano()))) 487 for i := 0; i < len(buf); i += 8 { 488 key := randomKey(rng, buf[i:i+8]) 489 offset := uint32(len(d.keys)) 490 d.keys = append(d.keys, key) 491 _ = l.Add(offset) 492 } 493 494 it := l.NewIter(nil, nil) 495 b.ResetTimer() 496 for i := 0; i < b.N; i++ { 497 if !it.Valid() { 498 it.Last() 499 } 500 it.Prev() 501 } 502 }