go-ethereum/swarm/storage/localstore.go
Janos Guljas 86625af2aa cmd/swarm, swarm: implement mock datastore (#161)
Packages under swarm/storage/mock define and implement mock storages that
keep chunk data of all swarm nodes in a centralized way for testing
purposes. They provide:
  - create individual swarm node mock stores that can be injected to
    swarm to bypass the DbStore chunk data storing
  - methods to inspect on which nodes are chunk stored
  - import/export functionality

Three implementations of mock stores are:
  - swarm/storage/mem - a memory backed storage
  - swarm/storage/db - a LevelDB backed storage
  - swarm/storage/rpc - a storage that connects to other storages by RPC

Bypassing is done only for the chunk data, not for the local chunk indexes
that DbStore creates which can not be shared between swarm nodes.
2018-01-15 16:44:16 +01:00

82 lines
2.5 KiB
Go

// Copyright 2016 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package storage
import (
"encoding/binary"
"github.com/ethereum/go-ethereum/swarm/storage/mock"
)
// LocalStore is a combination of inmemory db over a disk persisted db
// implements a Get/Put with fallback (caching) logic using any 2 ChunkStores
type LocalStore struct {
memStore ChunkStore
DbStore ChunkStore
}
// This constructor uses MemStore and DbStore as components.
// If mockStore is not nil, it will be used by DbStore to store chunk data.
func NewLocalStore(hash SwarmHasher, params *StoreParams, mockStore mock.NodeStorer) (*LocalStore, error) {
dbStore, err := NewMockDbStore(params.ChunkDbPath, hash, params.DbCapacity, params.Radius, mockStore)
if err != nil {
return nil, err
}
return &LocalStore{
memStore: NewMemStore(dbStore, params.CacheCapacity),
DbStore: dbStore,
}, nil
}
// LocalStore is itself a chunk store
// unsafe, in that the data is not integrity checked
func (self *LocalStore) Put(chunk *Chunk) {
chunk.dbStored = make(chan bool)
self.memStore.Put(chunk)
if chunk.wg != nil {
chunk.wg.Add(1)
}
go func() {
self.DbStore.Put(chunk)
if chunk.wg != nil {
chunk.wg.Done()
}
}()
}
// Get(chunk *Chunk) looks up a chunk in the local stores
// This method is blocking until the chunk is retrieved
// so additional timeout may be needed to wrap this call if
// ChunkStores are remote and can have long latency
func (self *LocalStore) Get(key Key) (chunk *Chunk, err error) {
chunk, err = self.memStore.Get(key)
if err == nil {
return
}
chunk, err = self.DbStore.Get(key)
if err != nil {
return
}
chunk.Size = int64(binary.LittleEndian.Uint64(chunk.SData[0:8]))
self.memStore.Put(chunk)
return
}
// Close local store
func (self *LocalStore) Close() {
self.DbStore.Close()
}