github.com/matrixorigin/matrixone@v1.2.0/pkg/common/arenaskl/skl_test.go (about)

     1  /*
     2   * Copyright 2017 Dgraph Labs, Inc. and Contributors
     3   * Modifications copyright (C) 2017 Andy Kimball and Contributors
     4   * and copyright (C) 2024 MatrixOrigin Inc.
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   *     http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package arenaskl
    20  
    21  import (
    22  	"bytes"
    23  	"encoding/binary"
    24  	"fmt"
    25  	"strconv"
    26  	"sync"
    27  	"sync/atomic"
    28  	"testing"
    29  	"time"
    30  
    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 []byte
    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(ok bool, key, val []byte) bool {
    53  	i.key = key
    54  	i.val = val
    55  	return ok
    56  }
    57  
    58  func (i *iterAdapter) String() string {
    59  	return "iter-adapter"
    60  }
    61  
    62  func (i *iterAdapter) SeekGE(key []byte) bool {
    63  	return i.update(i.Iterator.SeekGE(key))
    64  }
    65  
    66  func (i *iterAdapter) SeekPrefixGE(prefix, key []byte) bool {
    67  	return i.update(i.Iterator.SeekPrefixGE(prefix, key))
    68  }
    69  
    70  func (i *iterAdapter) SeekLT(key []byte) bool {
    71  	return i.update(i.Iterator.SeekLT(key))
    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() []byte {
    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) []byte {
   103  	return []byte(fmt.Sprintf("%05d", i))
   104  }
   105  
   106  func makeKey(s string) []byte {
   107  	return []byte(s)
   108  }
   109  
   110  func makeIkey(s string) []byte {
   111  	return []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 []byte, value []byte) error {
   119  	ins := &Inserter{}
   120  	return func(key []byte, 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))
   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")))
   202  			require.True(t, it.Valid())
   203  			require.NotEqual(t, "key", it.Key())
   204  
   205  			require.True(t, it.SeekGE(makeKey("key1")))
   206  			require.EqualValues(t, "key1", it.Key())
   207  			require.EqualValues(t, makeValue(1), it.Value())
   208  
   209  			require.True(t, it.SeekGE(makeKey("key2")))
   210  			require.EqualValues(t, "key2", it.Key())
   211  			require.EqualValues(t, makeValue(2), it.Value())
   212  
   213  			require.True(t, it.SeekGE(makeKey("key3")))
   214  			require.EqualValues(t, "key3", it.Key())
   215  			require.EqualValues(t, makeValue(3), it.Value())
   216  		})
   217  	}
   218  }
   219  
   220  // TestConcurrentBasic tests concurrent writes followed by concurrent reads.
   221  func TestConcurrentBasic(t *testing.T) {
   222  	const n = 1000
   223  
   224  	for _, inserter := range []bool{false, true} {
   225  		t.Run(fmt.Sprintf("inserter=%t", inserter), func(t *testing.T) {
   226  			// Set testing flag to make it easier to trigger unusual race conditions.
   227  			l := NewSkiplist(newArena(arenaSize), bytes.Compare)
   228  			l.testing = true
   229  
   230  			var wg sync.WaitGroup
   231  			for i := 0; i < n; i++ {
   232  				wg.Add(1)
   233  				go func(i int) {
   234  					defer wg.Done()
   235  
   236  					if inserter {
   237  						var ins Inserter
   238  						ins.Add(l, makeIntKey(i), makeValue(i))
   239  					} else {
   240  						l.Add(makeIntKey(i), makeValue(i))
   241  					}
   242  				}(i)
   243  			}
   244  			wg.Wait()
   245  
   246  			// Check values. Concurrent reads.
   247  			for i := 0; i < n; i++ {
   248  				wg.Add(1)
   249  				go func(i int) {
   250  					defer wg.Done()
   251  
   252  					it := newIterAdapter(l.NewIter(nil, nil))
   253  					require.True(t, it.SeekGE(makeKey(fmt.Sprintf("%05d", i))))
   254  					require.EqualValues(t, fmt.Sprintf("%05d", i), it.Key())
   255  				}(i)
   256  			}
   257  			wg.Wait()
   258  			require.Equal(t, n, length(l))
   259  			require.Equal(t, n, lengthRev(l))
   260  		})
   261  	}
   262  }
   263  
   264  // TestConcurrentOneKey will read while writing to one single key.
   265  func TestConcurrentOneKey(t *testing.T) {
   266  	const n = 100
   267  	key := makeKey("thekey")
   268  	ikey := makeIkey("thekey")
   269  
   270  	for _, inserter := range []bool{false, true} {
   271  		t.Run(fmt.Sprintf("inserter=%t", inserter), func(t *testing.T) {
   272  			// Set testing flag to make it easier to trigger unusual race conditions.
   273  			l := NewSkiplist(newArena(arenaSize), bytes.Compare)
   274  			l.testing = true
   275  
   276  			var wg sync.WaitGroup
   277  			writeDone := make(chan struct{}, 1)
   278  			for i := 0; i < n; i++ {
   279  				wg.Add(1)
   280  				go func(i int) {
   281  					defer func() {
   282  						wg.Done()
   283  						select {
   284  						case writeDone <- struct{}{}:
   285  						default:
   286  						}
   287  					}()
   288  
   289  					if inserter {
   290  						var ins Inserter
   291  						ins.Add(l, ikey, makeValue(i))
   292  					} else {
   293  						l.Add(ikey, makeValue(i))
   294  					}
   295  				}(i)
   296  			}
   297  			// Wait until at least some write made it such that reads return a value.
   298  			<-writeDone
   299  			var sawValue atomic.Int32
   300  			for i := 0; i < n; i++ {
   301  				wg.Add(1)
   302  				go func() {
   303  					defer wg.Done()
   304  
   305  					it := newIterAdapter(l.NewIter(nil, nil))
   306  					it.SeekGE(key)
   307  					require.True(t, it.Valid())
   308  					require.True(t, bytes.Equal(key, it.Key()))
   309  
   310  					sawValue.Add(1)
   311  					v, err := strconv.Atoi(string(it.Value()[1:]))
   312  					require.NoError(t, err)
   313  					require.True(t, 0 <= v && v < n)
   314  				}()
   315  			}
   316  			wg.Wait()
   317  			require.Equal(t, int32(n), sawValue.Load())
   318  			require.Equal(t, 1, length(l))
   319  			require.Equal(t, 1, lengthRev(l))
   320  		})
   321  	}
   322  }
   323  
   324  func TestSkiplistAdd(t *testing.T) {
   325  	for _, inserter := range []bool{false, true} {
   326  		t.Run(fmt.Sprintf("inserter=%t", inserter), func(t *testing.T) {
   327  			l := NewSkiplist(newArena(arenaSize), bytes.Compare)
   328  			it := newIterAdapter(l.NewIter(nil, nil))
   329  
   330  			add := l.Add
   331  			if inserter {
   332  				add = makeInserterAdd(l)
   333  			}
   334  
   335  			// Add nil key and value (treated same as empty).
   336  			err := add([]byte{}, nil)
   337  			require.Nil(t, err)
   338  			require.True(t, it.SeekGE([]byte{}))
   339  			require.EqualValues(t, []byte{}, it.Key())
   340  			require.EqualValues(t, []byte{}, it.Value())
   341  
   342  			l = NewSkiplist(newArena(arenaSize), bytes.Compare)
   343  			it = newIterAdapter(l.NewIter(nil, nil))
   344  
   345  			add = l.Add
   346  			if inserter {
   347  				add = makeInserterAdd(l)
   348  			}
   349  
   350  			// Add empty key and value (treated same as nil).
   351  			err = add(makeIkey(""), []byte{})
   352  			require.Nil(t, err)
   353  			require.True(t, it.SeekGE([]byte{}))
   354  			require.EqualValues(t, []byte{}, it.Key())
   355  			require.EqualValues(t, []byte{}, it.Value())
   356  
   357  			// Add to empty list.
   358  			err = add(makeIntKey(2), makeValue(2))
   359  			require.Nil(t, err)
   360  			require.True(t, it.SeekGE(makeKey("00002")))
   361  			require.EqualValues(t, "00002", it.Key())
   362  			require.EqualValues(t, makeValue(2), it.Value())
   363  
   364  			// Add first element in non-empty list.
   365  			err = add(makeIntKey(1), makeValue(1))
   366  			require.Nil(t, err)
   367  			require.True(t, it.SeekGE(makeKey("00001")))
   368  			require.EqualValues(t, "00001", it.Key())
   369  			require.EqualValues(t, makeValue(1), it.Value())
   370  
   371  			// Add last element in non-empty list.
   372  			err = add(makeIntKey(4), makeValue(4))
   373  			require.Nil(t, err)
   374  			require.True(t, it.SeekGE(makeKey("00004")))
   375  			require.EqualValues(t, "00004", it.Key())
   376  			require.EqualValues(t, makeValue(4), it.Value())
   377  
   378  			// Add element in middle of list.
   379  			err = add(makeIntKey(3), makeValue(3))
   380  			require.Nil(t, err)
   381  			require.True(t, it.SeekGE(makeKey("00003")))
   382  			require.EqualValues(t, "00003", it.Key())
   383  			require.EqualValues(t, makeValue(3), it.Value())
   384  
   385  			// Try to add element that already exists.
   386  			err = add(makeIntKey(2), nil)
   387  			require.Equal(t, ErrRecordExists, err)
   388  			require.EqualValues(t, "00003", it.Key())
   389  			require.EqualValues(t, makeValue(3), it.Value())
   390  
   391  			require.Equal(t, 5, length(l))
   392  			require.Equal(t, 5, lengthRev(l))
   393  		})
   394  	}
   395  }
   396  
   397  // TestConcurrentAdd races between adding same nodes.
   398  func TestConcurrentAdd(t *testing.T) {
   399  	for _, inserter := range []bool{false, true} {
   400  		t.Run(fmt.Sprintf("inserter=%t", inserter), func(t *testing.T) {
   401  			const n = 100
   402  
   403  			// Set testing flag to make it easier to trigger unusual race conditions.
   404  			l := NewSkiplist(newArena(arenaSize), bytes.Compare)
   405  			l.testing = true
   406  
   407  			start := make([]sync.WaitGroup, n)
   408  			end := make([]sync.WaitGroup, n)
   409  
   410  			for i := 0; i < n; i++ {
   411  				start[i].Add(1)
   412  				end[i].Add(2)
   413  			}
   414  
   415  			for f := 0; f < 2; f++ {
   416  				go func(f int) {
   417  					it := newIterAdapter(l.NewIter(nil, nil))
   418  					add := l.Add
   419  					if inserter {
   420  						add = makeInserterAdd(l)
   421  					}
   422  
   423  					for i := 0; i < n; i++ {
   424  						start[i].Wait()
   425  
   426  						key := makeIntKey(i)
   427  						if add(key, nil) == nil {
   428  							require.True(t, it.SeekGE(key))
   429  							require.EqualValues(t, key, it.Key())
   430  						}
   431  
   432  						end[i].Done()
   433  					}
   434  				}(f)
   435  			}
   436  
   437  			for i := 0; i < n; i++ {
   438  				start[i].Done()
   439  				end[i].Wait()
   440  			}
   441  
   442  			require.Equal(t, n, length(l))
   443  			require.Equal(t, n, lengthRev(l))
   444  		})
   445  	}
   446  }
   447  
   448  // TestIteratorNext tests a basic iteration over all nodes from the beginning.
   449  func TestIteratorNext(t *testing.T) {
   450  	const n = 100
   451  	l := NewSkiplist(newArena(arenaSize), bytes.Compare)
   452  	it := newIterAdapter(l.NewIter(nil, nil))
   453  
   454  	require.False(t, it.Valid())
   455  
   456  	it.First()
   457  	require.False(t, it.Valid())
   458  
   459  	for i := n - 1; i >= 0; i-- {
   460  		l.Add(makeIntKey(i), makeValue(i))
   461  	}
   462  
   463  	it.First()
   464  	for i := 0; i < n; i++ {
   465  		require.True(t, it.Valid())
   466  		require.EqualValues(t, makeIntKey(i), it.Key())
   467  		require.EqualValues(t, makeValue(i), it.Value())
   468  		it.Next()
   469  	}
   470  	require.False(t, it.Valid())
   471  }
   472  
   473  // TestIteratorPrev tests a basic iteration over all nodes from the end.
   474  func TestIteratorPrev(t *testing.T) {
   475  	const n = 100
   476  	l := NewSkiplist(newArena(arenaSize), bytes.Compare)
   477  	it := newIterAdapter(l.NewIter(nil, nil))
   478  
   479  	require.False(t, it.Valid())
   480  
   481  	it.Last()
   482  	require.False(t, it.Valid())
   483  
   484  	var ins Inserter
   485  	for i := 0; i < n; i++ {
   486  		ins.Add(l, makeIntKey(i), makeValue(i))
   487  	}
   488  
   489  	it.Last()
   490  	for i := n - 1; i >= 0; i-- {
   491  		require.True(t, it.Valid())
   492  		require.EqualValues(t, makeIntKey(i), it.Key())
   493  		require.EqualValues(t, makeValue(i), it.Value())
   494  		it.Prev()
   495  	}
   496  	require.False(t, it.Valid())
   497  }
   498  
   499  func TestIteratorSeekGEAndSeekPrefixGE(t *testing.T) {
   500  	const n = 100
   501  	l := NewSkiplist(newArena(arenaSize), bytes.Compare)
   502  	it := newIterAdapter(l.NewIter(nil, nil))
   503  
   504  	require.False(t, it.Valid())
   505  	it.First()
   506  	require.False(t, it.Valid())
   507  	// 1000, 1010, 1020, ..., 1990.
   508  
   509  	var ins Inserter
   510  	for i := n - 1; i >= 0; i-- {
   511  		v := i*10 + 1000
   512  		ins.Add(l, makeIntKey(v), makeValue(v))
   513  	}
   514  
   515  	require.True(t, it.SeekGE(makeKey("")))
   516  	require.True(t, it.Valid())
   517  	require.EqualValues(t, "01000", it.Key())
   518  	require.EqualValues(t, "v01000", it.Value())
   519  
   520  	require.True(t, it.SeekGE(makeKey("01000")))
   521  	require.True(t, it.Valid())
   522  	require.EqualValues(t, "01000", it.Key())
   523  	require.EqualValues(t, "v01000", it.Value())
   524  
   525  	require.True(t, it.SeekGE(makeKey("01005")))
   526  	require.True(t, it.Valid())
   527  	require.EqualValues(t, "01010", it.Key())
   528  	require.EqualValues(t, "v01010", it.Value())
   529  
   530  	require.True(t, it.SeekGE(makeKey("01010")))
   531  	require.True(t, it.Valid())
   532  	require.EqualValues(t, "01010", it.Key())
   533  	require.EqualValues(t, "v01010", it.Value())
   534  
   535  	require.False(t, it.SeekGE(makeKey("99999")))
   536  	require.False(t, it.Valid())
   537  
   538  	// Test seek for empty key.
   539  	ins.Add(l, []byte{}, nil)
   540  	require.True(t, it.SeekGE([]byte{}))
   541  	require.True(t, it.Valid())
   542  	require.EqualValues(t, "", it.Key())
   543  
   544  	require.True(t, it.SeekGE(makeKey("")))
   545  	require.True(t, it.Valid())
   546  	require.EqualValues(t, "", it.Key())
   547  }
   548  
   549  func TestIteratorSeekLT(t *testing.T) {
   550  	const n = 100
   551  	l := NewSkiplist(newArena(arenaSize), bytes.Compare)
   552  	it := newIterAdapter(l.NewIter(nil, nil))
   553  
   554  	require.False(t, it.Valid())
   555  	it.First()
   556  	require.False(t, it.Valid())
   557  	// 1000, 1010, 1020, ..., 1990.
   558  	var ins Inserter
   559  	for i := n - 1; i >= 0; i-- {
   560  		v := i*10 + 1000
   561  		ins.Add(l, makeIntKey(v), makeValue(v))
   562  	}
   563  
   564  	require.False(t, it.SeekLT(makeKey("")))
   565  	require.False(t, it.Valid())
   566  
   567  	require.False(t, it.SeekLT(makeKey("01000")))
   568  	require.False(t, it.Valid())
   569  
   570  	require.True(t, it.SeekLT(makeKey("01001")))
   571  	require.True(t, it.Valid())
   572  	require.EqualValues(t, "01000", it.Key())
   573  	require.EqualValues(t, "v01000", it.Value())
   574  
   575  	require.True(t, it.SeekLT(makeKey("01005")))
   576  	require.True(t, it.Valid())
   577  	require.EqualValues(t, "01000", it.Key())
   578  	require.EqualValues(t, "v01000", it.Value())
   579  
   580  	require.True(t, it.SeekLT(makeKey("01991")))
   581  	require.True(t, it.Valid())
   582  	require.EqualValues(t, "01990", it.Key())
   583  	require.EqualValues(t, "v01990", it.Value())
   584  
   585  	require.True(t, it.SeekLT(makeKey("99999")))
   586  	require.True(t, it.Valid())
   587  	require.EqualValues(t, "01990", it.Key())
   588  	require.EqualValues(t, "v01990", it.Value())
   589  
   590  	// Test seek for empty key.
   591  	ins.Add(l, []byte{}, nil)
   592  	require.False(t, it.SeekLT([]byte{}))
   593  	require.False(t, it.Valid())
   594  
   595  	require.True(t, it.SeekLT(makeKey("\x01")))
   596  	require.True(t, it.Valid())
   597  	require.EqualValues(t, "", it.Key())
   598  }
   599  
   600  // TODO(peter): test First and Last.
   601  func TestIteratorBounds(t *testing.T) {
   602  	l := NewSkiplist(newArena(arenaSize), bytes.Compare)
   603  	for i := 1; i < 10; i++ {
   604  		require.NoError(t, l.Add(makeIntKey(i), makeValue(i)))
   605  	}
   606  
   607  	key := func(i int) []byte {
   608  		return makeIntKey(i)
   609  	}
   610  
   611  	it := newIterAdapter(l.NewIter(key(3), key(7)))
   612  
   613  	// SeekGE within the lower and upper bound succeeds.
   614  	for i := 3; i <= 6; i++ {
   615  		k := key(i)
   616  		require.True(t, it.SeekGE(k))
   617  		require.EqualValues(t, string(k), string(it.Key()))
   618  	}
   619  
   620  	// SeekGE before the lower bound still succeeds (only the upper bound is
   621  	// checked).
   622  	for i := 1; i < 3; i++ {
   623  		k := key(i)
   624  		require.True(t, it.SeekGE(k))
   625  		require.EqualValues(t, string(k), string(it.Key()))
   626  	}
   627  
   628  	// SeekGE beyond the upper bound fails.
   629  	for i := 7; i < 10; i++ {
   630  		require.False(t, it.SeekGE(key(i)))
   631  	}
   632  
   633  	require.True(t, it.SeekGE(key(6)))
   634  	require.EqualValues(t, "00006", it.Key())
   635  	require.EqualValues(t, "v00006", it.Value())
   636  
   637  	// Next into the upper bound fails.
   638  	require.False(t, it.Next())
   639  
   640  	// SeekLT within the lower and upper bound succeeds.
   641  	for i := 4; i <= 7; i++ {
   642  		require.True(t, it.SeekLT(key(i)))
   643  		require.EqualValues(t, string(key(i-1)), string(it.Key()))
   644  	}
   645  
   646  	// SeekLT beyond the upper bound still succeeds (only the lower bound is
   647  	// checked).
   648  	for i := 8; i < 9; i++ {
   649  		require.True(t, it.SeekLT(key(8)))
   650  		require.EqualValues(t, string(key(i-1)), string(it.Key()))
   651  	}
   652  
   653  	// SeekLT before the lower bound fails.
   654  	for i := 1; i < 4; i++ {
   655  		require.False(t, it.SeekLT(key(i)))
   656  	}
   657  
   658  	require.True(t, it.SeekLT(key(4)))
   659  	require.EqualValues(t, "00003", it.Key())
   660  	require.EqualValues(t, "v00003", it.Value())
   661  
   662  	// Prev into the lower bound fails.
   663  	require.False(t, it.Prev())
   664  }
   665  
   666  func randomKey(rng *rand.Rand, b []byte) []byte {
   667  	key := rng.Uint32()
   668  	key2 := rng.Uint32()
   669  	binary.LittleEndian.PutUint32(b, key)
   670  	binary.LittleEndian.PutUint32(b[4:], key2)
   671  	return b
   672  }
   673  
   674  // Standard test. Some fraction is read. Some fraction is write. Writes have
   675  // to go through mutex lock.
   676  func BenchmarkReadWrite(b *testing.B) {
   677  	for i := 0; i <= 10; i++ {
   678  		readFrac := float32(i) / 10.0
   679  		b.Run(fmt.Sprintf("frac_%d", i*10), func(b *testing.B) {
   680  			l := NewSkiplist(newArena(uint32((b.N+2)*maxNodeSize)), bytes.Compare)
   681  			b.ResetTimer()
   682  			var count int
   683  			b.RunParallel(func(pb *testing.PB) {
   684  				it := l.NewIter(nil, nil)
   685  				rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano())))
   686  				buf := make([]byte, 8)
   687  
   688  				for pb.Next() {
   689  					if rng.Float32() < readFrac {
   690  						ok, key, _ := it.SeekGE(randomKey(rng, buf))
   691  						if ok {
   692  							_ = key
   693  							count++
   694  						}
   695  					} else {
   696  						_ = l.Add(randomKey(rng, buf), nil)
   697  					}
   698  				}
   699  			})
   700  		})
   701  	}
   702  }
   703  
   704  func BenchmarkOrderedWrite(b *testing.B) {
   705  	l := NewSkiplist(newArena(8<<20), bytes.Compare)
   706  	var ins Inserter
   707  	buf := make([]byte, 8)
   708  
   709  	b.ResetTimer()
   710  	for i := 0; i < b.N; i++ {
   711  		binary.BigEndian.PutUint64(buf, uint64(i))
   712  		if err := ins.Add(l, buf, nil); err == ErrArenaFull {
   713  			b.StopTimer()
   714  			l = NewSkiplist(newArena(uint32((b.N+2)*maxNodeSize)), bytes.Compare)
   715  			ins = Inserter{}
   716  			b.StartTimer()
   717  		}
   718  	}
   719  }
   720  
   721  func BenchmarkIterNext(b *testing.B) {
   722  	l := NewSkiplist(newArena(64<<10), bytes.Compare)
   723  	rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano())))
   724  	buf := make([]byte, 8)
   725  	for {
   726  		if err := l.Add(randomKey(rng, buf), nil); err == ErrArenaFull {
   727  			break
   728  		}
   729  	}
   730  
   731  	it := l.NewIter(nil, nil)
   732  	b.ResetTimer()
   733  	for i := 0; i < b.N; i++ {
   734  		ok, key, _ := it.Next()
   735  		if !ok {
   736  			_, key, _ = it.First()
   737  		}
   738  		_ = key
   739  	}
   740  }
   741  
   742  func BenchmarkIterPrev(b *testing.B) {
   743  	l := NewSkiplist(newArena(64<<10), bytes.Compare)
   744  	rng := rand.New(rand.NewSource(uint64(time.Now().UnixNano())))
   745  	buf := make([]byte, 8)
   746  	for {
   747  		if err := l.Add(randomKey(rng, buf), nil); err == ErrArenaFull {
   748  			break
   749  		}
   750  	}
   751  
   752  	it := l.NewIter(nil, nil)
   753  	_, _, _ = it.Last()
   754  	b.ResetTimer()
   755  	for i := 0; i < b.N; i++ {
   756  		ok, key, _ := it.Prev()
   757  		if !ok {
   758  			_, key, _ = it.Last()
   759  		}
   760  		_ = key
   761  	}
   762  }
   763  
   764  // BenchmarkSeekPrefixGE looks at the performance of repeated calls to
   765  // SeekPrefixGE, with different skip distances and different settings of
   766  // trySeekUsingNext.
   767  func BenchmarkSeekPrefixGE(b *testing.B) {
   768  	l := NewSkiplist(newArena(64<<10), bytes.Compare)
   769  	var count int
   770  	// count was measured to be 1279.
   771  	for count = 0; ; count++ {
   772  		if err := l.Add(makeIntKey(count), makeValue(count)); err == ErrArenaFull {
   773  			break
   774  		}
   775  	}
   776  	for _, skip := range []int{1, 2, 4, 8, 16} {
   777  		for _, useNext := range []bool{false} {
   778  			b.Run(fmt.Sprintf("skip=%d/use-next=%t", skip, useNext), func(b *testing.B) {
   779  				it := l.NewIter(nil, nil)
   780  				j := 0
   781  				var k []byte
   782  				makeKey := func() {
   783  					k = []byte(fmt.Sprintf("%05d", j))
   784  				}
   785  				makeKey()
   786  				it.SeekPrefixGE(k, k)
   787  				b.ResetTimer()
   788  				for i := 0; i < b.N; i++ {
   789  					j += skip
   790  					if j >= count {
   791  						j = 0
   792  					}
   793  					makeKey()
   794  					it.SeekPrefixGE(k, k)
   795  				}
   796  			})
   797  		}
   798  	}
   799  }