github.com/scottcagno/storage@v1.8.0/pkg/lsmt/sstable/_sparse.go (about) 1 package sstable 2 3 import ( 4 "fmt" 5 "github.com/scottcagno/storage/pkg/lsmt/binary" 6 "github.com/scottcagno/storage/pkg/lsmt/trees/rbtree" 7 "strings" 8 ) 9 10 type sparseIndexEntry struct { 11 LastKey string 12 SSTIndex int64 13 IndexEntry *binary.Index 14 } 15 16 func (r sparseIndexEntry) Compare(that rbtree.RBEntry) int { 17 return strings.Compare(r.LastKey, that.(sparseIndexEntry).LastKey) 18 } 19 20 func (r sparseIndexEntry) Size() int { 21 return len(r.LastKey) + 8 22 } 23 24 func (r sparseIndexEntry) String() string { 25 return fmt.Sprintf("entry.LastKey=%q", r.LastKey) 26 } 27 28 type SparseIndex struct { 29 rbt *rbtree.RBTree 30 } 31 32 func NewSparseIndex() *SparseIndex { 33 return &SparseIndex{ 34 rbt: rbtree.NewRBTree(), 35 } 36 } 37 38 func (s *SparseIndex) Put(last string, index int64) { 39 s.rbt.Put(sparseIndexEntry{ 40 LastKey: last, 41 SSTIndex: index, 42 }) 43 } 44 45 /* 46 47 func ratio(n int64) int64 { 48 if n < 1 { 49 return 0 50 } 51 if n == 1 { 52 n++ 53 } 54 return int64(math.Log2(float64(n))) 55 } 56 57 func makeNewSparseIndex(index int64, ssi *SSTIndex) *SparseIndex { 58 spi := &SparseIndex{ 59 rbt: rbtree.NewRBTree(), 60 } 61 count := int64(ssi.Len()) 62 n, i := ratio(count), int64(0) 63 ssi.Scan(func(k string, off int64) bool { 64 if i%(count/n) == 0 { 65 spi.rbt.Put(sparseIndexEntry{Key: k, Path: index, Index: &binary.Index{Key: []byte(k), Offset: off}}) 66 } 67 i++ 68 return true 69 }) 70 return spi 71 } 72 73 func (spi *SparseIndex) Search(k string) (int64, int64) { 74 v, _ := spi.rbt.GetNearMin(sparseIndexEntry{Key: k}) 75 return v.(sparseIndexEntry).Path, v.(sparseIndexEntry).Index.Offset 76 } 77 78 func (spi *SparseIndex) HasKey(k string) bool { 79 key := sparseIndexEntry{Key: k} 80 _, prev, next, ok := spi.rbt.GetApproxPrevNext(key) 81 if ok { 82 return true 83 } 84 if prev.Compare(key) == -1 && key.Compare(next) == -1 { 85 return true 86 } 87 return false 88 } 89 */