Skip to content

Commit

Permalink
sstable: move obsoleteKey collector/filter code
Browse files Browse the repository at this point in the history
  • Loading branch information
RaduBerinde committed Mar 18, 2024
1 parent f16b86e commit b7e5e71
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 97 deletions.
104 changes: 104 additions & 0 deletions sstable/block_property_obsolete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2024 The LevelDB-Go and Pebble Authors. All rights reserved. Use
// of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.

package sstable

import "github.com/cockroachdb/errors"

type obsoleteKeyBlockPropertyCollector struct {
blockIsNonObsolete bool
indexIsNonObsolete bool
tableIsNonObsolete bool
}

func encodeNonObsolete(isNonObsolete bool, buf []byte) []byte {
if isNonObsolete {
return buf
}
return append(buf, 't')
}

func (o *obsoleteKeyBlockPropertyCollector) Name() string {
return "obsolete-key"
}

func (o *obsoleteKeyBlockPropertyCollector) Add(key InternalKey, value []byte) error {
// Ignore.
return nil
}

func (o *obsoleteKeyBlockPropertyCollector) AddPoint(isObsolete bool) {
o.blockIsNonObsolete = o.blockIsNonObsolete || !isObsolete
}

func (o *obsoleteKeyBlockPropertyCollector) FinishDataBlock(buf []byte) ([]byte, error) {
o.tableIsNonObsolete = o.tableIsNonObsolete || o.blockIsNonObsolete
return encodeNonObsolete(o.blockIsNonObsolete, buf), nil
}

func (o *obsoleteKeyBlockPropertyCollector) AddPrevDataBlockToIndexBlock() {
o.indexIsNonObsolete = o.indexIsNonObsolete || o.blockIsNonObsolete
o.blockIsNonObsolete = false
}

func (o *obsoleteKeyBlockPropertyCollector) FinishIndexBlock(buf []byte) ([]byte, error) {
indexIsNonObsolete := o.indexIsNonObsolete
o.indexIsNonObsolete = false
return encodeNonObsolete(indexIsNonObsolete, buf), nil
}

func (o *obsoleteKeyBlockPropertyCollector) FinishTable(buf []byte) ([]byte, error) {
return encodeNonObsolete(o.tableIsNonObsolete, buf), nil
}

func (o *obsoleteKeyBlockPropertyCollector) UpdateKeySuffixes(
oldProp []byte, oldSuffix, newSuffix []byte,
) error {
_, err := propToIsObsolete(oldProp)
if err != nil {
return err
}
// Suffix rewriting currently loses the obsolete bit.
o.blockIsNonObsolete = true
return nil
}

// NB: obsoleteKeyBlockPropertyFilter is stateless. This aspect of the filter
// is used in table_cache.go for in-place modification of a filters slice.
type obsoleteKeyBlockPropertyFilter struct{}

func (o obsoleteKeyBlockPropertyFilter) Name() string {
return "obsolete-key"
}

// Intersects returns true if the set represented by prop intersects with
// the set in the filter.
func (o obsoleteKeyBlockPropertyFilter) Intersects(prop []byte) (bool, error) {
return propToIsObsolete(prop)
}

func (o obsoleteKeyBlockPropertyFilter) SyntheticSuffixIntersects(
prop []byte, suffix []byte,
) (bool, error) {
// A block with suffix replacement should never be
// obselete, so return an assertion error if it is.
isNotObsolete, err := o.Intersects(prop)
if err != nil {
return false, err
}
if !isNotObsolete {
return false, errors.AssertionFailedf("block with synthetic suffix is obselete")
}
return true, nil
}

func propToIsObsolete(prop []byte) (bool, error) {
if len(prop) == 0 {
return true, nil
}
if len(prop) > 1 || prop[0] != 't' {
return false, errors.Errorf("unexpected property %x", prop)
}
return false, nil
}
97 changes: 0 additions & 97 deletions sstable/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2334,100 +2334,3 @@ func init() {
}
private.SSTableInternalProperties = internalGetProperties
}

type obsoleteKeyBlockPropertyCollector struct {
blockIsNonObsolete bool
indexIsNonObsolete bool
tableIsNonObsolete bool
}

func encodeNonObsolete(isNonObsolete bool, buf []byte) []byte {
if isNonObsolete {
return buf
}
return append(buf, 't')
}

func (o *obsoleteKeyBlockPropertyCollector) Name() string {
return "obsolete-key"
}

func (o *obsoleteKeyBlockPropertyCollector) Add(key InternalKey, value []byte) error {
// Ignore.
return nil
}

func (o *obsoleteKeyBlockPropertyCollector) AddPoint(isObsolete bool) {
o.blockIsNonObsolete = o.blockIsNonObsolete || !isObsolete
}

func (o *obsoleteKeyBlockPropertyCollector) FinishDataBlock(buf []byte) ([]byte, error) {
o.tableIsNonObsolete = o.tableIsNonObsolete || o.blockIsNonObsolete
return encodeNonObsolete(o.blockIsNonObsolete, buf), nil
}

func (o *obsoleteKeyBlockPropertyCollector) AddPrevDataBlockToIndexBlock() {
o.indexIsNonObsolete = o.indexIsNonObsolete || o.blockIsNonObsolete
o.blockIsNonObsolete = false
}

func (o *obsoleteKeyBlockPropertyCollector) FinishIndexBlock(buf []byte) ([]byte, error) {
indexIsNonObsolete := o.indexIsNonObsolete
o.indexIsNonObsolete = false
return encodeNonObsolete(indexIsNonObsolete, buf), nil
}

func (o *obsoleteKeyBlockPropertyCollector) FinishTable(buf []byte) ([]byte, error) {
return encodeNonObsolete(o.tableIsNonObsolete, buf), nil
}

func (o *obsoleteKeyBlockPropertyCollector) UpdateKeySuffixes(
oldProp []byte, oldSuffix, newSuffix []byte,
) error {
_, err := propToIsObsolete(oldProp)
if err != nil {
return err
}
// Suffix rewriting currently loses the obsolete bit.
o.blockIsNonObsolete = true
return nil
}

// NB: obsoleteKeyBlockPropertyFilter is stateless. This aspect of the filter
// is used in table_cache.go for in-place modification of a filters slice.
type obsoleteKeyBlockPropertyFilter struct{}

func (o obsoleteKeyBlockPropertyFilter) Name() string {
return "obsolete-key"
}

// Intersects returns true if the set represented by prop intersects with
// the set in the filter.
func (o obsoleteKeyBlockPropertyFilter) Intersects(prop []byte) (bool, error) {
return propToIsObsolete(prop)
}

func (o obsoleteKeyBlockPropertyFilter) SyntheticSuffixIntersects(
prop []byte, suffix []byte,
) (bool, error) {
// A block with suffix replacement should never be
// obselete, so return an assertion error if it is.
isNotObsolete, err := o.Intersects(prop)
if err != nil {
return false, err
}
if !isNotObsolete {
return false, errors.AssertionFailedf("block with synthetic suffix is obselete")
}
return true, nil
}

func propToIsObsolete(prop []byte) (bool, error) {
if len(prop) == 0 {
return true, nil
}
if len(prop) > 1 || prop[0] != 't' {
return false, errors.Errorf("unexpected property %x", prop)
}
return false, nil
}

0 comments on commit b7e5e71

Please sign in to comment.