github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/acm/acmstate/metadata_cache.go (about) 1 package acmstate 2 3 import ( 4 "sync" 5 ) 6 7 type metadataInfo struct { 8 metadata string 9 updated bool 10 } 11 12 type MetadataCache struct { 13 backend MetadataReader 14 m sync.Map 15 } 16 17 func NewMetadataCache(backend MetadataReader) *MetadataCache { 18 return &MetadataCache{ 19 backend: backend, 20 } 21 } 22 23 func (cache *MetadataCache) SetMetadata(metahash MetadataHash, metadata string) error { 24 cache.m.Store(metahash, &metadataInfo{updated: true, metadata: metadata}) 25 return nil 26 } 27 28 func (cache *MetadataCache) GetMetadata(metahash MetadataHash) (string, error) { 29 metaInfo, err := cache.getMetadata(metahash) 30 if err != nil { 31 return "", err 32 } 33 34 return metaInfo.metadata, nil 35 } 36 37 // Syncs changes to the backend in deterministic order. Sends storage updates before updating 38 // the account they belong so that storage values can be taken account of in the update. 39 func (cache *MetadataCache) Sync(st MetadataWriter) error { 40 var err error 41 cache.m.Range(func(key, value interface{}) bool { 42 hash := key.(MetadataHash) 43 info := value.(*metadataInfo) 44 if info.updated { 45 err = st.SetMetadata(hash, info.metadata) 46 if err != nil { 47 return false 48 } 49 } 50 return true 51 }) 52 if err != nil { 53 return err 54 } 55 return nil 56 } 57 58 func (cache *MetadataCache) Reset(backend MetadataReader) { 59 cache.backend = backend 60 cache.m = sync.Map{} 61 } 62 63 // Get the cache accountInfo item creating it if necessary 64 func (cache *MetadataCache) getMetadata(metahash MetadataHash) (*metadataInfo, error) { 65 value, ok := cache.m.Load(metahash) 66 if !ok { 67 metadata, err := cache.backend.GetMetadata(metahash) 68 if err != nil { 69 return nil, err 70 } 71 metaInfo := &metadataInfo{ 72 metadata: metadata, 73 } 74 cache.m.Store(metahash, metaInfo) 75 return metaInfo, nil 76 } 77 return value.(*metadataInfo), nil 78 }