github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/database/internal/treap/treapiter_test.go (about)

     1  // Copyright (c) 2015-2016 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package treap
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/binary"
    11  	"testing"
    12  )
    13  
    14  // TestMutableIterator ensures that the general behavior of mutable treap
    15  // iterators is as expected including tests for first, last, ordered and reverse
    16  // ordered iteration, limiting the range, seeking, and initially unpositioned.
    17  func TestMutableIterator(t *testing.T) {
    18  	t.Parallel()
    19  
    20  	tests := []struct {
    21  		numKeys       int
    22  		step          int
    23  		startKey      []byte
    24  		limitKey      []byte
    25  		expectedFirst []byte
    26  		expectedLast  []byte
    27  		seekKey       []byte
    28  		expectedSeek  []byte
    29  	}{
    30  		// No range limits.  Values are the set (0, 1, 2, ..., 49).
    31  		// Seek existing value.
    32  		{
    33  			numKeys:       50,
    34  			step:          1,
    35  			expectedFirst: serializeUint32(0),
    36  			expectedLast:  serializeUint32(49),
    37  			seekKey:       serializeUint32(12),
    38  			expectedSeek:  serializeUint32(12),
    39  		},
    40  
    41  		// Limited to range [24, end].  Values are the set
    42  		// (0, 2, 4, ..., 48).  Seek value that doesn't exist and is
    43  		// greater than largest existing key.
    44  		{
    45  			numKeys:       50,
    46  			step:          2,
    47  			startKey:      serializeUint32(24),
    48  			expectedFirst: serializeUint32(24),
    49  			expectedLast:  serializeUint32(48),
    50  			seekKey:       serializeUint32(49),
    51  			expectedSeek:  nil,
    52  		},
    53  
    54  		// Limited to range [start, 25).  Values are the set
    55  		// (0, 3, 6, ..., 48).  Seek value that doesn't exist but is
    56  		// before an existing value within the range.
    57  		{
    58  			numKeys:       50,
    59  			step:          3,
    60  			limitKey:      serializeUint32(25),
    61  			expectedFirst: serializeUint32(0),
    62  			expectedLast:  serializeUint32(24),
    63  			seekKey:       serializeUint32(17),
    64  			expectedSeek:  serializeUint32(18),
    65  		},
    66  
    67  		// Limited to range [10, 21).  Values are the set
    68  		// (0, 4, ..., 48).  Seek value that exists, but is before the
    69  		// minimum allowed range.
    70  		{
    71  			numKeys:       50,
    72  			step:          4,
    73  			startKey:      serializeUint32(10),
    74  			limitKey:      serializeUint32(21),
    75  			expectedFirst: serializeUint32(12),
    76  			expectedLast:  serializeUint32(20),
    77  			seekKey:       serializeUint32(4),
    78  			expectedSeek:  nil,
    79  		},
    80  
    81  		// Limited by prefix {0,0,0}, range [{0,0,0}, {0,0,1}).
    82  		// Since it's a bytewise compare,  {0,0,0,...} < {0,0,1}.
    83  		// Seek existing value within the allowed range.
    84  		{
    85  			numKeys:       300,
    86  			step:          1,
    87  			startKey:      []byte{0x00, 0x00, 0x00},
    88  			limitKey:      []byte{0x00, 0x00, 0x01},
    89  			expectedFirst: serializeUint32(0),
    90  			expectedLast:  serializeUint32(255),
    91  			seekKey:       serializeUint32(100),
    92  			expectedSeek:  serializeUint32(100),
    93  		},
    94  	}
    95  
    96  testLoop:
    97  	for i, test := range tests {
    98  		// Insert a bunch of keys.
    99  		testTreap := NewMutable()
   100  		for i := 0; i < test.numKeys; i += test.step {
   101  			key := serializeUint32(uint32(i))
   102  			testTreap.Put(key, key)
   103  		}
   104  
   105  		// Create new iterator limited by the test params.
   106  		iter := testTreap.Iterator(test.startKey, test.limitKey)
   107  
   108  		// Ensure the first item is accurate.
   109  		hasFirst := iter.First()
   110  		if !hasFirst && test.expectedFirst != nil {
   111  			t.Errorf("First #%d: unexpected exhausted iterator", i)
   112  			continue
   113  		}
   114  		gotKey := iter.Key()
   115  		if !bytes.Equal(gotKey, test.expectedFirst) {
   116  			t.Errorf("First.Key #%d: unexpected key - got %x, "+
   117  				"want %x", i, gotKey, test.expectedFirst)
   118  			continue
   119  		}
   120  		gotVal := iter.Value()
   121  		if !bytes.Equal(gotVal, test.expectedFirst) {
   122  			t.Errorf("First.Value #%d: unexpected value - got %x, "+
   123  				"want %x", i, gotVal, test.expectedFirst)
   124  			continue
   125  		}
   126  
   127  		// Ensure the iterator gives the expected items in order.
   128  		curNum := binary.BigEndian.Uint32(test.expectedFirst)
   129  		for iter.Next() {
   130  			curNum += uint32(test.step)
   131  
   132  			// Ensure key is as expected.
   133  			gotKey := iter.Key()
   134  			expectedKey := serializeUint32(curNum)
   135  			if !bytes.Equal(gotKey, expectedKey) {
   136  				t.Errorf("iter.Key #%d (%d): unexpected key - "+
   137  					"got %x, want %x", i, curNum, gotKey,
   138  					expectedKey)
   139  				continue testLoop
   140  			}
   141  
   142  			// Ensure value is as expected.
   143  			gotVal := iter.Value()
   144  			if !bytes.Equal(gotVal, expectedKey) {
   145  				t.Errorf("iter.Value #%d (%d): unexpected "+
   146  					"value - got %x, want %x", i, curNum,
   147  					gotVal, expectedKey)
   148  				continue testLoop
   149  			}
   150  		}
   151  
   152  		// Ensure iterator is exhausted.
   153  		if iter.Valid() {
   154  			t.Errorf("Valid #%d: iterator should be exhausted", i)
   155  			continue
   156  		}
   157  
   158  		// Ensure the last item is accurate.
   159  		hasLast := iter.Last()
   160  		if !hasLast && test.expectedLast != nil {
   161  			t.Errorf("Last #%d: unexpected exhausted iterator", i)
   162  			continue
   163  		}
   164  		gotKey = iter.Key()
   165  		if !bytes.Equal(gotKey, test.expectedLast) {
   166  			t.Errorf("Last.Key #%d: unexpected key - got %x, "+
   167  				"want %x", i, gotKey, test.expectedLast)
   168  			continue
   169  		}
   170  		gotVal = iter.Value()
   171  		if !bytes.Equal(gotVal, test.expectedLast) {
   172  			t.Errorf("Last.Value #%d: unexpected value - got %x, "+
   173  				"want %x", i, gotVal, test.expectedLast)
   174  			continue
   175  		}
   176  
   177  		// Ensure the iterator gives the expected items in reverse
   178  		// order.
   179  		curNum = binary.BigEndian.Uint32(test.expectedLast)
   180  		for iter.Prev() {
   181  			curNum -= uint32(test.step)
   182  
   183  			// Ensure key is as expected.
   184  			gotKey := iter.Key()
   185  			expectedKey := serializeUint32(curNum)
   186  			if !bytes.Equal(gotKey, expectedKey) {
   187  				t.Errorf("iter.Key #%d (%d): unexpected key - "+
   188  					"got %x, want %x", i, curNum, gotKey,
   189  					expectedKey)
   190  				continue testLoop
   191  			}
   192  
   193  			// Ensure value is as expected.
   194  			gotVal := iter.Value()
   195  			if !bytes.Equal(gotVal, expectedKey) {
   196  				t.Errorf("iter.Value #%d (%d): unexpected "+
   197  					"value - got %x, want %x", i, curNum,
   198  					gotVal, expectedKey)
   199  				continue testLoop
   200  			}
   201  		}
   202  
   203  		// Ensure iterator is exhausted.
   204  		if iter.Valid() {
   205  			t.Errorf("Valid #%d: iterator should be exhausted", i)
   206  			continue
   207  		}
   208  
   209  		// Seek to the provided key.
   210  		seekValid := iter.Seek(test.seekKey)
   211  		if !seekValid && test.expectedSeek != nil {
   212  			t.Errorf("Seek #%d: unexpected exhausted iterator", i)
   213  			continue
   214  		}
   215  		gotKey = iter.Key()
   216  		if !bytes.Equal(gotKey, test.expectedSeek) {
   217  			t.Errorf("Seek.Key #%d: unexpected key - got %x, "+
   218  				"want %x", i, gotKey, test.expectedSeek)
   219  			continue
   220  		}
   221  		gotVal = iter.Value()
   222  		if !bytes.Equal(gotVal, test.expectedSeek) {
   223  			t.Errorf("Seek.Value #%d: unexpected value - got %x, "+
   224  				"want %x", i, gotVal, test.expectedSeek)
   225  			continue
   226  		}
   227  
   228  		// Recreate the iterator and ensure calling Next on it before it
   229  		// has been positioned gives the first element.
   230  		iter = testTreap.Iterator(test.startKey, test.limitKey)
   231  		hasNext := iter.Next()
   232  		if !hasNext && test.expectedFirst != nil {
   233  			t.Errorf("Next #%d: unexpected exhausted iterator", i)
   234  			continue
   235  		}
   236  		gotKey = iter.Key()
   237  		if !bytes.Equal(gotKey, test.expectedFirst) {
   238  			t.Errorf("Next.Key #%d: unexpected key - got %x, "+
   239  				"want %x", i, gotKey, test.expectedFirst)
   240  			continue
   241  		}
   242  		gotVal = iter.Value()
   243  		if !bytes.Equal(gotVal, test.expectedFirst) {
   244  			t.Errorf("Next.Value #%d: unexpected value - got %x, "+
   245  				"want %x", i, gotVal, test.expectedFirst)
   246  			continue
   247  		}
   248  
   249  		// Recreate the iterator and ensure calling Prev on it before it
   250  		// has been positioned gives the first element.
   251  		iter = testTreap.Iterator(test.startKey, test.limitKey)
   252  		hasPrev := iter.Prev()
   253  		if !hasPrev && test.expectedLast != nil {
   254  			t.Errorf("Prev #%d: unexpected exhausted iterator", i)
   255  			continue
   256  		}
   257  		gotKey = iter.Key()
   258  		if !bytes.Equal(gotKey, test.expectedLast) {
   259  			t.Errorf("Prev.Key #%d: unexpected key - got %x, "+
   260  				"want %x", i, gotKey, test.expectedLast)
   261  			continue
   262  		}
   263  		gotVal = iter.Value()
   264  		if !bytes.Equal(gotVal, test.expectedLast) {
   265  			t.Errorf("Next.Value #%d: unexpected value - got %x, "+
   266  				"want %x", i, gotVal, test.expectedLast)
   267  			continue
   268  		}
   269  	}
   270  }
   271  
   272  // TestMutableEmptyIterator ensures that the various functions behave as
   273  // expected when a mutable treap is empty.
   274  func TestMutableEmptyIterator(t *testing.T) {
   275  	t.Parallel()
   276  
   277  	// Create iterator against empty treap.
   278  	testTreap := NewMutable()
   279  	iter := testTreap.Iterator(nil, nil)
   280  
   281  	// Ensure Valid on empty iterator reports it as exhausted.
   282  	if iter.Valid() {
   283  		t.Fatal("Valid: iterator should be exhausted")
   284  	}
   285  
   286  	// Ensure First and Last on empty iterator report it as exhausted.
   287  	if iter.First() {
   288  		t.Fatal("First: iterator should be exhausted")
   289  	}
   290  	if iter.Last() {
   291  		t.Fatal("Last: iterator should be exhausted")
   292  	}
   293  
   294  	// Ensure Next and Prev on empty iterator report it as exhausted.
   295  	if iter.Next() {
   296  		t.Fatal("Next: iterator should be exhausted")
   297  	}
   298  	if iter.Prev() {
   299  		t.Fatal("Prev: iterator should be exhausted")
   300  	}
   301  
   302  	// Ensure Key and Value on empty iterator are nil.
   303  	if gotKey := iter.Key(); gotKey != nil {
   304  		t.Fatalf("Key: should be nil - got %q", gotKey)
   305  	}
   306  	if gotVal := iter.Value(); gotVal != nil {
   307  		t.Fatalf("Value: should be nil - got %q", gotVal)
   308  	}
   309  
   310  	// Ensure Next and Prev report exhausted after forcing a reseek on an
   311  	// empty iterator.
   312  	iter.ForceReseek()
   313  	if iter.Next() {
   314  		t.Fatal("Next: iterator should be exhausted")
   315  	}
   316  	iter.ForceReseek()
   317  	if iter.Prev() {
   318  		t.Fatal("Prev: iterator should be exhausted")
   319  	}
   320  }
   321  
   322  // TestIteratorUpdates ensures that issuing a call to ForceReseek on an iterator
   323  // that had the underlying mutable treap updated works as expected.
   324  func TestIteratorUpdates(t *testing.T) {
   325  	t.Parallel()
   326  
   327  	// Create a new treap with various values inserted in no particular
   328  	// order.  The resulting keys are the set (2, 4, 7, 11, 18, 25).
   329  	testTreap := NewMutable()
   330  	testTreap.Put(serializeUint32(7), nil)
   331  	testTreap.Put(serializeUint32(2), nil)
   332  	testTreap.Put(serializeUint32(18), nil)
   333  	testTreap.Put(serializeUint32(11), nil)
   334  	testTreap.Put(serializeUint32(25), nil)
   335  	testTreap.Put(serializeUint32(4), nil)
   336  
   337  	// Create an iterator against the treap with a range that excludes the
   338  	// lowest and highest entries.  The limited set is then (4, 7, 11, 18)
   339  	iter := testTreap.Iterator(serializeUint32(3), serializeUint32(25))
   340  
   341  	// Delete a key from the middle of the range and notify the iterator to
   342  	// force a reseek.
   343  	testTreap.Delete(serializeUint32(11))
   344  	iter.ForceReseek()
   345  
   346  	// Ensure that calling Next on the iterator after the forced reseek
   347  	// gives the expected key.  The limited set of keys at this point is
   348  	// (4, 7, 18) and the iterator has not yet been positioned.
   349  	if !iter.Next() {
   350  		t.Fatal("ForceReseek.Next: unexpected exhausted iterator")
   351  	}
   352  	wantKey := serializeUint32(4)
   353  	gotKey := iter.Key()
   354  	if !bytes.Equal(gotKey, wantKey) {
   355  		t.Fatalf("ForceReseek.Key: unexpected key - got %x, want %x",
   356  			gotKey, wantKey)
   357  	}
   358  
   359  	// Delete the key the iterator is currently position at and notify the
   360  	// iterator to force a reseek.
   361  	testTreap.Delete(serializeUint32(4))
   362  	iter.ForceReseek()
   363  
   364  	// Ensure that calling Next on the iterator after the forced reseek
   365  	// gives the expected key.  The limited set of keys at this point is
   366  	// (7, 18) and the iterator is positioned at a deleted entry before 7.
   367  	if !iter.Next() {
   368  		t.Fatal("ForceReseek.Next: unexpected exhausted iterator")
   369  	}
   370  	wantKey = serializeUint32(7)
   371  	gotKey = iter.Key()
   372  	if !bytes.Equal(gotKey, wantKey) {
   373  		t.Fatalf("ForceReseek.Key: unexpected key - got %x, want %x",
   374  			gotKey, wantKey)
   375  	}
   376  
   377  	// Add a key before the current key the iterator is position at and
   378  	// notify the iterator to force a reseek.
   379  	testTreap.Put(serializeUint32(4), nil)
   380  	iter.ForceReseek()
   381  
   382  	// Ensure that calling Prev on the iterator after the forced reseek
   383  	// gives the expected key.  The limited set of keys at this point is
   384  	// (4, 7, 18) and the iterator is positioned at 7.
   385  	if !iter.Prev() {
   386  		t.Fatal("ForceReseek.Prev: unexpected exhausted iterator")
   387  	}
   388  	wantKey = serializeUint32(4)
   389  	gotKey = iter.Key()
   390  	if !bytes.Equal(gotKey, wantKey) {
   391  		t.Fatalf("ForceReseek.Key: unexpected key - got %x, want %x",
   392  			gotKey, wantKey)
   393  	}
   394  
   395  	// Delete the next key the iterator would ordinarily move to then notify
   396  	// the iterator to force a reseek.
   397  	testTreap.Delete(serializeUint32(7))
   398  	iter.ForceReseek()
   399  
   400  	// Ensure that calling Next on the iterator after the forced reseek
   401  	// gives the expected key.  The limited set of keys at this point is
   402  	// (4, 18) and the iterator is positioned at 4.
   403  	if !iter.Next() {
   404  		t.Fatal("ForceReseek.Next: unexpected exhausted iterator")
   405  	}
   406  	wantKey = serializeUint32(18)
   407  	gotKey = iter.Key()
   408  	if !bytes.Equal(gotKey, wantKey) {
   409  		t.Fatalf("ForceReseek.Key: unexpected key - got %x, want %x",
   410  			gotKey, wantKey)
   411  	}
   412  }
   413  
   414  // TestImmutableIterator ensures that the general behavior of immutable treap
   415  // iterators is as expected including tests for first, last, ordered and reverse
   416  // ordered iteration, limiting the range, seeking, and initially unpositioned.
   417  func TestImmutableIterator(t *testing.T) {
   418  	t.Parallel()
   419  
   420  	tests := []struct {
   421  		numKeys       int
   422  		step          int
   423  		startKey      []byte
   424  		limitKey      []byte
   425  		expectedFirst []byte
   426  		expectedLast  []byte
   427  		seekKey       []byte
   428  		expectedSeek  []byte
   429  	}{
   430  		// No range limits.  Values are the set (0, 1, 2, ..., 49).
   431  		// Seek existing value.
   432  		{
   433  			numKeys:       50,
   434  			step:          1,
   435  			expectedFirst: serializeUint32(0),
   436  			expectedLast:  serializeUint32(49),
   437  			seekKey:       serializeUint32(12),
   438  			expectedSeek:  serializeUint32(12),
   439  		},
   440  
   441  		// Limited to range [24, end].  Values are the set
   442  		// (0, 2, 4, ..., 48).  Seek value that doesn't exist and is
   443  		// greater than largest existing key.
   444  		{
   445  			numKeys:       50,
   446  			step:          2,
   447  			startKey:      serializeUint32(24),
   448  			expectedFirst: serializeUint32(24),
   449  			expectedLast:  serializeUint32(48),
   450  			seekKey:       serializeUint32(49),
   451  			expectedSeek:  nil,
   452  		},
   453  
   454  		// Limited to range [start, 25).  Values are the set
   455  		// (0, 3, 6, ..., 48).  Seek value that doesn't exist but is
   456  		// before an existing value within the range.
   457  		{
   458  			numKeys:       50,
   459  			step:          3,
   460  			limitKey:      serializeUint32(25),
   461  			expectedFirst: serializeUint32(0),
   462  			expectedLast:  serializeUint32(24),
   463  			seekKey:       serializeUint32(17),
   464  			expectedSeek:  serializeUint32(18),
   465  		},
   466  
   467  		// Limited to range [10, 21).  Values are the set
   468  		// (0, 4, ..., 48).  Seek value that exists, but is before the
   469  		// minimum allowed range.
   470  		{
   471  			numKeys:       50,
   472  			step:          4,
   473  			startKey:      serializeUint32(10),
   474  			limitKey:      serializeUint32(21),
   475  			expectedFirst: serializeUint32(12),
   476  			expectedLast:  serializeUint32(20),
   477  			seekKey:       serializeUint32(4),
   478  			expectedSeek:  nil,
   479  		},
   480  
   481  		// Limited by prefix {0,0,0}, range [{0,0,0}, {0,0,1}).
   482  		// Since it's a bytewise compare,  {0,0,0,...} < {0,0,1}.
   483  		// Seek existing value within the allowed range.
   484  		{
   485  			numKeys:       300,
   486  			step:          1,
   487  			startKey:      []byte{0x00, 0x00, 0x00},
   488  			limitKey:      []byte{0x00, 0x00, 0x01},
   489  			expectedFirst: serializeUint32(0),
   490  			expectedLast:  serializeUint32(255),
   491  			seekKey:       serializeUint32(100),
   492  			expectedSeek:  serializeUint32(100),
   493  		},
   494  	}
   495  
   496  testLoop:
   497  	for i, test := range tests {
   498  		// Insert a bunch of keys.
   499  		testTreap := NewImmutable()
   500  		for i := 0; i < test.numKeys; i += test.step {
   501  			key := serializeUint32(uint32(i))
   502  			testTreap = testTreap.Put(key, key)
   503  		}
   504  
   505  		// Create new iterator limited by the test params.
   506  		iter := testTreap.Iterator(test.startKey, test.limitKey)
   507  
   508  		// Ensure the first item is accurate.
   509  		hasFirst := iter.First()
   510  		if !hasFirst && test.expectedFirst != nil {
   511  			t.Errorf("First #%d: unexpected exhausted iterator", i)
   512  			continue
   513  		}
   514  		gotKey := iter.Key()
   515  		if !bytes.Equal(gotKey, test.expectedFirst) {
   516  			t.Errorf("First.Key #%d: unexpected key - got %x, "+
   517  				"want %x", i, gotKey, test.expectedFirst)
   518  			continue
   519  		}
   520  		gotVal := iter.Value()
   521  		if !bytes.Equal(gotVal, test.expectedFirst) {
   522  			t.Errorf("First.Value #%d: unexpected value - got %x, "+
   523  				"want %x", i, gotVal, test.expectedFirst)
   524  			continue
   525  		}
   526  
   527  		// Ensure the iterator gives the expected items in order.
   528  		curNum := binary.BigEndian.Uint32(test.expectedFirst)
   529  		for iter.Next() {
   530  			curNum += uint32(test.step)
   531  
   532  			// Ensure key is as expected.
   533  			gotKey := iter.Key()
   534  			expectedKey := serializeUint32(curNum)
   535  			if !bytes.Equal(gotKey, expectedKey) {
   536  				t.Errorf("iter.Key #%d (%d): unexpected key - "+
   537  					"got %x, want %x", i, curNum, gotKey,
   538  					expectedKey)
   539  				continue testLoop
   540  			}
   541  
   542  			// Ensure value is as expected.
   543  			gotVal := iter.Value()
   544  			if !bytes.Equal(gotVal, expectedKey) {
   545  				t.Errorf("iter.Value #%d (%d): unexpected "+
   546  					"value - got %x, want %x", i, curNum,
   547  					gotVal, expectedKey)
   548  				continue testLoop
   549  			}
   550  		}
   551  
   552  		// Ensure iterator is exhausted.
   553  		if iter.Valid() {
   554  			t.Errorf("Valid #%d: iterator should be exhausted", i)
   555  			continue
   556  		}
   557  
   558  		// Ensure the last item is accurate.
   559  		hasLast := iter.Last()
   560  		if !hasLast && test.expectedLast != nil {
   561  			t.Errorf("Last #%d: unexpected exhausted iterator", i)
   562  			continue
   563  		}
   564  		gotKey = iter.Key()
   565  		if !bytes.Equal(gotKey, test.expectedLast) {
   566  			t.Errorf("Last.Key #%d: unexpected key - got %x, "+
   567  				"want %x", i, gotKey, test.expectedLast)
   568  			continue
   569  		}
   570  		gotVal = iter.Value()
   571  		if !bytes.Equal(gotVal, test.expectedLast) {
   572  			t.Errorf("Last.Value #%d: unexpected value - got %x, "+
   573  				"want %x", i, gotVal, test.expectedLast)
   574  			continue
   575  		}
   576  
   577  		// Ensure the iterator gives the expected items in reverse
   578  		// order.
   579  		curNum = binary.BigEndian.Uint32(test.expectedLast)
   580  		for iter.Prev() {
   581  			curNum -= uint32(test.step)
   582  
   583  			// Ensure key is as expected.
   584  			gotKey := iter.Key()
   585  			expectedKey := serializeUint32(curNum)
   586  			if !bytes.Equal(gotKey, expectedKey) {
   587  				t.Errorf("iter.Key #%d (%d): unexpected key - "+
   588  					"got %x, want %x", i, curNum, gotKey,
   589  					expectedKey)
   590  				continue testLoop
   591  			}
   592  
   593  			// Ensure value is as expected.
   594  			gotVal := iter.Value()
   595  			if !bytes.Equal(gotVal, expectedKey) {
   596  				t.Errorf("iter.Value #%d (%d): unexpected "+
   597  					"value - got %x, want %x", i, curNum,
   598  					gotVal, expectedKey)
   599  				continue testLoop
   600  			}
   601  		}
   602  
   603  		// Ensure iterator is exhausted.
   604  		if iter.Valid() {
   605  			t.Errorf("Valid #%d: iterator should be exhausted", i)
   606  			continue
   607  		}
   608  
   609  		// Seek to the provided key.
   610  		seekValid := iter.Seek(test.seekKey)
   611  		if !seekValid && test.expectedSeek != nil {
   612  			t.Errorf("Seek #%d: unexpected exhausted iterator", i)
   613  			continue
   614  		}
   615  		gotKey = iter.Key()
   616  		if !bytes.Equal(gotKey, test.expectedSeek) {
   617  			t.Errorf("Seek.Key #%d: unexpected key - got %x, "+
   618  				"want %x", i, gotKey, test.expectedSeek)
   619  			continue
   620  		}
   621  		gotVal = iter.Value()
   622  		if !bytes.Equal(gotVal, test.expectedSeek) {
   623  			t.Errorf("Seek.Value #%d: unexpected value - got %x, "+
   624  				"want %x", i, gotVal, test.expectedSeek)
   625  			continue
   626  		}
   627  
   628  		// Recreate the iterator and ensure calling Next on it before it
   629  		// has been positioned gives the first element.
   630  		iter = testTreap.Iterator(test.startKey, test.limitKey)
   631  		hasNext := iter.Next()
   632  		if !hasNext && test.expectedFirst != nil {
   633  			t.Errorf("Next #%d: unexpected exhausted iterator", i)
   634  			continue
   635  		}
   636  		gotKey = iter.Key()
   637  		if !bytes.Equal(gotKey, test.expectedFirst) {
   638  			t.Errorf("Next.Key #%d: unexpected key - got %x, "+
   639  				"want %x", i, gotKey, test.expectedFirst)
   640  			continue
   641  		}
   642  		gotVal = iter.Value()
   643  		if !bytes.Equal(gotVal, test.expectedFirst) {
   644  			t.Errorf("Next.Value #%d: unexpected value - got %x, "+
   645  				"want %x", i, gotVal, test.expectedFirst)
   646  			continue
   647  		}
   648  
   649  		// Recreate the iterator and ensure calling Prev on it before it
   650  		// has been positioned gives the first element.
   651  		iter = testTreap.Iterator(test.startKey, test.limitKey)
   652  		hasPrev := iter.Prev()
   653  		if !hasPrev && test.expectedLast != nil {
   654  			t.Errorf("Prev #%d: unexpected exhausted iterator", i)
   655  			continue
   656  		}
   657  		gotKey = iter.Key()
   658  		if !bytes.Equal(gotKey, test.expectedLast) {
   659  			t.Errorf("Prev.Key #%d: unexpected key - got %x, "+
   660  				"want %x", i, gotKey, test.expectedLast)
   661  			continue
   662  		}
   663  		gotVal = iter.Value()
   664  		if !bytes.Equal(gotVal, test.expectedLast) {
   665  			t.Errorf("Next.Value #%d: unexpected value - got %x, "+
   666  				"want %x", i, gotVal, test.expectedLast)
   667  			continue
   668  		}
   669  	}
   670  }
   671  
   672  // TestImmutableEmptyIterator ensures that the various functions behave as
   673  // expected when an immutable treap is empty.
   674  func TestImmutableEmptyIterator(t *testing.T) {
   675  	t.Parallel()
   676  
   677  	// Create iterator against empty treap.
   678  	testTreap := NewImmutable()
   679  	iter := testTreap.Iterator(nil, nil)
   680  
   681  	// Ensure Valid on empty iterator reports it as exhausted.
   682  	if iter.Valid() {
   683  		t.Fatal("Valid: iterator should be exhausted")
   684  	}
   685  
   686  	// Ensure First and Last on empty iterator report it as exhausted.
   687  	if iter.First() {
   688  		t.Fatal("First: iterator should be exhausted")
   689  	}
   690  	if iter.Last() {
   691  		t.Fatal("Last: iterator should be exhausted")
   692  	}
   693  
   694  	// Ensure Next and Prev on empty iterator report it as exhausted.
   695  	if iter.Next() {
   696  		t.Fatal("Next: iterator should be exhausted")
   697  	}
   698  	if iter.Prev() {
   699  		t.Fatal("Prev: iterator should be exhausted")
   700  	}
   701  
   702  	// Ensure Key and Value on empty iterator are nil.
   703  	if gotKey := iter.Key(); gotKey != nil {
   704  		t.Fatalf("Key: should be nil - got %q", gotKey)
   705  	}
   706  	if gotVal := iter.Value(); gotVal != nil {
   707  		t.Fatalf("Value: should be nil - got %q", gotVal)
   708  	}
   709  
   710  	// Ensure calling ForceReseek on an immutable treap iterator does not
   711  	// cause any issues since it only applies to mutable treap iterators.
   712  	iter.ForceReseek()
   713  	if iter.Next() {
   714  		t.Fatal("Next: iterator should be exhausted")
   715  	}
   716  	iter.ForceReseek()
   717  	if iter.Prev() {
   718  		t.Fatal("Prev: iterator should be exhausted")
   719  	}
   720  }