github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/sstable/value_block_test.go (about) 1 // Copyright 2022 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 sstable 6 7 import ( 8 "fmt" 9 "math" 10 "math/rand" 11 "testing" 12 13 "github.com/cockroachdb/pebble/internal/base" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestValueHandleEncodeDecode(t *testing.T) { 18 testCases := []valueHandle{ 19 {valueLen: 23, blockNum: 100003, offsetInBlock: 2300}, 20 {valueLen: math.MaxUint32 - 1, blockNum: math.MaxUint32 / 2, offsetInBlock: math.MaxUint32 - 2}, 21 } 22 var buf [valueHandleMaxLen]byte 23 for _, tc := range testCases { 24 t.Run(fmt.Sprintf("%+v", tc), func(t *testing.T) { 25 n := encodeValueHandle(buf[:], tc) 26 vh := decodeValueHandle(buf[:n]) 27 require.Equal(t, tc, vh) 28 }) 29 } 30 } 31 32 func TestValuePrefix(t *testing.T) { 33 testCases := []struct { 34 isHandle bool 35 setHasSamePrefix bool 36 attr base.ShortAttribute 37 }{ 38 { 39 isHandle: false, 40 setHasSamePrefix: false, 41 }, 42 { 43 isHandle: false, 44 setHasSamePrefix: true, 45 }, 46 { 47 isHandle: true, 48 setHasSamePrefix: false, 49 attr: 5, 50 }, 51 { 52 isHandle: true, 53 setHasSamePrefix: true, 54 attr: 2, 55 }, 56 } 57 for _, tc := range testCases { 58 t.Run(fmt.Sprintf("%+v", tc), func(t *testing.T) { 59 var prefix valuePrefix 60 if tc.isHandle { 61 prefix = makePrefixForValueHandle(tc.setHasSamePrefix, tc.attr) 62 } else { 63 prefix = makePrefixForInPlaceValue(tc.setHasSamePrefix) 64 } 65 require.Equal(t, tc.isHandle, isValueHandle(prefix)) 66 require.Equal(t, tc.setHasSamePrefix, setHasSamePrefix(prefix)) 67 if tc.isHandle { 68 require.Equal(t, tc.attr, getShortAttribute(prefix)) 69 } 70 }) 71 } 72 } 73 74 func TestValueBlocksIndexHandleEncodeDecode(t *testing.T) { 75 testCases := []valueBlocksIndexHandle{ 76 { 77 h: BlockHandle{ 78 Offset: math.MaxUint64 / 2, 79 Length: math.MaxUint64 / 4, 80 }, 81 blockNumByteLength: 53, 82 blockOffsetByteLength: math.MaxUint8, 83 blockLengthByteLength: math.MaxUint8 / 2, 84 }, 85 } 86 var buf [valueBlocksIndexHandleMaxLen]byte 87 for _, tc := range testCases { 88 t.Run(fmt.Sprintf("%+v", tc), func(t *testing.T) { 89 n := encodeValueBlocksIndexHandle(buf[:], tc) 90 vbih, n2, err := decodeValueBlocksIndexHandle(buf[:n]) 91 require.NoError(t, err) 92 require.Equal(t, n, n2) 93 require.Equal(t, tc, vbih) 94 }) 95 } 96 } 97 98 func TestLittleEndianGetPut(t *testing.T) { 99 testCases := []uint64{ 100 0, (1 << 10) - 1, (1 << 25) + 1, math.MaxUint32, math.MaxUint64, uint64(rand.Int63())} 101 var buf [8]byte 102 for _, tc := range testCases { 103 t.Run(fmt.Sprintf("%d", tc), func(t *testing.T) { 104 length := lenLittleEndian(tc) 105 b := buf[:length:length] 106 littleEndianPut(tc, b, length) 107 v := littleEndianGet(b, length) 108 require.Equal(t, tc, v) 109 }) 110 } 111 }