github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/internal/base/lazy_value_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 base 6 7 import ( 8 "bytes" 9 "testing" 10 "unsafe" 11 12 "github.com/stretchr/testify/require" 13 ) 14 15 type valueFetcherFunc func( 16 handle []byte, valLen int32, buf []byte) (val []byte, callerOwned bool, err error) 17 18 func (v valueFetcherFunc) Fetch( 19 handle []byte, valLen int32, buf []byte, 20 ) (val []byte, callerOwned bool, err error) { 21 return v(handle, valLen, buf) 22 } 23 24 func TestLazyValue(t *testing.T) { 25 // Both 40 and 48 bytes makes iteration benchmarks like 26 // BenchmarkIteratorScan/keys=1000,r-amp=1,key-types=points-only 75% 27 // slower. 28 require.True(t, unsafe.Sizeof(LazyValue{}) <= 32) 29 30 fooBytes1 := []byte("foo") 31 fooLV1 := MakeInPlaceValue(fooBytes1) 32 require.Equal(t, 3, fooLV1.Len()) 33 _, hasAttr := fooLV1.TryGetShortAttribute() 34 require.False(t, hasAttr) 35 fooLV2, fooBytes2 := fooLV1.Clone(nil, &LazyFetcher{}) 36 require.Equal(t, 3, fooLV2.Len()) 37 _, hasAttr = fooLV2.TryGetShortAttribute() 38 require.False(t, hasAttr) 39 require.Equal(t, fooLV1.InPlaceValue(), fooLV2.InPlaceValue()) 40 getValue := func(lv LazyValue, expectedCallerOwned bool) []byte { 41 v, callerOwned, err := lv.Value(nil) 42 require.NoError(t, err) 43 require.Equal(t, expectedCallerOwned, callerOwned) 44 return v 45 } 46 require.Equal(t, getValue(fooLV1, false), getValue(fooLV2, false)) 47 fooBytes2[0] = 'b' 48 require.False(t, bytes.Equal(fooLV1.InPlaceValue(), fooLV2.InPlaceValue())) 49 50 for _, callerOwned := range []bool{false, true} { 51 numCalls := 0 52 fooLV3 := LazyValue{ 53 ValueOrHandle: []byte("foo-handle"), 54 Fetcher: &LazyFetcher{ 55 Fetcher: valueFetcherFunc( 56 func(handle []byte, valLen int32, buf []byte) ([]byte, bool, error) { 57 numCalls++ 58 require.Equal(t, []byte("foo-handle"), handle) 59 require.Equal(t, int32(3), valLen) 60 return fooBytes1, callerOwned, nil 61 }), 62 Attribute: AttributeAndLen{ValueLen: 3, ShortAttribute: 7}, 63 }, 64 } 65 require.Equal(t, []byte("foo"), getValue(fooLV3, callerOwned)) 66 require.Equal(t, 1, numCalls) 67 require.Equal(t, []byte("foo"), getValue(fooLV3, callerOwned)) 68 require.Equal(t, 1, numCalls) 69 require.Equal(t, 3, fooLV3.Len()) 70 attr, hasAttr := fooLV3.TryGetShortAttribute() 71 require.True(t, hasAttr) 72 require.Equal(t, ShortAttribute(7), attr) 73 } 74 }