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  }