github.com/MetalBlockchain/metalgo@v1.11.9/snow/engine/avalanche/state/prefixed_state.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package state 5 6 import ( 7 "github.com/MetalBlockchain/metalgo/cache" 8 "github.com/MetalBlockchain/metalgo/ids" 9 "github.com/MetalBlockchain/metalgo/snow/choices" 10 "github.com/MetalBlockchain/metalgo/snow/engine/avalanche/vertex" 11 ) 12 13 const ( 14 vtxID uint64 = iota 15 vtxStatusID 16 edgeID 17 ) 18 19 var uniqueEdgeID = ids.Empty.Prefix(edgeID) 20 21 type prefixedState struct { 22 state *state 23 24 vtx, status cache.Cacher[ids.ID, ids.ID] 25 uniqueVtx cache.Deduplicator[ids.ID, *uniqueVertex] 26 } 27 28 func newPrefixedState(state *state, idCacheSizes int) *prefixedState { 29 return &prefixedState{ 30 state: state, 31 vtx: &cache.LRU[ids.ID, ids.ID]{Size: idCacheSizes}, 32 status: &cache.LRU[ids.ID, ids.ID]{Size: idCacheSizes}, 33 uniqueVtx: &cache.EvictableLRU[ids.ID, *uniqueVertex]{Size: idCacheSizes}, 34 } 35 } 36 37 func (s *prefixedState) UniqueVertex(vtx *uniqueVertex) *uniqueVertex { 38 return s.uniqueVtx.Deduplicate(vtx) 39 } 40 41 func (s *prefixedState) Vertex(id ids.ID) vertex.StatelessVertex { 42 var ( 43 vID ids.ID 44 ok bool 45 ) 46 if vID, ok = s.vtx.Get(id); !ok { 47 vID = id.Prefix(vtxID) 48 s.vtx.Put(id, vID) 49 } 50 51 return s.state.Vertex(vID) 52 } 53 54 func (s *prefixedState) SetVertex(vtx vertex.StatelessVertex) error { 55 var ( 56 rawVertexID = vtx.ID() 57 vID ids.ID 58 ok bool 59 ) 60 if vID, ok = s.vtx.Get(rawVertexID); !ok { 61 vID = rawVertexID.Prefix(vtxID) 62 s.vtx.Put(rawVertexID, vID) 63 } 64 65 return s.state.SetVertex(vID, vtx) 66 } 67 68 func (s *prefixedState) Status(id ids.ID) choices.Status { 69 var ( 70 sID ids.ID 71 ok bool 72 ) 73 if sID, ok = s.status.Get(id); !ok { 74 sID = id.Prefix(vtxStatusID) 75 s.status.Put(id, sID) 76 } 77 78 return s.state.Status(sID) 79 } 80 81 func (s *prefixedState) SetStatus(id ids.ID, status choices.Status) error { 82 var ( 83 sID ids.ID 84 ok bool 85 ) 86 if sID, ok = s.status.Get(id); !ok { 87 sID = id.Prefix(vtxStatusID) 88 s.status.Put(id, sID) 89 } 90 91 return s.state.SetStatus(sID, status) 92 } 93 94 func (s *prefixedState) Edge() []ids.ID { 95 return s.state.Edge(uniqueEdgeID) 96 } 97 98 func (s *prefixedState) SetEdge(frontier []ids.ID) error { 99 return s.state.SetEdge(uniqueEdgeID, frontier) 100 }