github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/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"
     9  	"math/rand"
    10  	"os"
    11  	"path/filepath"
    12  	"reflect"
    13  	"strings"
    14  	"testing"
    15  	"testing/quick"
    16  	"time"
    17  
    18  	"github.com/kr/pretty"
    19  )
    20  
    21  func TestPropertiesLoad(t *testing.T) {
    22  	expected := Properties{
    23  		ColumnFamilyID:         math.MaxInt32,
    24  		ComparerName:           "leveldb.BytewiseComparator",
    25  		CompressionName:        "Snappy",
    26  		CompressionOptions:     "window_bits=-14; level=32767; strategy=0; max_dict_bytes=0; zstd_max_train_bytes=0; enabled=0; ",
    27  		DataSize:               13913,
    28  		IndexSize:              325,
    29  		MergerName:             "nullptr",
    30  		NumDataBlocks:          14,
    31  		NumEntries:             1727,
    32  		NumDeletions:           17,
    33  		NumRangeDeletions:      17,
    34  		PrefixExtractorName:    "nullptr",
    35  		PropertyCollectorNames: "[KeyCountPropertyCollector]",
    36  		RawKeySize:             23938,
    37  		RawValueSize:           1912,
    38  		Version:                2,
    39  		UserProperties: map[string]string{
    40  			"test.key-count": "1727",
    41  		},
    42  		WholeKeyFiltering: false,
    43  		ValueOffsets: map[string]uint64{
    44  			"rocksdb.block.based.table.index.type":          14625,
    45  			"rocksdb.block.based.table.prefix.filtering":    14674,
    46  			"rocksdb.block.based.table.whole.key.filtering": 14697,
    47  			"rocksdb.column.family.id":                      14699,
    48  			"rocksdb.comparator":                            14717,
    49  			"rocksdb.compression":                           14755,
    50  			"rocksdb.compression_options":                   14779,
    51  			"rocksdb.creation.time":                         14879,
    52  			"rocksdb.data.size":                             14891,
    53  			"rocksdb.deleted.keys":                          14908,
    54  			"rocksdb.external_sst_file.global_seqno":        14941,
    55  			"rocksdb.external_sst_file.version":             14977,
    56  			"rocksdb.filter.size":                           14977,
    57  			"rocksdb.fixed.key.length":                      14997,
    58  			"rocksdb.format.version":                        15013,
    59  			"rocksdb.index.key.is.user.key":                 15037,
    60  			"rocksdb.index.size":                            15051,
    61  			"rocksdb.index.value.is.delta.encoded":          15078,
    62  			"rocksdb.merge.operands":                        15090,
    63  			"rocksdb.merge.operator":                        15108,
    64  			"rocksdb.num.data.blocks":                       15122,
    65  			"rocksdb.num.entries":                           15137,
    66  			"rocksdb.num.range-deletions":                   15157,
    67  			"rocksdb.oldest.key.time":                       15172,
    68  			"rocksdb.prefix.extractor.name":                 15197,
    69  			"rocksdb.property.collectors":                   15226,
    70  			"rocksdb.raw.key.size":                          15266,
    71  			"rocksdb.raw.value.size":                        15286,
    72  			"test.key-count":                                15293,
    73  		},
    74  	}
    75  
    76  	{
    77  		// Check that we can read properties from a table.
    78  		f, err := os.Open(filepath.FromSlash("testdata/h.sst"))
    79  		if err != nil {
    80  			t.Fatal(err)
    81  		}
    82  		defer f.Close()
    83  		r, err := NewReader(f, 0, 0, nil)
    84  		if err != nil {
    85  			t.Fatal(err)
    86  		}
    87  
    88  		if diff := pretty.Diff(expected, r.Properties); diff != nil {
    89  			t.Fatalf("%s", strings.Join(diff, "\n"))
    90  		}
    91  	}
    92  }
    93  
    94  func TestPropertiesSave(t *testing.T) {
    95  	expected := &Properties{
    96  		ColumnFamilyID:           1,
    97  		ColumnFamilyName:         "column family name",
    98  		ComparerName:             "comparator name",
    99  		CompressionName:          "compression name",
   100  		CompressionOptions:       "compression option",
   101  		CreationTime:             2,
   102  		DataSize:                 3,
   103  		FilterPolicyName:         "filter policy name",
   104  		FilterSize:               4,
   105  		FixedKeyLen:              5,
   106  		FormatVersion:            6,
   107  		GlobalSeqNum:             7,
   108  		IndexKeyIsUserKey:        8,
   109  		IndexPartitions:          9,
   110  		IndexSize:                10,
   111  		IndexType:                11,
   112  		IndexValueIsDeltaEncoded: 12,
   113  		MergerName:               "merge operator name",
   114  		NumDataBlocks:            13,
   115  		NumDeletions:             14,
   116  		NumEntries:               15,
   117  		NumMergeOperands:         16,
   118  		NumRangeDeletions:        17,
   119  		OldestKeyTime:            18,
   120  		PrefixExtractorName:      "prefix extractor name",
   121  		PrefixFiltering:          true,
   122  		PropertyCollectorNames:   "prefix collector names",
   123  		RawKeySize:               19,
   124  		RawValueSize:             20,
   125  		TopLevelIndexSize:        21,
   126  		Version:                  22,
   127  		WholeKeyFiltering:        true,
   128  		UserProperties: map[string]string{
   129  			"user-prop-a": "1",
   130  			"user-prop-b": "2",
   131  		},
   132  	}
   133  
   134  	check1 := func(expected *Properties) {
   135  		// Check that we can save properties and read them back.
   136  		var w rawBlockWriter
   137  		w.restartInterval = propertiesBlockRestartInterval
   138  		expected.save(&w)
   139  		var props Properties
   140  		if err := props.load(w.finish(), 0); err != nil {
   141  			t.Fatal(err)
   142  		}
   143  		props.ValueOffsets = nil
   144  		if diff := pretty.Diff(*expected, props); diff != nil {
   145  			t.Fatalf("%s", strings.Join(diff, "\n"))
   146  		}
   147  	}
   148  
   149  	check1(expected)
   150  
   151  	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
   152  	for i := 0; i < 1000; i++ {
   153  		v, _ := quick.Value(reflect.TypeOf(Properties{}), rng)
   154  		props := v.Interface().(Properties)
   155  		if props.IndexPartitions == 0 {
   156  			props.TopLevelIndexSize = 0
   157  		}
   158  		check1(&props)
   159  	}
   160  }