github.com/andy-kimball/arenaskl@v0.0.0-20200617143215-f701008588b9/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  	"encoding/binary"
    22  	"fmt"
    23  	"math/rand"
    24  	"strconv"
    25  	"sync"
    26  	"sync/atomic"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  const arenaSize = 1 << 20
    34  
    35  func newValue(v int) []byte {
    36  	return []byte(fmt.Sprintf("%05d", v))
    37  }
    38  
    39  // length iterates over skiplist to give exact size.
    40  func length(s *Skiplist) int {
    41  	count := 0
    42  
    43  	var it Iterator
    44  	it.Init(s)
    45  
    46  	for it.SeekToFirst(); it.Valid(); it.Next() {
    47  		count++
    48  	}
    49  
    50  	return count
    51  }
    52  
    53  // length iterates over skiplist in reverse order to give exact size.
    54  func lengthRev(s *Skiplist) int {
    55  	count := 0
    56  
    57  	var it Iterator
    58  	it.Init(s)
    59  
    60  	for it.SeekToLast(); it.Valid(); it.Prev() {
    61  		count++
    62  	}
    63  
    64  	return count
    65  }
    66  
    67  func TestEmpty(t *testing.T) {
    68  	key := []byte("aaa")
    69  	l := NewSkiplist(NewArena(arenaSize))
    70  
    71  	var it Iterator
    72  	it.Init(l)
    73  
    74  	require.False(t, it.Valid())
    75  
    76  	it.SeekToFirst()
    77  	require.False(t, it.Valid())
    78  
    79  	it.SeekToLast()
    80  	require.False(t, it.Valid())
    81  
    82  	found := it.Seek(key)
    83  	require.False(t, found)
    84  	require.False(t, it.Valid())
    85  }
    86  
    87  func TestFull(t *testing.T) {
    88  	l := NewSkiplist(NewArena(1000))
    89  
    90  	var it Iterator
    91  	it.Init(l)
    92  
    93  	foundArenaFull := false
    94  	for i := 0; i < 100; i++ {
    95  		err := it.Add([]byte(fmt.Sprintf("%05d", i)), newValue(i), 0)
    96  		if err == ErrArenaFull {
    97  			foundArenaFull = true
    98  		}
    99  	}
   100  
   101  	require.True(t, foundArenaFull)
   102  
   103  	err := it.Set([]byte("someval"), 0)
   104  	require.Equal(t, ErrArenaFull, err)
   105  
   106  	// Delete does not perform any allocation.
   107  	err = it.Delete()
   108  	require.Nil(t, err)
   109  }
   110  
   111  // TestBasic tests single-threaded seeks and sets, adds, and deletes.
   112  func TestBasic(t *testing.T) {
   113  	l := NewSkiplist(NewArena(arenaSize))
   114  
   115  	var it Iterator
   116  	it.Init(l)
   117  
   118  	val1 := newValue(42)
   119  	val2 := newValue(52)
   120  	val3 := newValue(62)
   121  	val4 := newValue(72)
   122  
   123  	// Try adding values.
   124  	it.Add([]byte("key1"), val1, 0)
   125  	it.Add([]byte("key3"), val3, 0xffff)
   126  	it.Add([]byte("key2"), val2, 100)
   127  
   128  	require.False(t, it.Seek([]byte("key")))
   129  
   130  	require.True(t, it.Seek([]byte("key1")))
   131  	require.EqualValues(t, "00042", it.Value())
   132  	require.EqualValues(t, 0, it.Meta())
   133  
   134  	require.True(t, it.Seek([]byte("key2")))
   135  	require.EqualValues(t, "00052", it.Value())
   136  	require.EqualValues(t, 100, it.Meta())
   137  
   138  	require.True(t, it.Seek([]byte("key3")))
   139  	require.EqualValues(t, "00062", it.Value())
   140  	require.EqualValues(t, 0xffff, it.Meta())
   141  
   142  	require.True(t, it.Seek([]byte("key2")))
   143  	require.Nil(t, it.Set(val4, 101))
   144  	require.EqualValues(t, "00072", it.Value())
   145  	require.EqualValues(t, 101, it.Meta())
   146  
   147  	require.True(t, it.Seek([]byte("key3")))
   148  	require.Nil(t, it.Delete())
   149  	require.True(t, !it.Valid())
   150  }
   151  
   152  // TestConcurrentBasic tests concurrent writes followed by concurrent reads.
   153  func TestConcurrentBasic(t *testing.T) {
   154  	const n = 1000
   155  
   156  	// Set testing flag to make it easier to trigger unusual race conditions.
   157  	l := NewSkiplist(NewArena(arenaSize))
   158  	l.testing = true
   159  
   160  	var wg sync.WaitGroup
   161  	for i := 0; i < n; i++ {
   162  		wg.Add(1)
   163  		go func(i int) {
   164  			defer wg.Done()
   165  
   166  			var it Iterator
   167  			it.Init(l)
   168  
   169  			it.Add([]byte(fmt.Sprintf("%05d", i)), newValue(i), 0)
   170  		}(i)
   171  	}
   172  	wg.Wait()
   173  
   174  	// Check values. Concurrent reads.
   175  	for i := 0; i < n; i++ {
   176  		wg.Add(1)
   177  		go func(i int) {
   178  			defer wg.Done()
   179  
   180  			var it Iterator
   181  			it.Init(l)
   182  
   183  			found := it.Seek([]byte(fmt.Sprintf("%05d", i)))
   184  			require.True(t, found)
   185  			require.EqualValues(t, newValue(i), it.Value())
   186  		}(i)
   187  	}
   188  	wg.Wait()
   189  	require.Equal(t, n, length(l))
   190  	require.Equal(t, n, lengthRev(l))
   191  }
   192  
   193  // TestConcurrentOneKey will read while writing to one single key.
   194  func TestConcurrentOneKey(t *testing.T) {
   195  	const n = 100
   196  	key := []byte("thekey")
   197  
   198  	// Set testing flag to make it easier to trigger unusual race conditions.
   199  	l := NewSkiplist(NewArena(arenaSize))
   200  	l.testing = true
   201  
   202  	var wg sync.WaitGroup
   203  	for i := 0; i < n; i++ {
   204  		wg.Add(1)
   205  		go func(i int) {
   206  			defer wg.Done()
   207  
   208  			var it Iterator
   209  			it.Init(l)
   210  			it.Add(key, newValue(i), 0)
   211  		}(i)
   212  	}
   213  	// We expect that at least some write made it such that some read returns a value.
   214  	var sawValue int32
   215  	for i := 0; i < n; i++ {
   216  		wg.Add(1)
   217  		go func() {
   218  			defer wg.Done()
   219  
   220  			var it Iterator
   221  			it.Init(l)
   222  			if !it.Seek(key) {
   223  				return
   224  			}
   225  
   226  			atomic.StoreInt32(&sawValue, 1)
   227  			v, err := strconv.Atoi(string(it.Value()))
   228  			require.NoError(t, err)
   229  			require.True(t, 0 <= v && v < n)
   230  		}()
   231  	}
   232  	wg.Wait()
   233  	require.True(t, sawValue > 0)
   234  	require.Equal(t, 1, length(l))
   235  	require.Equal(t, 1, lengthRev(l))
   236  }
   237  
   238  func TestIteratorAdd(t *testing.T) {
   239  	l := NewSkiplist(NewArena(arenaSize))
   240  
   241  	var it Iterator
   242  	it.Init(l)
   243  
   244  	// Add nil key and value (treated same as empty).
   245  	err := it.Add(nil, nil, 0)
   246  	require.Nil(t, err)
   247  	require.EqualValues(t, []byte{}, it.Key())
   248  	require.EqualValues(t, []byte{}, it.Value())
   249  	require.EqualValues(t, 0, it.Meta())
   250  	it.Delete()
   251  
   252  	// Add empty key and value (treated same as nil).
   253  	err = it.Add([]byte{}, []byte{}, 0)
   254  	require.Nil(t, err)
   255  	require.EqualValues(t, []byte{}, it.Key())
   256  	require.EqualValues(t, []byte{}, it.Value())
   257  	require.EqualValues(t, 0, it.Meta())
   258  
   259  	// Add to empty list.
   260  	err = it.Add([]byte("00002"), []byte("00002"), 50)
   261  	require.Nil(t, err)
   262  	require.EqualValues(t, "00002", it.Value())
   263  	require.EqualValues(t, 50, it.Meta())
   264  
   265  	// Add first element in non-empty list.
   266  	err = it.Add([]byte("00001"), []byte("00001"), 100)
   267  	require.Nil(t, err)
   268  	require.EqualValues(t, "00001", it.Value())
   269  	require.EqualValues(t, 100, it.Meta())
   270  
   271  	// Add last element in non-empty list.
   272  	err = it.Add([]byte("00004"), []byte("00004"), 150)
   273  	require.Nil(t, err)
   274  	require.EqualValues(t, "00004", it.Value())
   275  	require.EqualValues(t, 150, it.Meta())
   276  
   277  	// Add element in middle of list.
   278  	err = it.Add([]byte("00003"), []byte("00003"), 200)
   279  	require.Nil(t, err)
   280  	require.EqualValues(t, "00003", it.Value())
   281  	require.EqualValues(t, 200, it.Meta())
   282  
   283  	// Try to add element that already exists.
   284  	err = it.Add([]byte("00002"), []byte("00002*"), 250)
   285  	require.Equal(t, ErrRecordExists, err)
   286  	require.EqualValues(t, []byte("00002"), it.Value())
   287  	require.EqualValues(t, 50, it.Meta())
   288  
   289  	// Try to add element that was previously deleted.
   290  	it.Seek([]byte("00004"))
   291  	it.Delete()
   292  	err = it.Add([]byte("00004"), []byte("00004*"), 300)
   293  	require.Nil(t, err)
   294  	require.EqualValues(t, []byte("00004*"), it.Value())
   295  	require.EqualValues(t, 300, it.Meta())
   296  
   297  	require.Equal(t, 5, length(l))
   298  	require.Equal(t, 5, lengthRev(l))
   299  }
   300  
   301  func TestIteratorSet(t *testing.T) {
   302  	l := NewSkiplist(NewArena(arenaSize))
   303  
   304  	var it Iterator
   305  	it.Init(l)
   306  
   307  	var it2 Iterator
   308  	it2.Init(l)
   309  
   310  	// Set when iterator position is invalid.
   311  	require.Panics(t, func() { it.Set([]byte("00001a"), 0) })
   312  
   313  	// Set new value.
   314  	it.Add([]byte("00001"), []byte("00001a"), 100)
   315  	err := it.Set([]byte("00001b"), 200)
   316  	require.Nil(t, err)
   317  	require.EqualValues(t, "00001b", it.Value())
   318  	require.EqualValues(t, 200, it.Meta())
   319  
   320  	// Try to set value that's been updated by a different iterator.
   321  	it2.Seek([]byte("00001"))
   322  	err = it.Set([]byte("00001c"), 300)
   323  	require.Nil(t, err)
   324  	err = it2.Set([]byte("00001d"), 400)
   325  	require.Equal(t, ErrRecordUpdated, err)
   326  	require.EqualValues(t, []byte("00001c"), it2.Value())
   327  	require.EqualValues(t, 300, it2.Meta())
   328  	err = it2.Set([]byte("00001d"), 400)
   329  	require.Nil(t, err)
   330  	require.EqualValues(t, "00001d", it2.Value())
   331  	require.EqualValues(t, 400, it2.Meta())
   332  
   333  	// Try to set value that's been deleted by a different iterator.
   334  	it.Seek([]byte("00001"))
   335  	it2.Seek([]byte("00001"))
   336  	err = it.Delete()
   337  	require.Nil(t, err)
   338  	err = it.Add([]byte("00002"), []byte("00002"), 500)
   339  	require.Nil(t, err)
   340  	err = it2.Set([]byte("00001e"), 600)
   341  	require.Equal(t, ErrRecordDeleted, err)
   342  	require.EqualValues(t, "00001d", it2.Value())
   343  	require.EqualValues(t, 400, it2.Meta())
   344  
   345  	require.Equal(t, 1, length(l))
   346  	require.Equal(t, 1, lengthRev(l))
   347  }
   348  
   349  func TestIteratorSetMeta(t *testing.T) {
   350  	l := NewSkiplist(NewArena(arenaSize))
   351  
   352  	var it Iterator
   353  	it.Init(l)
   354  
   355  	var it2 Iterator
   356  	it2.Init(l)
   357  
   358  	// SetMeta when iterator position is invalid.
   359  	require.Panics(t, func() { it.SetMeta(0) })
   360  
   361  	// SetMeta new value.
   362  	it.Add([]byte("00001"), []byte("00001a"), 100)
   363  	val := it.Value()
   364  	err := it.SetMeta(200)
   365  	require.Nil(t, err)
   366  	require.EqualValues(t, "00001a", it.Value())
   367  	require.True(t, &val[0] == &it.Value()[0], "Value bytes should not be reused")
   368  	require.EqualValues(t, 200, it.Meta())
   369  
   370  	// SetMeta new lower value.
   371  	err = it.SetMeta(50)
   372  	require.Nil(t, err)
   373  	require.EqualValues(t, "00001a", it.Value())
   374  	require.False(t, &val[0] == &it.Value()[0], "Value bytes should not be reused")
   375  	require.EqualValues(t, 50, it.Meta())
   376  
   377  	// Try to set meta that's been updated by a different iterator.
   378  	it2.Seek([]byte("00001"))
   379  	err = it.SetMeta(300)
   380  	require.Nil(t, err)
   381  	err = it2.SetMeta(400)
   382  	require.Equal(t, ErrRecordUpdated, err)
   383  	require.EqualValues(t, 300, it2.Meta())
   384  	err = it2.SetMeta(400)
   385  	require.Nil(t, err)
   386  	require.EqualValues(t, 400, it2.Meta())
   387  
   388  	// Try to set value that's been deleted by a different iterator.
   389  	it.Seek([]byte("00001"))
   390  	it2.Seek([]byte("00001"))
   391  	err = it.Delete()
   392  	require.Nil(t, err)
   393  	err = it.Add([]byte("00002"), []byte("00002"), 500)
   394  	require.Nil(t, err)
   395  	err = it2.SetMeta(600)
   396  	require.Equal(t, ErrRecordDeleted, err)
   397  	require.EqualValues(t, 400, it2.Meta())
   398  
   399  	require.Equal(t, 1, length(l))
   400  	require.Equal(t, 1, lengthRev(l))
   401  }
   402  
   403  func TestIteratorDelete(t *testing.T) {
   404  	l := NewSkiplist(NewArena(arenaSize))
   405  
   406  	var it Iterator
   407  	it.Init(l)
   408  
   409  	var it2 Iterator
   410  	it2.Init(l)
   411  
   412  	// Delete when iterator position is invalid.
   413  	require.Panics(t, func() { it.Delete() })
   414  
   415  	it.Add([]byte("00001"), []byte("00001"), 100)
   416  	it.Add([]byte("00002"), []byte("00002"), 200)
   417  	it.Add([]byte("00003"), []byte("00003"), 300)
   418  	it.Add([]byte("00004"), []byte("00004"), 400)
   419  
   420  	// Delete first node.
   421  	it.SeekToFirst()
   422  	err := it.Delete()
   423  	require.Nil(t, err)
   424  	require.EqualValues(t, "00002", it.Value())
   425  	require.EqualValues(t, 200, it.Meta())
   426  
   427  	// Delete last node.
   428  	it.Seek([]byte("00004"))
   429  	err = it.Delete()
   430  	require.Nil(t, err)
   431  	require.False(t, it.Valid())
   432  	require.Equal(t, 2, length(l))
   433  
   434  	// Try to delete node that's been updated by another iterator.
   435  	it.SeekToFirst()
   436  	require.EqualValues(t, "00002", it.Value())
   437  	it2.SeekToFirst()
   438  	require.EqualValues(t, "00002", it2.Value())
   439  	it2.Set([]byte("00002a"), 500)
   440  	err = it.Delete()
   441  	require.Equal(t, ErrRecordUpdated, err)
   442  	require.EqualValues(t, "00002a", it.Value())
   443  	require.EqualValues(t, 500, it.Meta())
   444  
   445  	// Delete node that's been deleted by another iterator.
   446  	err = it2.Delete()
   447  	require.Nil(t, err)
   448  	err = it.Delete()
   449  	require.Nil(t, err)
   450  	require.EqualValues(t, "00003", it.Value())
   451  	require.EqualValues(t, 300, it.Meta())
   452  
   453  	// Delete final node so that list is empty.
   454  	err = it.Delete()
   455  	require.Nil(t, err)
   456  	require.False(t, it.Valid())
   457  	require.Equal(t, 0, length(l))
   458  	require.Equal(t, 0, lengthRev(l))
   459  }
   460  
   461  // TestConcurrentAdd races between adding same nodes.
   462  func TestConcurrentAdd(t *testing.T) {
   463  	const n = 100
   464  
   465  	// Set testing flag to make it easier to trigger unusual race conditions.
   466  	l := NewSkiplist(NewArena(arenaSize))
   467  	l.testing = true
   468  
   469  	start := make([]sync.WaitGroup, n)
   470  	end := make([]sync.WaitGroup, n)
   471  
   472  	for i := 0; i < n; i++ {
   473  		start[i].Add(1)
   474  		end[i].Add(2)
   475  	}
   476  
   477  	for f := 0; f < 2; f++ {
   478  		go func(id int) {
   479  			var it Iterator
   480  			it.Init(l)
   481  
   482  			for i := 0; i < n; i++ {
   483  				start[i].Wait()
   484  
   485  				key := newValue(i)
   486  				val := []byte(fmt.Sprintf("%d: %05d", id, i))
   487  				if it.Add(key, val, 0) == nil {
   488  					it.Seek(key)
   489  					require.EqualValues(t, val, it.Value())
   490  				}
   491  
   492  				end[i].Done()
   493  			}
   494  		}(f)
   495  	}
   496  
   497  	for i := 0; i < n; i++ {
   498  		start[i].Done()
   499  		end[i].Wait()
   500  	}
   501  
   502  	require.Equal(t, n, length(l))
   503  	require.Equal(t, n, lengthRev(l))
   504  }
   505  
   506  // TestConcurrentAddDelete races between adding and deleting the same node.
   507  func TestConcurrentAddDelete(t *testing.T) {
   508  	const n = 100
   509  
   510  	// Set testing flag to make it easier to trigger unusual race conditions.
   511  	l := NewSkiplist(NewArena(arenaSize))
   512  	l.testing = true
   513  
   514  	var wg sync.WaitGroup
   515  	for i := 0; i < n; i++ {
   516  		key := []byte("key")
   517  		val := newValue(i)
   518  
   519  		wg.Add(1)
   520  		go func(i int) {
   521  			defer wg.Done()
   522  
   523  			var it Iterator
   524  			it.Init(l)
   525  
   526  			for {
   527  				if it.Add(key, val, 0) == nil {
   528  					require.EqualValues(t, val, it.Value())
   529  					break
   530  				}
   531  
   532  				require.NotEqual(t, val, it.Value())
   533  				if it.Delete() == nil {
   534  					require.False(t, it.Valid())
   535  				}
   536  			}
   537  		}(i)
   538  	}
   539  	wg.Wait()
   540  
   541  	require.Equal(t, 1, length(l))
   542  	require.Equal(t, 1, lengthRev(l))
   543  }
   544  
   545  // TestIteratorNext tests a basic iteration over all nodes from the beginning.
   546  func TestIteratorNext(t *testing.T) {
   547  	const n = 100
   548  	l := NewSkiplist(NewArena(arenaSize))
   549  
   550  	var it Iterator
   551  	it.Init(l)
   552  
   553  	require.False(t, it.Valid())
   554  
   555  	it.SeekToFirst()
   556  	require.False(t, it.Valid())
   557  
   558  	for i := n - 1; i >= 0; i-- {
   559  		it.Add([]byte(fmt.Sprintf("%05d", i)), newValue(i), 0)
   560  	}
   561  
   562  	it.SeekToFirst()
   563  	for i := 0; i < n; i++ {
   564  		require.True(t, it.Valid())
   565  		require.EqualValues(t, newValue(i), it.Value())
   566  		it.Next()
   567  	}
   568  	require.False(t, it.Valid())
   569  }
   570  
   571  // TestIteratorPrev tests a basic iteration over all nodes from the end.
   572  func TestIteratorPrev(t *testing.T) {
   573  	const n = 100
   574  	l := NewSkiplist(NewArena(arenaSize))
   575  
   576  	var it Iterator
   577  	it.Init(l)
   578  
   579  	require.False(t, it.Valid())
   580  
   581  	it.SeekToLast()
   582  	require.False(t, it.Valid())
   583  
   584  	for i := 0; i < n; i++ {
   585  		it.Add([]byte(fmt.Sprintf("%05d", i)), newValue(i), 0)
   586  	}
   587  
   588  	it.SeekToLast()
   589  	for i := n - 1; i >= 0; i-- {
   590  		require.True(t, it.Valid())
   591  		require.EqualValues(t, newValue(i), it.Value())
   592  		it.Prev()
   593  	}
   594  	require.False(t, it.Valid())
   595  }
   596  
   597  func TestIteratorSeek(t *testing.T) {
   598  	const n = 100
   599  	l := NewSkiplist(NewArena(arenaSize))
   600  
   601  	var it Iterator
   602  	it.Init(l)
   603  
   604  	require.False(t, it.Valid())
   605  	it.SeekToFirst()
   606  	require.False(t, it.Valid())
   607  	// 1000, 1010, 1020, ..., 1990.
   608  	for i := n - 1; i >= 0; i-- {
   609  		v := i*10 + 1000
   610  		it.Add([]byte(fmt.Sprintf("%05d", i*10+1000)), newValue(v), uint16(v))
   611  	}
   612  
   613  	found := it.Seek([]byte(""))
   614  	require.False(t, found)
   615  	require.True(t, it.Valid())
   616  	require.EqualValues(t, "01000", it.Value())
   617  	require.EqualValues(t, 1000, it.Meta())
   618  
   619  	found = it.Seek([]byte("01000"))
   620  	require.True(t, found)
   621  	require.True(t, it.Valid())
   622  	require.EqualValues(t, "01000", it.Value())
   623  	require.EqualValues(t, 1000, it.Meta())
   624  
   625  	found = it.Seek([]byte("01005"))
   626  	require.False(t, found)
   627  	require.True(t, it.Valid())
   628  	require.EqualValues(t, "01010", it.Value())
   629  	require.EqualValues(t, 1010, it.Meta())
   630  
   631  	found = it.Seek([]byte("01010"))
   632  	require.True(t, found)
   633  	require.True(t, it.Valid())
   634  	require.EqualValues(t, "01010", it.Value())
   635  	require.EqualValues(t, 1010, it.Meta())
   636  
   637  	found = it.Seek([]byte("99999"))
   638  	require.False(t, found)
   639  	require.False(t, it.Valid())
   640  
   641  	// Test seek for deleted key.
   642  	it.Seek([]byte("01020"))
   643  	it.Delete()
   644  	found = it.Seek([]byte("01020"))
   645  	require.False(t, found)
   646  	require.True(t, it.Valid())
   647  	require.EqualValues(t, "01030", it.Value())
   648  	require.EqualValues(t, 1030, it.Meta())
   649  
   650  	// Test seek for empty key.
   651  	it.Add(nil, nil, 0)
   652  	found = it.Seek(nil)
   653  	require.True(t, found)
   654  	require.True(t, it.Valid())
   655  	require.EqualValues(t, "", it.Value())
   656  	require.EqualValues(t, 0, it.Meta())
   657  
   658  	found = it.Seek([]byte{})
   659  	require.True(t, found)
   660  	require.True(t, it.Valid())
   661  	require.EqualValues(t, "", it.Value())
   662  	require.EqualValues(t, 0, it.Meta())
   663  }
   664  
   665  func TestIteratorSeekForPrev(t *testing.T) {
   666  	const n = 100
   667  	l := NewSkiplist(NewArena(arenaSize))
   668  
   669  	var it Iterator
   670  	it.Init(l)
   671  
   672  	require.False(t, it.Valid())
   673  	it.SeekToFirst()
   674  	require.False(t, it.Valid())
   675  	// 1000, 1010, 1020, ..., 1990.
   676  	for i := n - 1; i >= 0; i-- {
   677  		v := i*10 + 1000
   678  		it.Add([]byte(fmt.Sprintf("%05d", i*10+1000)), newValue(v), uint16(v))
   679  	}
   680  
   681  	found := it.SeekForPrev([]byte(""))
   682  	require.False(t, found)
   683  	require.False(t, it.Valid())
   684  
   685  	found = it.SeekForPrev([]byte("00990"))
   686  	require.False(t, found)
   687  	require.False(t, it.Valid())
   688  
   689  	found = it.SeekForPrev([]byte("01000"))
   690  	require.True(t, found)
   691  	require.True(t, it.Valid())
   692  	require.EqualValues(t, "01000", it.Value())
   693  	require.EqualValues(t, 1000, it.Meta())
   694  
   695  	found = it.SeekForPrev([]byte("01005"))
   696  	require.False(t, found)
   697  	require.True(t, it.Valid())
   698  	require.EqualValues(t, "01000", it.Value())
   699  	require.EqualValues(t, 1000, it.Meta())
   700  
   701  	found = it.SeekForPrev([]byte("01990"))
   702  	require.True(t, found)
   703  	require.True(t, it.Valid())
   704  	require.EqualValues(t, "01990", it.Value())
   705  	require.EqualValues(t, 1990, it.Meta())
   706  
   707  	found = it.SeekForPrev([]byte("99999"))
   708  	require.False(t, found)
   709  	require.True(t, it.Valid())
   710  	require.EqualValues(t, "01990", it.Value())
   711  	require.EqualValues(t, 1990, it.Meta())
   712  
   713  	// Test seek for deleted key.
   714  	it.Seek([]byte("01020"))
   715  	it.Delete()
   716  	found = it.SeekForPrev([]byte("01020"))
   717  	require.False(t, found)
   718  	require.True(t, it.Valid())
   719  	require.EqualValues(t, "01010", it.Value())
   720  	require.EqualValues(t, 1010, it.Meta())
   721  
   722  	// Test seek for empty key.
   723  	it.Add(nil, nil, 0)
   724  	found = it.SeekForPrev(nil)
   725  	require.True(t, found)
   726  	require.True(t, it.Valid())
   727  	require.EqualValues(t, "", it.Value())
   728  	require.EqualValues(t, 0, it.Meta())
   729  
   730  	found = it.SeekForPrev([]byte{})
   731  	require.True(t, found)
   732  	require.True(t, it.Valid())
   733  	require.EqualValues(t, "", it.Value())
   734  	require.EqualValues(t, 0, it.Meta())
   735  }
   736  
   737  func randomKey(rng *rand.Rand) []byte {
   738  	b := make([]byte, 8)
   739  	key := rng.Uint32()
   740  	key2 := rng.Uint32()
   741  	binary.LittleEndian.PutUint32(b, key)
   742  	binary.LittleEndian.PutUint32(b[4:], key2)
   743  	return b
   744  }
   745  
   746  // Standard test. Some fraction is read. Some fraction is write.
   747  func BenchmarkReadWrite(b *testing.B) {
   748  	value := newValue(123)
   749  	for i := 0; i <= 10; i++ {
   750  		readFrac := float32(i) / 10.0
   751  		b.Run(fmt.Sprintf("frac_%d", i*10), func(b *testing.B) {
   752  			l := NewSkiplist(NewArena(uint32((b.N + 2) * MaxNodeSize)))
   753  			b.ResetTimer()
   754  			var count int
   755  			b.RunParallel(func(pb *testing.PB) {
   756  				var iter Iterator
   757  				iter.Init(l)
   758  
   759  				rng := rand.New(rand.NewSource(time.Now().UnixNano()))
   760  
   761  				for pb.Next() {
   762  					if rng.Float32() < readFrac {
   763  						if iter.Seek(randomKey(rng)) {
   764  							_ = iter.Value()
   765  							count++
   766  						}
   767  					} else {
   768  						iter.Add(randomKey(rng), value, 0)
   769  					}
   770  				}
   771  			})
   772  		})
   773  	}
   774  }
   775  
   776  // Standard test. Some fraction is read. Some fraction is write. Writes have
   777  // to go through mutex lock.
   778  func BenchmarkReadWriteMap(b *testing.B) {
   779  	value := newValue(123)
   780  	for i := 0; i <= 10; i++ {
   781  		readFrac := float32(i) / 10.0
   782  		b.Run(fmt.Sprintf("frac_%d", i), func(b *testing.B) {
   783  			m := make(map[string][]byte)
   784  			var mutex sync.RWMutex
   785  			b.ResetTimer()
   786  			var count int
   787  			b.RunParallel(func(pb *testing.PB) {
   788  				rng := rand.New(rand.NewSource(time.Now().UnixNano()))
   789  				for pb.Next() {
   790  					if rng.Float32() < readFrac {
   791  						mutex.RLock()
   792  						_, ok := m[string(randomKey(rng))]
   793  						mutex.RUnlock()
   794  						if ok {
   795  							count++
   796  						}
   797  					} else {
   798  						mutex.Lock()
   799  						m[string(randomKey(rng))] = value
   800  						mutex.Unlock()
   801  					}
   802  				}
   803  			})
   804  		})
   805  	}
   806  }