github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/sstable/properties_test.go (about)

     1  // Copyright 2018 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  	"math/rand"
     9  	"os"
    10  	"path/filepath"
    11  	"reflect"
    12  	"strings"
    13  	"testing"
    14  	"testing/quick"
    15  	"time"
    16  
    17  	"github.com/kr/pretty"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestPropertiesLoad(t *testing.T) {
    22  	expected := Properties{
    23  		CommonProperties: CommonProperties{
    24  			NumEntries:        1727,
    25  			NumDeletions:      17,
    26  			NumRangeDeletions: 17,
    27  			RawKeySize:        23938,
    28  			RawValueSize:      1912,
    29  		},
    30  		ComparerName:           "leveldb.BytewiseComparator",
    31  		CompressionName:        "Snappy",
    32  		CompressionOptions:     "window_bits=-14; level=32767; strategy=0; max_dict_bytes=0; zstd_max_train_bytes=0; enabled=0; ",
    33  		DataSize:               13913,
    34  		ExternalFormatVersion:  2,
    35  		IndexSize:              325,
    36  		MergerName:             "nullptr",
    37  		NumDataBlocks:          14,
    38  		PrefixExtractorName:    "nullptr",
    39  		PropertyCollectorNames: "[KeyCountPropertyCollector]",
    40  		UserProperties: map[string]string{
    41  			"test.key-count": "1727",
    42  		},
    43  		WholeKeyFiltering: false,
    44  	}
    45  
    46  	{
    47  		// Check that we can read properties from a table.
    48  		f, err := os.Open(filepath.FromSlash("testdata/h.sst"))
    49  		require.NoError(t, err)
    50  
    51  		r, err := newReader(f, ReaderOptions{})
    52  
    53  		require.NoError(t, err)
    54  		defer r.Close()
    55  
    56  		r.Properties.Loaded = nil
    57  
    58  		if diff := pretty.Diff(expected, r.Properties); diff != nil {
    59  			t.Fatalf("%s", strings.Join(diff, "\n"))
    60  		}
    61  	}
    62  }
    63  
    64  func TestPropertiesSave(t *testing.T) {
    65  	expected := &Properties{
    66  		CommonProperties: CommonProperties{
    67  			NumDeletions:      15,
    68  			NumEntries:        16,
    69  			NumRangeDeletions: 18,
    70  			NumRangeKeyDels:   19,
    71  			NumRangeKeySets:   20,
    72  			RawKeySize:        25,
    73  			RawValueSize:      26,
    74  		},
    75  		ComparerName:           "comparator name",
    76  		CompressionName:        "compression name",
    77  		CompressionOptions:     "compression option",
    78  		DataSize:               3,
    79  		ExternalFormatVersion:  4,
    80  		FilterPolicyName:       "filter policy name",
    81  		FilterSize:             5,
    82  		GlobalSeqNum:           8,
    83  		IndexPartitions:        10,
    84  		IndexSize:              11,
    85  		IndexType:              12,
    86  		IsStrictObsolete:       true,
    87  		MergerName:             "merge operator name",
    88  		NumDataBlocks:          14,
    89  		NumMergeOperands:       17,
    90  		NumRangeKeyUnsets:      21,
    91  		NumValueBlocks:         22,
    92  		NumValuesInValueBlocks: 23,
    93  		PrefixExtractorName:    "prefix extractor name",
    94  		PrefixFiltering:        true,
    95  		PropertyCollectorNames: "prefix collector names",
    96  		TopLevelIndexSize:      27,
    97  		WholeKeyFiltering:      true,
    98  		UserProperties: map[string]string{
    99  			"user-prop-a": "1",
   100  			"user-prop-b": "2",
   101  		},
   102  	}
   103  
   104  	check1 := func(expected *Properties) {
   105  		// Check that we can save properties and read them back.
   106  		var w rawBlockWriter
   107  		w.restartInterval = propertiesBlockRestartInterval
   108  		expected.save(TableFormatPebblev2, &w)
   109  		var props Properties
   110  
   111  		require.NoError(t, props.load(w.finish(), 0, make(map[string]struct{})))
   112  		props.Loaded = nil
   113  		if diff := pretty.Diff(*expected, props); diff != nil {
   114  			t.Fatalf("%s", strings.Join(diff, "\n"))
   115  		}
   116  	}
   117  
   118  	check1(expected)
   119  
   120  	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
   121  	for i := 0; i < 1000; i++ {
   122  		v, _ := quick.Value(reflect.TypeOf(Properties{}), rng)
   123  		props := v.Interface().(Properties)
   124  		if props.IndexPartitions == 0 {
   125  			props.TopLevelIndexSize = 0
   126  		}
   127  		check1(&props)
   128  	}
   129  }