mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 10:27:26 +08:00
123 lines
2.9 KiB
Go
123 lines
2.9 KiB
Go
// Copyright 2011 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 "sync/atomic"
|
|
|
|
// FilterMetrics holds metrics for the filter policy.
|
|
type FilterMetrics struct {
|
|
// The number of hits for the filter policy. This is the
|
|
// number of times the filter policy was successfully used to avoid access
|
|
// of a data block.
|
|
Hits int64
|
|
// The number of misses for the filter policy. This is the number of times
|
|
// the filter policy was checked but was unable to filter an access of a data
|
|
// block.
|
|
Misses int64
|
|
}
|
|
|
|
// FilterMetricsTracker is used to keep track of filter metrics. It contains the
|
|
// same metrics as FilterMetrics, but they can be updated atomically. An
|
|
// instance of FilterMetricsTracker can be passed to a Reader as a ReaderOption.
|
|
type FilterMetricsTracker struct {
|
|
// See FilterMetrics.Hits.
|
|
hits atomic.Int64
|
|
// See FilterMetrics.Misses.
|
|
misses atomic.Int64
|
|
}
|
|
|
|
var _ ReaderOption = (*FilterMetricsTracker)(nil)
|
|
|
|
func (m *FilterMetricsTracker) readerApply(r *Reader) {
|
|
if r.tableFilter != nil {
|
|
r.tableFilter.metrics = m
|
|
}
|
|
}
|
|
|
|
// Load returns the current values as FilterMetrics.
|
|
func (m *FilterMetricsTracker) Load() FilterMetrics {
|
|
return FilterMetrics{
|
|
Hits: m.hits.Load(),
|
|
Misses: m.misses.Load(),
|
|
}
|
|
}
|
|
|
|
// BlockHandle is the file offset and length of a block.
|
|
type BlockHandle struct {
|
|
Offset, Length uint64
|
|
}
|
|
|
|
// BlockHandleWithProperties is used for data blocks and first/lower level
|
|
// index blocks, since they can be annotated using BlockPropertyCollectors.
|
|
type BlockHandleWithProperties struct {
|
|
BlockHandle
|
|
Props []byte
|
|
}
|
|
|
|
type filterWriter interface {
|
|
addKey(key []byte)
|
|
finish() ([]byte, error)
|
|
metaName() string
|
|
policyName() string
|
|
}
|
|
|
|
type tableFilterReader struct {
|
|
policy FilterPolicy
|
|
metrics *FilterMetricsTracker
|
|
}
|
|
|
|
func newTableFilterReader(policy FilterPolicy) *tableFilterReader {
|
|
return &tableFilterReader{
|
|
policy: policy,
|
|
metrics: nil,
|
|
}
|
|
}
|
|
|
|
func (f *tableFilterReader) mayContain(data, key []byte) bool {
|
|
mayContain := f.policy.MayContain(TableFilter, data, key)
|
|
if f.metrics != nil {
|
|
if mayContain {
|
|
f.metrics.misses.Add(1)
|
|
} else {
|
|
f.metrics.hits.Add(1)
|
|
}
|
|
}
|
|
return mayContain
|
|
}
|
|
|
|
type tableFilterWriter struct {
|
|
policy FilterPolicy
|
|
writer FilterWriter
|
|
// count is the count of the number of keys added to the filter.
|
|
count int
|
|
}
|
|
|
|
func newTableFilterWriter(policy FilterPolicy) *tableFilterWriter {
|
|
return &tableFilterWriter{
|
|
policy: policy,
|
|
writer: policy.NewWriter(TableFilter),
|
|
}
|
|
}
|
|
|
|
func (f *tableFilterWriter) addKey(key []byte) {
|
|
f.count++
|
|
f.writer.AddKey(key)
|
|
}
|
|
|
|
func (f *tableFilterWriter) finish() ([]byte, error) {
|
|
if f.count == 0 {
|
|
return nil, nil
|
|
}
|
|
return f.writer.Finish(nil), nil
|
|
}
|
|
|
|
func (f *tableFilterWriter) metaName() string {
|
|
return "fullfilter." + f.policy.Name()
|
|
}
|
|
|
|
func (f *tableFilterWriter) policyName() string {
|
|
return f.policy.Name()
|
|
}
|