Line data Source code
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 : // FilterMetricsTracker is used to keep track of filter metrics. It contains the 22 : // same metrics as FilterMetrics, but they can be updated atomically. An 23 : // instance of FilterMetricsTracker can be passed to a Reader as a ReaderOption. 24 : type FilterMetricsTracker struct { 25 : // See FilterMetrics.Hits. 26 : hits atomic.Int64 27 : // See FilterMetrics.Misses. 28 : misses atomic.Int64 29 : } 30 : 31 : // Load returns the current values as FilterMetrics. 32 1 : func (m *FilterMetricsTracker) Load() FilterMetrics { 33 1 : return FilterMetrics{ 34 1 : Hits: m.hits.Load(), 35 1 : Misses: m.misses.Load(), 36 1 : } 37 1 : } 38 : 39 : type filterWriter interface { 40 : addKey(key []byte) 41 : finish() ([]byte, error) 42 : metaName() string 43 : policyName() string 44 : } 45 : 46 : type tableFilterReader struct { 47 : policy FilterPolicy 48 : metrics *FilterMetricsTracker 49 : } 50 : 51 1 : func newTableFilterReader(policy FilterPolicy, metrics *FilterMetricsTracker) *tableFilterReader { 52 1 : return &tableFilterReader{ 53 1 : policy: policy, 54 1 : metrics: metrics, 55 1 : } 56 1 : } 57 : 58 1 : func (f *tableFilterReader) mayContain(data, key []byte) bool { 59 1 : mayContain := f.policy.MayContain(TableFilter, data, key) 60 1 : if f.metrics != nil { 61 1 : if mayContain { 62 1 : f.metrics.misses.Add(1) 63 1 : } else { 64 1 : f.metrics.hits.Add(1) 65 1 : } 66 : } 67 1 : 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 1 : func newTableFilterWriter(policy FilterPolicy) *tableFilterWriter { 78 1 : return &tableFilterWriter{ 79 1 : policy: policy, 80 1 : writer: policy.NewWriter(TableFilter), 81 1 : } 82 1 : } 83 : 84 1 : func (f *tableFilterWriter) addKey(key []byte) { 85 1 : f.count++ 86 1 : f.writer.AddKey(key) 87 1 : } 88 : 89 1 : func (f *tableFilterWriter) finish() ([]byte, error) { 90 1 : if f.count == 0 { 91 1 : return nil, nil 92 1 : } 93 1 : return f.writer.Finish(nil), nil 94 : } 95 : 96 1 : func (f *tableFilterWriter) metaName() string { 97 1 : return "fullfilter." + f.policy.Name() 98 1 : } 99 : 100 1 : func (f *tableFilterWriter) policyName() string { 101 1 : return f.policy.Name() 102 1 : }