swarm: add database abstractions (shed package) (#18183)

This commit is contained in:
Janoš Guljaš
2018-11-26 18:49:01 +01:00
committed by Anton Evangelatov
parent 4f0d978eaa
commit c207edf2a3
18 changed files with 2287 additions and 0 deletions

View File

@ -86,6 +86,13 @@ func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error {
return s.db.Write(batch, nil)
}
// Delete removes the chunk reference to node with address addr.
func (s *GlobalStore) Delete(addr common.Address, key []byte) error {
batch := new(leveldb.Batch)
batch.Delete(nodeDBKey(addr, key))
return s.db.Write(batch, nil)
}
// HasKey returns whether a node with addr contains the key.
func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool {
has, err := s.db.Has(nodeDBKey(addr, key), nil)

View File

@ -83,6 +83,22 @@ func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error {
return nil
}
// Delete removes the chunk data for node with address addr.
func (s *GlobalStore) Delete(addr common.Address, key []byte) error {
s.mu.Lock()
defer s.mu.Unlock()
var count int
if _, ok := s.nodes[string(key)]; ok {
delete(s.nodes[string(key)], addr)
count = len(s.nodes[string(key)])
}
if count == 0 {
delete(s.data, string(key))
}
return nil
}
// HasKey returns whether a node with addr contains the key.
func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool {
s.mu.Lock()

View File

@ -70,6 +70,12 @@ func (n *NodeStore) Put(key []byte, data []byte) error {
return n.store.Put(n.addr, key, data)
}
// Delete removes chunk data for a key for a node that has the address
// provided on NodeStore initialization.
func (n *NodeStore) Delete(key []byte) error {
return n.store.Delete(n.addr, key)
}
// GlobalStorer defines methods for mock db store
// that stores chunk data for all swarm nodes.
// It is used in tests to construct mock NodeStores
@ -77,6 +83,7 @@ func (n *NodeStore) Put(key []byte, data []byte) error {
type GlobalStorer interface {
Get(addr common.Address, key []byte) (data []byte, err error)
Put(addr common.Address, key []byte, data []byte) error
Delete(addr common.Address, key []byte) error
HasKey(addr common.Address, key []byte) bool
// NewNodeStore creates an instance of NodeStore
// to be used by a single swarm node with

View File

@ -73,6 +73,12 @@ func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error {
return err
}
// Delete calls a Delete method to RPC server.
func (s *GlobalStore) Delete(addr common.Address, key []byte) error {
err := s.client.Call(nil, "mockStore_delete", addr, key)
return err
}
// HasKey calls a HasKey method to RPC server.
func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool {
var has bool

View File

@ -72,6 +72,31 @@ func MockStore(t *testing.T, globalStore mock.GlobalStorer, n int) {
}
}
}
t.Run("delete", func(t *testing.T) {
chunkAddr := storage.Address([]byte("1234567890abcd"))
for _, addr := range addrs {
err := globalStore.Put(addr, chunkAddr, []byte("data"))
if err != nil {
t.Fatalf("put data to store %s key %s: %v", addr.Hex(), chunkAddr.Hex(), err)
}
}
firstNodeAddr := addrs[0]
if err := globalStore.Delete(firstNodeAddr, chunkAddr); err != nil {
t.Fatalf("delete from store %s key %s: %v", firstNodeAddr.Hex(), chunkAddr.Hex(), err)
}
for i, addr := range addrs {
_, err := globalStore.Get(addr, chunkAddr)
if i == 0 {
if err != mock.ErrNotFound {
t.Errorf("get data from store %s key %s: expected mock.ErrNotFound error, got %v", addr.Hex(), chunkAddr.Hex(), err)
}
} else {
if err != nil {
t.Errorf("get data from store %s key %s: %v", addr.Hex(), chunkAddr.Hex(), err)
}
}
}
})
})
t.Run("NodeStore", func(t *testing.T) {
@ -114,6 +139,34 @@ func MockStore(t *testing.T, globalStore mock.GlobalStorer, n int) {
}
}
}
t.Run("delete", func(t *testing.T) {
chunkAddr := storage.Address([]byte("1234567890abcd"))
var chosenStore *mock.NodeStore
for addr, store := range nodes {
if chosenStore == nil {
chosenStore = store
}
err := store.Put(chunkAddr, []byte("data"))
if err != nil {
t.Fatalf("put data to store %s key %s: %v", addr.Hex(), chunkAddr.Hex(), err)
}
}
if err := chosenStore.Delete(chunkAddr); err != nil {
t.Fatalf("delete key %s: %v", chunkAddr.Hex(), err)
}
for addr, store := range nodes {
_, err := store.Get(chunkAddr)
if store == chosenStore {
if err != mock.ErrNotFound {
t.Errorf("get data from store %s key %s: expected mock.ErrNotFound error, got %v", addr.Hex(), chunkAddr.Hex(), err)
}
} else {
if err != nil {
t.Errorf("get data from store %s key %s: %v", addr.Hex(), chunkAddr.Hex(), err)
}
}
}
})
})
}