LCOV - code coverage report
Current view: top level - pebble/sstable/sstable - block_property_obsolete.go (source / functions) Coverage Total Hit
Test: 2025-09-29 08:19Z e52aa891 - meta test only.lcov Lines: 73.6 % 72 53
Test Date: 2025-09-29 08:21:14 Functions: - 0 0

            Line data    Source code
       1              : // Copyright 2024 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              :         "github.com/cockroachdb/errors"
       9              :         "github.com/cockroachdb/pebble/internal/base"
      10              : )
      11              : 
      12              : // obsoleteKeyBlockPropertyCollector is a block property collector used to
      13              : // implement obsoleteKeyBlockPropertyFilter - a filter that excludes blocks
      14              : // which contain only obsolete keys.
      15              : //
      16              : // For an explanation of obsolete keys, see the comment for TableFormatPebblev4
      17              : // which explains obsolete keys.
      18              : type obsoleteKeyBlockPropertyCollector struct {
      19              :         blockIsNonObsolete bool
      20              :         indexIsNonObsolete bool
      21              :         tableIsNonObsolete bool
      22              : }
      23              : 
      24              : var _ BlockPropertyCollector = (*obsoleteKeyBlockPropertyCollector)(nil)
      25              : 
      26              : // Name is part of the BlockPropertyCollector interface.
      27            1 : func (o *obsoleteKeyBlockPropertyCollector) Name() string {
      28            1 :         return "obsolete-key"
      29            1 : }
      30              : 
      31              : // AddPointKey is part of the BlockPropertyCollector interface.
      32            1 : func (o *obsoleteKeyBlockPropertyCollector) AddPointKey(key InternalKey, value []byte) error {
      33            1 :         // Ignore.
      34            1 :         return nil
      35            1 : }
      36              : 
      37              : // AddRangeKeys is part of the BlockPropertyCollector interface.
      38            1 : func (o *obsoleteKeyBlockPropertyCollector) AddRangeKeys(span Span) error {
      39            1 :         // Ignore.
      40            1 :         return nil
      41            1 : }
      42              : 
      43              : // AddPoint is an out-of-band method that is specific to this collector.
      44            1 : func (o *obsoleteKeyBlockPropertyCollector) AddPoint(isObsolete bool) {
      45            1 :         o.blockIsNonObsolete = o.blockIsNonObsolete || !isObsolete
      46            1 : }
      47              : 
      48              : // FinishDataBlock is part of the BlockPropertyCollector interface.
      49            1 : func (o *obsoleteKeyBlockPropertyCollector) FinishDataBlock(buf []byte) ([]byte, error) {
      50            1 :         o.tableIsNonObsolete = o.tableIsNonObsolete || o.blockIsNonObsolete
      51            1 :         return obsoleteKeyBlockPropertyEncode(!o.blockIsNonObsolete, buf), nil
      52            1 : }
      53              : 
      54              : // AddPrevDataBlockToIndexBlock is part of the BlockPropertyCollector interface.
      55            1 : func (o *obsoleteKeyBlockPropertyCollector) AddPrevDataBlockToIndexBlock() {
      56            1 :         o.indexIsNonObsolete = o.indexIsNonObsolete || o.blockIsNonObsolete
      57            1 :         o.blockIsNonObsolete = false
      58            1 : }
      59              : 
      60              : // FinishIndexBlock is part of the BlockPropertyCollector interface.
      61            1 : func (o *obsoleteKeyBlockPropertyCollector) FinishIndexBlock(buf []byte) ([]byte, error) {
      62            1 :         buf = obsoleteKeyBlockPropertyEncode(!o.indexIsNonObsolete, buf)
      63            1 :         o.indexIsNonObsolete = false
      64            1 :         return buf, nil
      65            1 : }
      66              : 
      67              : // FinishTable is part of the BlockPropertyCollector interface.
      68            1 : func (o *obsoleteKeyBlockPropertyCollector) FinishTable(buf []byte) ([]byte, error) {
      69            1 :         return obsoleteKeyBlockPropertyEncode(!o.tableIsNonObsolete, buf), nil
      70            1 : }
      71              : 
      72              : // AddCollectedWithSuffixReplacement is part of the BlockPropertyCollector interface.
      73              : func (o *obsoleteKeyBlockPropertyCollector) AddCollectedWithSuffixReplacement(
      74              :         oldProp []byte, oldSuffix, newSuffix []byte,
      75            0 : ) error {
      76            0 :         // Verify the property is valid.
      77            0 :         _, err := obsoleteKeyBlockPropertyDecode(oldProp)
      78            0 :         if err != nil {
      79            0 :                 return err
      80            0 :         }
      81              :         // Suffix rewriting currently loses the obsolete bit.
      82            0 :         o.blockIsNonObsolete = true
      83            0 :         return nil
      84              : }
      85              : 
      86              : // SupportsSuffixReplacement is part of the BlockPropertyCollector interface.
      87            0 : func (o *obsoleteKeyBlockPropertyCollector) SupportsSuffixReplacement() bool {
      88            0 :         return true
      89            0 : }
      90              : 
      91              : // obsoleteKeyBlockPropertyFilter implements the filter that excludes blocks
      92              : // that only contain obsolete keys. It pairs with
      93              : // obsoleteKeyBlockPropertyCollector.
      94              : //
      95              : // Note that we filter data blocks as well as first-level index blocks.
      96              : //
      97              : // For an explanation of obsolete keys, see the comment for TableFormatPebblev4
      98              : // which explains obsolete keys.
      99              : //
     100              : // NB: obsoleteKeyBlockPropertyFilter is stateless. This aspect of the filter
     101              : // is used in table_cache.go for in-place modification of a filters slice.
     102              : type obsoleteKeyBlockPropertyFilter struct{}
     103              : 
     104              : var _ BlockPropertyFilter = obsoleteKeyBlockPropertyFilter{}
     105              : 
     106              : // Name is part of the BlockPropertyFilter interface. It must match
     107              : // obsoleteKeyBlockPropertyCollector.Name.
     108            1 : func (o obsoleteKeyBlockPropertyFilter) Name() string {
     109            1 :         return "obsolete-key"
     110            1 : }
     111              : 
     112              : // Intersects is part of the BlockPropertyFilter interface. It returns true
     113              : // if the block may contain non-obsolete keys.
     114            1 : func (o obsoleteKeyBlockPropertyFilter) Intersects(prop []byte) (bool, error) {
     115            1 :         isObsolete, err := obsoleteKeyBlockPropertyDecode(prop)
     116            1 :         if err != nil {
     117            0 :                 return false, err
     118            0 :         }
     119            1 :         return !isObsolete, nil
     120              : }
     121              : 
     122              : // SyntheticSuffixIntersects is part of the BlockPropertyFilter interface. It
     123              : // expects that synthetic suffix is never used with tables that contain obsolete
     124              : // keys.
     125              : func (o obsoleteKeyBlockPropertyFilter) SyntheticSuffixIntersects(
     126              :         prop []byte, suffix []byte,
     127            1 : ) (bool, error) {
     128            1 :         isObsolete, err := obsoleteKeyBlockPropertyDecode(prop)
     129            1 :         if err != nil {
     130            0 :                 return false, err
     131            0 :         }
     132              :         // A block with suffix replacement should never be obsolete.
     133            1 :         if isObsolete {
     134            0 :                 return false, base.AssertionFailedf("block with synthetic suffix is obsolete")
     135            0 :         }
     136            1 :         return true, nil
     137              : }
     138              : 
     139              : // Encodes the information of whether the block contains only obsolete keys. We
     140              : // use the empty encoding for the common case of a block not being obsolete.
     141            1 : func obsoleteKeyBlockPropertyEncode(isObsolete bool, buf []byte) []byte {
     142            1 :         if isObsolete {
     143            1 :                 return append(buf, 't')
     144            1 :         }
     145            1 :         return buf
     146              : }
     147              : 
     148              : // Decodes the information of whether the block contains only obsolete keys (the
     149              : // inverse of obsoleteKeyBlockPropertyEncode).
     150            1 : func obsoleteKeyBlockPropertyDecode(prop []byte) (isObsolete bool, _ error) {
     151            1 :         switch {
     152            1 :         case len(prop) == 0:
     153            1 :                 return false, nil
     154            1 :         case len(prop) == 1 && prop[0] == 't':
     155            1 :                 return true, nil
     156            0 :         default:
     157            0 :                 return false, errors.Errorf("invalid obsolete block property %x", prop)
     158              :         }
     159              : }
        

Generated by: LCOV version 2.0-1