github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/vecmt/index.go (about) 1 package vecmt 2 3 import ( 4 "github.com/syndtr/goleveldb/leveldb/opt" 5 "github.com/unicornultrafoundation/go-helios/hash" 6 "github.com/unicornultrafoundation/go-helios/native/dag" 7 "github.com/unicornultrafoundation/go-helios/native/idx" 8 "github.com/unicornultrafoundation/go-helios/native/pos" 9 "github.com/unicornultrafoundation/go-helios/u2udb" 10 "github.com/unicornultrafoundation/go-helios/u2udb/table" 11 "github.com/unicornultrafoundation/go-helios/utils/cachescale" 12 "github.com/unicornultrafoundation/go-helios/utils/wlru" 13 "github.com/unicornultrafoundation/go-helios/vecengine" 14 "github.com/unicornultrafoundation/go-helios/vecengine/vecflushable" 15 "github.com/unicornultrafoundation/go-helios/vecfc" 16 ) 17 18 // IndexCacheConfig - config for cache sizes of Engine 19 type IndexCacheConfig struct { 20 HighestBeforeTimeSize uint 21 DBCache int 22 } 23 24 // IndexConfig - Engine config (cache sizes) 25 type IndexConfig struct { 26 Fc vecfc.IndexConfig 27 Caches IndexCacheConfig 28 } 29 30 // Index is a data to detect forkless-cause condition, calculate median timestamp, detect forks. 31 type Index struct { 32 *vecfc.Index 33 Base *vecfc.Index 34 baseCallbacks vecengine.Callbacks 35 36 crit func(error) 37 validators *pos.Validators 38 validatorIdxs map[idx.ValidatorID]idx.Validator 39 40 getEvent func(hash.Event) dag.Event 41 42 vecDb u2udb.Store 43 table struct { 44 HighestBeforeTime u2udb.Store `table:"T"` 45 } 46 47 cache struct { 48 HighestBeforeTime *wlru.Cache 49 } 50 51 cfg IndexConfig 52 } 53 54 // DefaultConfig returns default index config 55 func DefaultConfig(scale cachescale.Func) IndexConfig { 56 return IndexConfig{ 57 Fc: vecfc.DefaultConfig(scale), 58 Caches: IndexCacheConfig{ 59 HighestBeforeTimeSize: scale.U(160 * 1024), 60 DBCache: scale.I(10 * opt.MiB), 61 }, 62 } 63 } 64 65 // LiteConfig returns default index config for tests 66 func LiteConfig() IndexConfig { 67 return IndexConfig{ 68 Fc: vecfc.LiteConfig(), 69 Caches: IndexCacheConfig{ 70 HighestBeforeTimeSize: 4 * 1024, 71 }, 72 } 73 } 74 75 // NewIndex creates Index instance. 76 func NewIndex(crit func(error), config IndexConfig) *Index { 77 vi := &Index{ 78 cfg: config, 79 crit: crit, 80 } 81 engine := vecengine.NewIndex(crit, vi.GetEngineCallbacks()) 82 83 vi.Base = vecfc.NewIndexWithEngine(crit, config.Fc, engine) 84 vi.Index = vi.Base 85 vi.baseCallbacks = vi.Base.GetEngineCallbacks() 86 vi.initCaches() 87 88 return vi 89 } 90 91 func NewIndexWithBase(crit func(error), config IndexConfig, base *vecfc.Index) *Index { 92 vi := &Index{ 93 Index: base, 94 Base: base, 95 baseCallbacks: base.GetEngineCallbacks(), 96 cfg: config, 97 crit: crit, 98 } 99 vi.initCaches() 100 101 return vi 102 } 103 104 func (vi *Index) initCaches() { 105 vi.cache.HighestBeforeTime, _ = wlru.New(vi.cfg.Caches.HighestBeforeTimeSize, int(vi.cfg.Caches.HighestBeforeTimeSize)) 106 } 107 108 // Reset resets buffers. 109 func (vi *Index) Reset(validators *pos.Validators, db u2udb.Store, getEvent func(hash.Event) dag.Event) { 110 fdb := vecflushable.Wrap(db, vi.cfg.Caches.DBCache) 111 vi.vecDb = fdb 112 vi.Base.Reset(validators, fdb, getEvent) 113 vi.getEvent = getEvent 114 vi.validators = validators 115 vi.validatorIdxs = validators.Idxs() 116 vi.onDropNotFlushed() 117 118 table.MigrateTables(&vi.table, vi.vecDb) 119 } 120 121 func (vi *Index) GetEngineCallbacks() vecengine.Callbacks { 122 return vecengine.Callbacks{ 123 GetHighestBefore: func(event hash.Event) vecengine.HighestBeforeI { 124 return vi.GetHighestBefore(event) 125 }, 126 GetLowestAfter: func(event hash.Event) vecengine.LowestAfterI { 127 return vi.baseCallbacks.GetLowestAfter(event) 128 }, 129 SetHighestBefore: func(event hash.Event, b vecengine.HighestBeforeI) { 130 vi.SetHighestBefore(event, b.(*HighestBefore)) 131 }, 132 SetLowestAfter: func(event hash.Event, i vecengine.LowestAfterI) { 133 vi.baseCallbacks.SetLowestAfter(event, i) 134 }, 135 NewHighestBefore: func(size idx.Validator) vecengine.HighestBeforeI { 136 return NewHighestBefore(size) 137 }, 138 NewLowestAfter: func(size idx.Validator) vecengine.LowestAfterI { 139 return vi.baseCallbacks.NewLowestAfter(size) 140 }, 141 OnDropNotFlushed: func() { 142 vi.baseCallbacks.OnDropNotFlushed() 143 vi.onDropNotFlushed() 144 }, 145 } 146 } 147 148 func (vi *Index) onDropNotFlushed() { 149 vi.cache.HighestBeforeTime.Purge() 150 } 151 152 // GetMergedHighestBefore returns HighestBefore vector clock without branches, where branches are merged into one 153 func (vi *Index) GetMergedHighestBefore(id hash.Event) *HighestBefore { 154 return vi.Engine.GetMergedHighestBefore(id).(*HighestBefore) 155 }