github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/storage/memstore.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:49</date> 10 //</624342681736187904> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 28 // 29 30 package storage 31 32 import ( 33 "context" 34 "sync" 35 36 lru "github.com/hashicorp/golang-lru" 37 ) 38 39 type MemStore struct { 40 cache *lru.Cache 41 requests *lru.Cache 42 mu sync.RWMutex 43 disabled bool 44 } 45 46 // 47 // 48 // 49 // 50 // 51 // 52 func NewMemStore(params *StoreParams, _ *LDBStore) (m *MemStore) { 53 if params.CacheCapacity == 0 { 54 return &MemStore{ 55 disabled: true, 56 } 57 } 58 59 onEvicted := func(key interface{}, value interface{}) { 60 v := value.(*Chunk) 61 <-v.dbStoredC 62 } 63 c, err := lru.NewWithEvict(int(params.CacheCapacity), onEvicted) 64 if err != nil { 65 panic(err) 66 } 67 68 requestEvicted := func(key interface{}, value interface{}) { 69 // 70 // 71 } 72 r, err := lru.NewWithEvict(int(params.ChunkRequestsCacheCapacity), requestEvicted) 73 if err != nil { 74 panic(err) 75 } 76 77 return &MemStore{ 78 cache: c, 79 requests: r, 80 } 81 } 82 83 func (m *MemStore) Get(ctx context.Context, addr Address) (*Chunk, error) { 84 if m.disabled { 85 return nil, ErrChunkNotFound 86 } 87 88 m.mu.RLock() 89 defer m.mu.RUnlock() 90 91 r, ok := m.requests.Get(string(addr)) 92 // 93 if ok { 94 return r.(*Chunk), nil 95 } 96 97 // 98 c, ok := m.cache.Get(string(addr)) 99 if !ok { 100 return nil, ErrChunkNotFound 101 } 102 return c.(*Chunk), nil 103 } 104 105 func (m *MemStore) Put(ctx context.Context, c *Chunk) { 106 if m.disabled { 107 return 108 } 109 110 m.mu.Lock() 111 defer m.mu.Unlock() 112 113 // 114 if c.ReqC != nil { 115 select { 116 case <-c.ReqC: 117 if c.GetErrored() != nil { 118 m.requests.Remove(string(c.Addr)) 119 return 120 } 121 m.cache.Add(string(c.Addr), c) 122 m.requests.Remove(string(c.Addr)) 123 default: 124 m.requests.Add(string(c.Addr), c) 125 } 126 return 127 } 128 129 // 130 m.cache.Add(string(c.Addr), c) 131 m.requests.Remove(string(c.Addr)) 132 } 133 134 func (m *MemStore) setCapacity(n int) { 135 if n <= 0 { 136 m.disabled = true 137 } else { 138 onEvicted := func(key interface{}, value interface{}) { 139 v := value.(*Chunk) 140 <-v.dbStoredC 141 } 142 c, err := lru.NewWithEvict(n, onEvicted) 143 if err != nil { 144 panic(err) 145 } 146 147 r, err := lru.New(defaultChunkRequestsCacheCapacity) 148 if err != nil { 149 panic(err) 150 } 151 152 m = &MemStore{ 153 cache: c, 154 requests: r, 155 } 156 } 157 } 158 159 func (s *MemStore) Close() {} 160