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() {}