github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/internal/base/internal_test.go (about)

     1  // Copyright 2012 The LevelDB-Go and Pebble Authors. All rights reserved. Use
     2  // of this source code is governed by a BSD-style license that can be found in
     3  // the LICENSE file.
     4  
     5  package base
     6  
     7  import (
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func (k InternalKey) encodedString() string {
    14  	buf := make([]byte, k.Size())
    15  	k.Encode(buf)
    16  	return string(buf)
    17  }
    18  
    19  func TestInternalKey(t *testing.T) {
    20  	k := MakeInternalKey([]byte("foo"), 0x08070605040302, 1)
    21  	if got, want := k.encodedString(), "foo\x01\x02\x03\x04\x05\x06\x07\x08"; got != want {
    22  		t.Fatalf("k = %q want %q", got, want)
    23  	}
    24  	if !k.Valid() {
    25  		t.Fatalf("invalid key")
    26  	}
    27  	if got, want := string(k.UserKey), "foo"; got != want {
    28  		t.Errorf("ukey = %q want %q", got, want)
    29  	}
    30  	if got, want := k.Kind(), InternalKeyKind(1); got != want {
    31  		t.Errorf("kind = %d want %d", got, want)
    32  	}
    33  	if got, want := k.SeqNum(), uint64(0x08070605040302); got != want {
    34  		t.Errorf("seqNum = %d want %d", got, want)
    35  	}
    36  }
    37  
    38  func TestInvalidInternalKey(t *testing.T) {
    39  	testCases := []string{
    40  		"",
    41  		"\x01\x02\x03\x04\x05\x06\x07",
    42  		"foo",
    43  		"foo\x08\x07\x06\x05\x04\x03\x02",
    44  		"foo\x18\x07\x06\x05\x04\x03\x02\x01",
    45  	}
    46  	for _, tc := range testCases {
    47  		k := DecodeInternalKey([]byte(tc))
    48  		if k.Valid() {
    49  			t.Errorf("%q is a valid key, want invalid", tc)
    50  		}
    51  		// Invalid key kind because the key doesn't have an 8 byte trailer.
    52  		if k.Kind() == InternalKeyKindInvalid && k.UserKey != nil {
    53  			t.Errorf("expected nil UserKey after decoding encodedKey=%q", tc)
    54  		}
    55  	}
    56  }
    57  
    58  func TestInternalKeyComparer(t *testing.T) {
    59  	// keys are some internal keys, in sorted order.
    60  	keys := []string{
    61  		// The remaining test keys are all valid.
    62  		"" + "\x01\xff\xff\xff\xff\xff\xff\xff",
    63  		"" + "\x00\xff\xff\xff\xff\xff\xff\xff",
    64  		"" + "\x01\x01\x00\x00\x00\x00\x00\x00",
    65  		"" + "\x00\x01\x00\x00\x00\x00\x00\x00",
    66  		// Invalid internal keys have no user key, but have trailer "\xff \x00 \x00 \x00 \x00 \x00 \x00 \x00"
    67  		// i.e. seqNum 0 and kind 255 (InternalKeyKindInvalid).
    68  		"",
    69  		"" + "\x01\x00\x00\x00\x00\x00\x00\x00",
    70  		"" + "\x00\x00\x00\x00\x00\x00\x00\x00",
    71  		"\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00",
    72  		"\x00blue" + "\x01\x11\x00\x00\x00\x00\x00\x00",
    73  		"bl\x00ue" + "\x01\x11\x00\x00\x00\x00\x00\x00",
    74  		"blue" + "\x01\x11\x00\x00\x00\x00\x00\x00",
    75  		"blue\x00" + "\x01\x11\x00\x00\x00\x00\x00\x00",
    76  		"green" + "\xff\x11\x00\x00\x00\x00\x00\x00",
    77  		"green" + "\x01\x11\x00\x00\x00\x00\x00\x00",
    78  		"green" + "\x01\x00\x00\x00\x00\x00\x00\x00",
    79  		"red" + "\x01\xff\xff\xff\xff\xff\xff\xff",
    80  		"red" + "\x01\x72\x73\x74\x75\x76\x77\x78",
    81  		"red" + "\x01\x00\x00\x00\x00\x00\x00\x11",
    82  		"red" + "\x01\x00\x00\x00\x00\x00\x11\x00",
    83  		"red" + "\x01\x00\x00\x00\x00\x11\x00\x00",
    84  		"red" + "\x01\x00\x00\x00\x11\x00\x00\x00",
    85  		"red" + "\x01\x00\x00\x11\x00\x00\x00\x00",
    86  		"red" + "\x01\x00\x11\x00\x00\x00\x00\x00",
    87  		"red" + "\x01\x11\x00\x00\x00\x00\x00\x00",
    88  		"red" + "\x00\x11\x00\x00\x00\x00\x00\x00",
    89  		"red" + "\x00\x00\x00\x00\x00\x00\x00\x00",
    90  		"\xfe" + "\x01\xff\xff\xff\xff\xff\xff\xff",
    91  		"\xfe" + "\x00\x00\x00\x00\x00\x00\x00\x00",
    92  		"\xff" + "\x01\xff\xff\xff\xff\xff\xff\xff",
    93  		"\xff" + "\x00\x00\x00\x00\x00\x00\x00\x00",
    94  		"\xff\x40" + "\x01\xff\xff\xff\xff\xff\xff\xff",
    95  		"\xff\x40" + "\x00\x00\x00\x00\x00\x00\x00\x00",
    96  		"\xff\xff" + "\x01\xff\xff\xff\xff\xff\xff\xff",
    97  		"\xff\xff" + "\x00\x00\x00\x00\x00\x00\x00\x00",
    98  	}
    99  	c := DefaultComparer.Compare
   100  	for i := range keys {
   101  		for j := range keys {
   102  			ik := DecodeInternalKey([]byte(keys[i]))
   103  			jk := DecodeInternalKey([]byte(keys[j]))
   104  			got := InternalCompare(c, ik, jk)
   105  			want := 0
   106  			if i < j {
   107  				want = -1
   108  			} else if i > j {
   109  				want = +1
   110  			}
   111  			if got != want {
   112  				t.Errorf("i=%d, j=%d, keys[i]=%q, keys[j]=%q: got %d, want %d",
   113  					i, j, keys[i], keys[j], got, want)
   114  			}
   115  		}
   116  	}
   117  }
   118  
   119  func TestKindsRoundtrip(t *testing.T) {
   120  	for kindNum, prettied := range internalKeyKindNames {
   121  		if prettied == "" {
   122  			continue
   123  		}
   124  		kind := InternalKeyKind(kindNum)
   125  		got := ParseKind(kind.String())
   126  		require.Equal(t, got, kind)
   127  	}
   128  }
   129  
   130  func TestInternalKeySeparator(t *testing.T) {
   131  	testCases := []struct {
   132  		a        string
   133  		b        string
   134  		expected string
   135  	}{
   136  		{"foo.SET.100", "foo.SET.99", "foo.SET.100"},
   137  		{"foo.SET.100", "foo.SET.100", "foo.SET.100"},
   138  		{"foo.SET.100", "foo.DEL.100", "foo.SET.100"},
   139  		{"foo.SET.100", "foo.SET.101", "foo.SET.100"},
   140  		{"foo.SET.100", "bar.SET.99", "foo.SET.100"},
   141  		{"foo.SET.100", "hello.SET.200", "g.SEPARATOR.72057594037927935"},
   142  		{"ABC1AAAAA.SET.100", "ABC2ABB.SET.200", "ABC2.SEPARATOR.72057594037927935"},
   143  		{"AAA1AAA.SET.100", "AAA2AA.SET.200", "AAA2.SEPARATOR.72057594037927935"},
   144  		{"AAA1AAA.SET.100", "AAA4.SET.200", "AAA2.SEPARATOR.72057594037927935"},
   145  		{"AAA1AAA.SET.100", "AAA2.SET.200", "AAA1B.SEPARATOR.72057594037927935"},
   146  		{"AAA1AAA.SET.100", "AAA2A.SET.200", "AAA2.SEPARATOR.72057594037927935"},
   147  		{"AAA1.SET.100", "AAA2.SET.200", "AAA1.SET.100"},
   148  		{"foo.SET.100", "foobar.SET.200", "foo.SET.100"},
   149  		{"foobar.SET.100", "foo.SET.200", "foobar.SET.100"},
   150  		{"foo.INGESTSST.100", "foo.INGESTSST.99", "foo.INGESTSST.100"},
   151  	}
   152  	d := DefaultComparer
   153  	for _, c := range testCases {
   154  		t.Run("", func(t *testing.T) {
   155  			a := ParseInternalKey(c.a)
   156  			b := ParseInternalKey(c.b)
   157  			expected := ParseInternalKey(c.expected)
   158  			result := a.Separator(d.Compare, d.Separator, nil, b)
   159  			if cmp := InternalCompare(d.Compare, expected, result); cmp != 0 {
   160  				t.Fatalf("expected %s, but found %s", expected, result)
   161  			}
   162  		})
   163  	}
   164  }
   165  
   166  func TestIsExclusiveSentinel(t *testing.T) {
   167  	userKey := []byte("foo")
   168  	testCases := []struct {
   169  		name string
   170  		key  InternalKey
   171  		want bool
   172  	}{
   173  		{
   174  			name: "rangedel; max seqnum",
   175  			key:  MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindRangeKeyDelete),
   176  			want: true,
   177  		},
   178  		{
   179  			name: "rangedel; non-max seqnum",
   180  			key:  MakeInternalKey(userKey, 42, InternalKeyKindRangeKeyDelete),
   181  			want: false,
   182  		},
   183  		{
   184  			name: "rangekeyset; max seqnum",
   185  			key:  MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindRangeKeySet),
   186  			want: true,
   187  		},
   188  		{
   189  			name: "rangekeyset; non-max seqnum",
   190  			key:  MakeInternalKey(userKey, 42, InternalKeyKindRangeKeySet),
   191  			want: false,
   192  		},
   193  		{
   194  			name: "rangekeyunset; max seqnum",
   195  			key:  MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindRangeKeyUnset),
   196  			want: true,
   197  		},
   198  		{
   199  			name: "rangekeyunset; non-max seqnum",
   200  			key:  MakeInternalKey(userKey, 42, InternalKeyKindRangeKeyUnset),
   201  			want: false,
   202  		},
   203  		{
   204  			name: "rangekeydel; max seqnum",
   205  			key:  MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindRangeKeyDelete),
   206  			want: true,
   207  		},
   208  		{
   209  			name: "rangekeydel; non-max seqnum",
   210  			key:  MakeInternalKey(userKey, 42, InternalKeyKindRangeKeyDelete),
   211  			want: false,
   212  		},
   213  		{
   214  			name: "neither rangedel nor rangekey",
   215  			key:  MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindSet),
   216  			want: false,
   217  		},
   218  	}
   219  
   220  	for _, tc := range testCases {
   221  		t.Run(tc.name, func(t *testing.T) {
   222  			got := tc.key.IsExclusiveSentinel()
   223  			require.Equal(t, tc.want, got)
   224  		})
   225  	}
   226  }