github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/sstable/filter.go (about)

     1  // Copyright 2011 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 "sync/atomic"
     8  
     9  // FilterMetrics holds metrics for the filter policy.
    10  type FilterMetrics struct {
    11  	// The number of hits for the filter policy. This is the
    12  	// number of times the filter policy was successfully used to avoid access
    13  	// of a data block.
    14  	Hits int64
    15  	// The number of misses for the filter policy. This is the number of times
    16  	// the filter policy was checked but was unable to filter an access of a data
    17  	// block.
    18  	Misses int64
    19  }
    20  
    21  var dummyFilterMetrics FilterMetrics
    22  
    23  func (m *FilterMetrics) readerApply(r *Reader) {
    24  	if r.tableFilter != nil {
    25  		r.tableFilter.metrics = m
    26  	}
    27  }
    28  
    29  // BlockHandle is the file offset and length of a block.
    30  type BlockHandle struct {
    31  	Offset, Length uint64
    32  }
    33  
    34  // BlockHandleWithProperties is used for data blocks and first/lower level
    35  // index blocks, since they can be annotated using BlockPropertyCollectors.
    36  type BlockHandleWithProperties struct {
    37  	BlockHandle
    38  	Props []byte
    39  }
    40  
    41  type filterWriter interface {
    42  	addKey(key []byte)
    43  	finish() ([]byte, error)
    44  	metaName() string
    45  	policyName() string
    46  }
    47  
    48  type tableFilterReader struct {
    49  	policy  FilterPolicy
    50  	metrics *FilterMetrics
    51  }
    52  
    53  func newTableFilterReader(policy FilterPolicy) *tableFilterReader {
    54  	return &tableFilterReader{
    55  		policy:  policy,
    56  		metrics: &dummyFilterMetrics,
    57  	}
    58  }
    59  
    60  func (f *tableFilterReader) mayContain(data, key []byte) bool {
    61  	mayContain := f.policy.MayContain(TableFilter, data, key)
    62  	if mayContain {
    63  		atomic.AddInt64(&f.metrics.Misses, 1)
    64  	} else {
    65  		atomic.AddInt64(&f.metrics.Hits, 1)
    66  	}
    67  	return mayContain
    68  }
    69  
    70  type tableFilterWriter struct {
    71  	policy FilterPolicy
    72  	writer FilterWriter
    73  	// count is the count of the number of keys added to the filter.
    74  	count int
    75  }
    76  
    77  func newTableFilterWriter(policy FilterPolicy) *tableFilterWriter {
    78  	return &tableFilterWriter{
    79  		policy: policy,
    80  		writer: policy.NewWriter(TableFilter),
    81  	}
    82  }
    83  
    84  func (f *tableFilterWriter) addKey(key []byte) {
    85  	f.count++
    86  	f.writer.AddKey(key)
    87  }
    88  
    89  func (f *tableFilterWriter) finish() ([]byte, error) {
    90  	if f.count == 0 {
    91  		return nil, nil
    92  	}
    93  	return f.writer.Finish(nil), nil
    94  }
    95  
    96  func (f *tableFilterWriter) metaName() string {
    97  	return "fullfilter." + f.policy.Name()
    98  }
    99  
   100  func (f *tableFilterWriter) policyName() string {
   101  	return f.policy.Name()
   102  }