github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/store_event.go (about) 1 package gossip 2 3 /* 4 In LRU cache data stored like pointer 5 */ 6 7 import ( 8 "bytes" 9 10 "github.com/unicornultrafoundation/go-helios/hash" 11 "github.com/unicornultrafoundation/go-helios/native/idx" 12 "github.com/unicornultrafoundation/go-u2u/ethdb" 13 "github.com/unicornultrafoundation/go-u2u/rlp" 14 15 "github.com/unicornultrafoundation/go-u2u/native" 16 ) 17 18 // DelEvent deletes event. 19 func (s *Store) DelEvent(id hash.Event) { 20 key := id.Bytes() 21 22 err := s.table.Events.Delete(key) 23 if err != nil { 24 s.Log.Crit("Failed to delete key", "err", err) 25 } 26 27 // Remove from LRU cache. 28 s.cache.Events.Remove(id) 29 s.cache.EventsHeaders.Remove(id) 30 s.cache.EventIDs.Remove(id) 31 } 32 33 // SetEvent stores event. 34 func (s *Store) SetEvent(e *native.EventPayload) { 35 key := e.ID().Bytes() 36 37 s.rlp.Set(s.table.Events, key, e) 38 39 // Add to LRU cache. 40 s.cache.Events.Add(e.ID(), e, uint(e.Size())) 41 eh := e.Event 42 s.cache.EventsHeaders.Add(e.ID(), &eh, nominalSize) 43 s.cache.EventIDs.Add(e.ID()) 44 } 45 46 // GetEventPayload returns stored event. 47 func (s *Store) GetEventPayload(id hash.Event) *native.EventPayload { 48 // Get event from LRU cache first. 49 if ev, ok := s.cache.Events.Get(id); ok { 50 return ev.(*native.EventPayload) 51 } 52 53 key := id.Bytes() 54 w, _ := s.rlp.Get(s.table.Events, key, &native.EventPayload{}).(*native.EventPayload) 55 56 if w != nil { 57 fixEventTxHashes(w) 58 } 59 60 // Put event to LRU cache. 61 if w != nil { 62 s.cache.Events.Add(id, w, uint(w.Size())) 63 eh := w.Event 64 s.cache.EventsHeaders.Add(id, &eh, nominalSize) 65 } 66 67 return w 68 } 69 70 // GetEvent returns stored event. 71 func (s *Store) GetEvent(id hash.Event) *native.Event { 72 // Get event from LRU cache first. 73 if ev, ok := s.cache.EventsHeaders.Get(id); ok { 74 return ev.(*native.Event) 75 } 76 77 key := id.Bytes() 78 w, _ := s.rlp.Get(s.table.Events, key, &native.EventPayload{}).(*native.EventPayload) 79 if w == nil { 80 return nil 81 } 82 fixEventTxHashes(w) 83 84 eh := w.Event 85 86 // Put event to LRU cache. 87 s.cache.Events.Add(id, w, uint(w.Size())) 88 s.cache.EventsHeaders.Add(id, &eh, nominalSize) 89 90 return &eh 91 } 92 93 func (s *Store) forEachEvent(it ethdb.Iterator, onEvent func(event *native.EventPayload) bool) { 94 for it.Next() { 95 event := &native.EventPayload{} 96 err := rlp.DecodeBytes(it.Value(), event) 97 if err != nil { 98 s.Log.Crit("Failed to decode event", "err", err) 99 } 100 101 if !onEvent(event) { 102 return 103 } 104 } 105 } 106 107 func (s *Store) ForEachEpochEvent(epoch idx.Epoch, onEvent func(event *native.EventPayload) bool) { 108 it := s.table.Events.NewIterator(epoch.Bytes(), nil) 109 defer it.Release() 110 s.forEachEvent(it, onEvent) 111 } 112 113 func (s *Store) ForEachEvent(start idx.Epoch, onEvent func(event *native.EventPayload) bool) { 114 it := s.table.Events.NewIterator(nil, start.Bytes()) 115 defer it.Release() 116 s.forEachEvent(it, onEvent) 117 } 118 119 func (s *Store) ForEachEventRLP(start []byte, onEvent func(key hash.Event, event rlp.RawValue) bool) { 120 it := s.table.Events.NewIterator(nil, start) 121 defer it.Release() 122 for it.Next() { 123 if !onEvent(hash.BytesToEvent(it.Key()), it.Value()) { 124 return 125 } 126 } 127 } 128 129 func (s *Store) FindEventHashes(epoch idx.Epoch, lamport idx.Lamport, hashPrefix []byte) hash.Events { 130 prefix := bytes.NewBuffer(epoch.Bytes()) 131 prefix.Write(lamport.Bytes()) 132 prefix.Write(hashPrefix) 133 res := make(hash.Events, 0, 10) 134 135 it := s.table.Events.NewIterator(prefix.Bytes(), nil) 136 defer it.Release() 137 for it.Next() { 138 res = append(res, hash.BytesToEvent(it.Key())) 139 } 140 141 return res 142 } 143 144 // GetEventPayloadRLP returns stored event. Serialized. 145 func (s *Store) GetEventPayloadRLP(id hash.Event) rlp.RawValue { 146 key := id.Bytes() 147 148 data, err := s.table.Events.Get(key) 149 if err != nil { 150 s.Log.Crit("Failed to get key-value", "err", err) 151 } 152 return data 153 } 154 155 // HasEvent returns true if event exists. 156 func (s *Store) HasEvent(h hash.Event) bool { 157 if has, ok := s.cache.EventIDs.Has(h); ok { 158 return has 159 } 160 has, _ := s.table.Events.Has(h.Bytes()) 161 return has 162 } 163 164 func (s *Store) loadHighestLamport() idx.Lamport { 165 lamportBytes, err := s.table.HighestLamport.Get([]byte("k")) 166 if err != nil { 167 s.Log.Crit("Failed to get key-value", "err", err) 168 } 169 if lamportBytes == nil { 170 return 0 171 } 172 return idx.BytesToLamport(lamportBytes) 173 } 174 175 func (s *Store) getCachedHighestLamport() (idx.Lamport, bool) { 176 cache := s.cache.HighestLamport.Load() 177 if cache != nil { 178 return cache.(idx.Lamport), true 179 } 180 return 0, false 181 } 182 183 func (s *Store) GetHighestLamport() idx.Lamport { 184 cached, ok := s.getCachedHighestLamport() 185 if ok { 186 return cached 187 } 188 lamport := s.loadHighestLamport() 189 s.cache.HighestLamport.Store(lamport) 190 return lamport 191 } 192 193 func (s *Store) SetHighestLamport(lamport idx.Lamport) { 194 s.cache.HighestLamport.Store(lamport) 195 } 196 197 func (s *Store) FlushHighestLamport() { 198 cached, ok := s.getCachedHighestLamport() 199 if !ok { 200 return 201 } 202 err := s.table.HighestLamport.Put([]byte("k"), cached.Bytes()) 203 if err != nil { 204 s.Log.Crit("Failed to put key-value", "err", err) 205 } 206 }