LCOV - code coverage report
Current view: top level - pebble/sstable - block_property_test_utils.go (source / functions) Hit Total Coverage
Test: 2023-12-18 08:16Z ab4952c5 - meta test only.lcov Lines: 48 52 92.3 %
Date: 2023-12-18 08:17:00 Functions: 0 0 -

          Line data    Source code
       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             :         "math"
       9             : 
      10             :         "github.com/cockroachdb/pebble/internal/base"
      11             :         "github.com/cockroachdb/pebble/internal/testkeys"
      12             : )
      13             : 
      14             : // Code in this file contains utils for testing. It implements interval block
      15             : // property collectors and filters on the suffixes of keys in the format used
      16             : // by the testkeys package (eg, 'key@5').
      17             : 
      18             : const testKeysBlockPropertyName = `pebble.internal.testkeys.suffixes`
      19             : 
      20             : // NewTestKeysBlockPropertyCollector constructs a sstable property collector
      21             : // over testkey suffixes.
      22           1 : func NewTestKeysBlockPropertyCollector() BlockPropertyCollector {
      23           1 :         return NewBlockIntervalCollector(
      24           1 :                 testKeysBlockPropertyName,
      25           1 :                 &testKeysSuffixIntervalCollector{},
      26           1 :                 nil)
      27           1 : }
      28             : 
      29             : // NewTestKeysBlockPropertyFilter constructs a new block-property filter that excludes
      30             : // blocks containing exclusively suffixed keys where all the suffixes fall
      31             : // outside of the range [filterMin, filterMax).
      32             : //
      33             : // The filter only filters based on data derived from the key. The iteration
      34             : // results of this block property filter are deterministic for unsuffixed keys
      35             : // and keys with suffixes within the range [filterMin, filterMax). For keys with
      36             : // suffixes outside the range, iteration is nondeterministic.
      37           1 : func NewTestKeysBlockPropertyFilter(filterMin, filterMax uint64) *BlockIntervalFilter {
      38           1 :         return NewBlockIntervalFilter(testKeysBlockPropertyName, filterMin, filterMax)
      39           1 : }
      40             : 
      41             : // NewTestKeysMaskingFilter constructs a TestKeysMaskingFilter that implements
      42             : // pebble.BlockPropertyFilterMask for efficient range-key masking using the
      43             : // testkeys block property filter. The masking filter wraps a block interval
      44             : // filter, and modifies the configured interval when Pebble requests it.
      45           1 : func NewTestKeysMaskingFilter() TestKeysMaskingFilter {
      46           1 :         return TestKeysMaskingFilter{BlockIntervalFilter: NewTestKeysBlockPropertyFilter(0, math.MaxUint64)}
      47           1 : }
      48             : 
      49             : // TestKeysMaskingFilter implements BlockPropertyFilterMask and may be used to mask
      50             : // point keys with the testkeys-style suffixes (eg, @4) that are masked by range
      51             : // keys with testkeys-style suffixes.
      52             : type TestKeysMaskingFilter struct {
      53             :         *BlockIntervalFilter
      54             : }
      55             : 
      56             : // SetSuffix implements pebble.BlockPropertyFilterMask.
      57           1 : func (f TestKeysMaskingFilter) SetSuffix(suffix []byte) error {
      58           1 :         ts, err := testkeys.ParseSuffix(suffix)
      59           1 :         if err != nil {
      60           0 :                 return err
      61           0 :         }
      62           1 :         f.BlockIntervalFilter.SetInterval(uint64(ts), math.MaxUint64)
      63           1 :         return nil
      64             : }
      65             : 
      66             : // Intersects implements the BlockPropertyFilter interface.
      67           1 : func (f TestKeysMaskingFilter) Intersects(prop []byte) (bool, error) {
      68           1 :         return f.BlockIntervalFilter.Intersects(prop)
      69           1 : }
      70             : 
      71             : var _ DataBlockIntervalCollector = (*testKeysSuffixIntervalCollector)(nil)
      72             : 
      73             : // testKeysSuffixIntervalCollector maintains an interval over the timestamps in
      74             : // MVCC-like suffixes for keys (e.g. foo@123).
      75             : type testKeysSuffixIntervalCollector struct {
      76             :         initialized  bool
      77             :         lower, upper uint64
      78             : }
      79             : 
      80             : // Add implements DataBlockIntervalCollector by adding the timestamp(s) in the
      81             : // suffix(es) of this record to the current interval.
      82             : //
      83             : // Note that range sets and unsets may have multiple suffixes. Range key deletes
      84             : // do not have a suffix. All other point keys have a single suffix.
      85           1 : func (c *testKeysSuffixIntervalCollector) Add(key base.InternalKey, value []byte) error {
      86           1 :         i := testkeys.Comparer.Split(key.UserKey)
      87           1 :         if i == len(key.UserKey) {
      88           1 :                 c.initialized = true
      89           1 :                 c.lower, c.upper = 0, math.MaxUint64
      90           1 :                 return nil
      91           1 :         }
      92           1 :         ts, err := testkeys.ParseSuffix(key.UserKey[i:])
      93           1 :         if err != nil {
      94           0 :                 return err
      95           0 :         }
      96           1 :         uts := uint64(ts)
      97           1 :         if !c.initialized {
      98           1 :                 c.lower, c.upper = uts, uts+1
      99           1 :                 c.initialized = true
     100           1 :                 return nil
     101           1 :         }
     102           1 :         if uts < c.lower {
     103           1 :                 c.lower = uts
     104           1 :         }
     105           1 :         if uts >= c.upper {
     106           1 :                 c.upper = uts + 1
     107           1 :         }
     108           1 :         return nil
     109             : }
     110             : 
     111             : // FinishDataBlock implements DataBlockIntervalCollector.
     112           1 : func (c *testKeysSuffixIntervalCollector) FinishDataBlock() (lower, upper uint64, err error) {
     113           1 :         l, u := c.lower, c.upper
     114           1 :         c.lower, c.upper = 0, 0
     115           1 :         c.initialized = false
     116           1 :         return l, u, nil
     117           1 : }

Generated by: LCOV version 1.14