github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/internal/rangekey/rangekey_test.go (about) 1 package rangekey 2 3 import ( 4 "testing" 5 6 "github.com/cockroachdb/pebble/internal/base" 7 "github.com/stretchr/testify/require" 8 ) 9 10 func TestSetSuffixValues_RoundTrip(t *testing.T) { 11 testCases := [][]SuffixValue{ 12 { 13 {Suffix: []byte{}, Value: []byte("world")}, 14 }, 15 { 16 {Suffix: []byte("foo"), Value: []byte("bar")}, 17 }, 18 { 19 {Suffix: []byte(""), Value: []byte("boop")}, 20 {Suffix: []byte("foo"), Value: []byte("beep")}, 21 {Suffix: []byte("bar"), Value: []byte("bop")}, 22 {Suffix: []byte("bax"), Value: []byte("boink")}, 23 {Suffix: []byte("zoop"), Value: []byte("zoink")}, 24 }, 25 } 26 27 var b []byte 28 for _, tc := range testCases { 29 // Encode. 30 l := encodedSetSuffixValuesLen(tc) 31 if l <= cap(b) { 32 b = b[:l] 33 } else { 34 b = make([]byte, l) 35 } 36 n := encodeSetSuffixValues(b, tc) 37 require.Equal(t, l, n) 38 39 // Decode. 40 var suffixValues []SuffixValue 41 for len(b) > 0 { 42 sv, rest, ok := decodeSuffixValue(b) 43 require.True(t, ok) 44 suffixValues = append(suffixValues, sv) 45 b = rest 46 } 47 require.Equal(t, tc, suffixValues) 48 } 49 } 50 51 func TestSetValue_Roundtrip(t *testing.T) { 52 testCases := []struct { 53 endKey []byte 54 suffixValues []SuffixValue 55 }{ 56 { 57 endKey: []byte("hello"), 58 suffixValues: []SuffixValue{ 59 {Suffix: []byte{}, Value: []byte("world")}, 60 }, 61 }, 62 { 63 endKey: []byte("hello world"), 64 suffixValues: []SuffixValue{ 65 {Suffix: []byte("foo"), Value: []byte("bar")}, 66 }, 67 }, 68 { 69 endKey: []byte("hello world"), 70 suffixValues: []SuffixValue{ 71 {Suffix: []byte(""), Value: []byte("boop")}, 72 {Suffix: []byte("foo"), Value: []byte("beep")}, 73 {Suffix: []byte("bar"), Value: []byte("bop")}, 74 {Suffix: []byte("bax"), Value: []byte("boink")}, 75 {Suffix: []byte("zoop"), Value: []byte("zoink")}, 76 }, 77 }, 78 } 79 80 var b []byte 81 for _, tc := range testCases { 82 l := EncodedSetValueLen(tc.endKey, tc.suffixValues) 83 84 if l <= cap(b) { 85 b = b[:l] 86 } else { 87 b = make([]byte, l) 88 } 89 90 n := EncodeSetValue(b, tc.endKey, tc.suffixValues) 91 require.Equal(t, l, n) 92 93 var endKey, rest []byte 94 var ok bool 95 endKey, rest, ok = DecodeEndKey(base.InternalKeyKindRangeKeySet, b[:n]) 96 require.True(t, ok) 97 98 var suffixValues []SuffixValue 99 for len(rest) > 0 { 100 var sv SuffixValue 101 var ok bool 102 sv, rest, ok = decodeSuffixValue(rest) 103 require.True(t, ok) 104 suffixValues = append(suffixValues, sv) 105 } 106 require.Equal(t, tc.endKey, endKey) 107 require.Equal(t, tc.suffixValues, suffixValues) 108 } 109 } 110 111 func TestUnsetSuffixes_RoundTrip(t *testing.T) { 112 type suffixes [][]byte 113 testCases := []suffixes{ 114 {{}}, 115 {[]byte("foo")}, 116 { 117 {}, 118 []byte("foo"), 119 []byte("bar"), 120 []byte("bax"), 121 []byte("zoop"), 122 }, 123 } 124 125 var b []byte 126 for _, tc := range testCases { 127 // Encode. 128 l := encodedUnsetSuffixesLen(tc) 129 if l <= cap(b) { 130 b = b[:l] 131 } else { 132 b = make([]byte, l) 133 } 134 n := encodeUnsetSuffixes(b, tc) 135 require.Equal(t, l, n) 136 137 // Decode. 138 var ss suffixes 139 for len(b) > 0 { 140 s, rest, ok := decodeSuffix(b) 141 require.True(t, ok) 142 ss = append(ss, s) 143 b = rest 144 } 145 require.Equal(t, tc, ss) 146 } 147 } 148 149 func TestUnsetValue_Roundtrip(t *testing.T) { 150 testCases := []struct { 151 endKey []byte 152 suffixes [][]byte 153 }{ 154 { 155 endKey: []byte("hello"), 156 suffixes: [][]byte{{}}, 157 }, 158 { 159 endKey: []byte("hello world"), 160 suffixes: [][]byte{[]byte("foo")}, 161 }, 162 { 163 endKey: []byte("hello world"), 164 suffixes: [][]byte{ 165 {}, 166 []byte("foo"), 167 []byte("bar"), 168 []byte("bax"), 169 []byte("zoop"), 170 }, 171 }, 172 } 173 174 var b []byte 175 for _, tc := range testCases { 176 l := EncodedUnsetValueLen(tc.endKey, tc.suffixes) 177 178 if l <= cap(b) { 179 b = b[:l] 180 } else { 181 b = make([]byte, l) 182 } 183 184 n := EncodeUnsetValue(b, tc.endKey, tc.suffixes) 185 require.Equal(t, l, n) 186 187 var ok bool 188 var endKey, rest []byte 189 endKey, rest, ok = DecodeEndKey(base.InternalKeyKindRangeKeyUnset, b[:n]) 190 require.True(t, ok) 191 var suffixes [][]byte 192 for len(rest) > 0 { 193 var ok bool 194 var suffix []byte 195 suffix, rest, ok = decodeSuffix(rest) 196 require.True(t, ok) 197 suffixes = append(suffixes, suffix) 198 } 199 require.Equal(t, tc.endKey, endKey) 200 require.Equal(t, tc.suffixes, suffixes) 201 } 202 } 203 204 func TestIsRangeKey(t *testing.T) { 205 testCases := []struct { 206 kind base.InternalKeyKind 207 want bool 208 }{ 209 { 210 kind: base.InternalKeyKindRangeKeyDelete, 211 want: true, 212 }, 213 { 214 kind: base.InternalKeyKindRangeKeyUnset, 215 want: true, 216 }, 217 { 218 kind: base.InternalKeyKindRangeKeyDelete, 219 want: true, 220 }, 221 { 222 kind: base.InternalKeyKindDelete, 223 want: false, 224 }, 225 { 226 kind: base.InternalKeyKindDeleteSized, 227 want: false, 228 }, 229 { 230 kind: base.InternalKeyKindSet, 231 want: false, 232 }, 233 } 234 for _, tc := range testCases { 235 t.Run("", func(t *testing.T) { 236 require.Equal(t, tc.want, IsRangeKey(tc.kind)) 237 }) 238 } 239 }