github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/swarm/storage/localstore.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package storage 13 14 import ( 15 "encoding/binary" 16 17 "github.com/Sberex/go-sberex/metrics" 18 ) 19 20 //metrics variables 21 var ( 22 dbStorePutCounter = metrics.NewRegisteredCounter("storage.db.dbstore.put.count", nil) 23 ) 24 25 // LocalStore is a combination of inmemory db over a disk persisted db 26 // implements a Get/Put with fallback (caching) logic using any 2 ChunkStores 27 type LocalStore struct { 28 memStore ChunkStore 29 DbStore ChunkStore 30 } 31 32 // This constructor uses MemStore and DbStore as components 33 func NewLocalStore(hash SwarmHasher, params *StoreParams) (*LocalStore, error) { 34 dbStore, err := NewDbStore(params.ChunkDbPath, hash, params.DbCapacity, params.Radius) 35 if err != nil { 36 return nil, err 37 } 38 return &LocalStore{ 39 memStore: NewMemStore(dbStore, params.CacheCapacity), 40 DbStore: dbStore, 41 }, nil 42 } 43 44 func (self *LocalStore) CacheCounter() uint64 { 45 return uint64(self.memStore.(*MemStore).Counter()) 46 } 47 48 func (self *LocalStore) DbCounter() uint64 { 49 return self.DbStore.(*DbStore).Counter() 50 } 51 52 // LocalStore is itself a chunk store 53 // unsafe, in that the data is not integrity checked 54 func (self *LocalStore) Put(chunk *Chunk) { 55 chunk.dbStored = make(chan bool) 56 self.memStore.Put(chunk) 57 if chunk.wg != nil { 58 chunk.wg.Add(1) 59 } 60 go func() { 61 dbStorePutCounter.Inc(1) 62 self.DbStore.Put(chunk) 63 if chunk.wg != nil { 64 chunk.wg.Done() 65 } 66 }() 67 } 68 69 // Get(chunk *Chunk) looks up a chunk in the local stores 70 // This method is blocking until the chunk is retrieved 71 // so additional timeout may be needed to wrap this call if 72 // ChunkStores are remote and can have long latency 73 func (self *LocalStore) Get(key Key) (chunk *Chunk, err error) { 74 chunk, err = self.memStore.Get(key) 75 if err == nil { 76 return 77 } 78 chunk, err = self.DbStore.Get(key) 79 if err != nil { 80 return 81 } 82 chunk.Size = int64(binary.LittleEndian.Uint64(chunk.SData[0:8])) 83 self.memStore.Put(chunk) 84 return 85 } 86 87 // Close local store 88 func (self *LocalStore) Close() {}