diff --git a/swarm/storage/memstore.go b/swarm/storage/memstore.go
deleted file mode 100644
index edaa3d217f..0000000000
--- a/swarm/storage/memstore.go
+++ /dev/null
@@ -1,372 +0,0 @@
-// 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 .
-
-// memory storage layer for the package blockhash
-
-package storage
-
-import (
- "bytes"
- "fmt"
- "sync"
-
- "github.com/ethereum/go-ethereum/metrics"
-)
-
-//metrics variables
-var (
- memstorePutCounter = metrics.NewRegisteredCounter("storage.db.memstore.put.count", nil)
- memstoreRemoveCounter = metrics.NewRegisteredCounter("storage.db.memstore.rm.count", nil)
-)
-
-const (
- memTreeLW = 2 // log2(subtree count) of the subtrees
- memTreeFLW = 14 // log2(subtree count) of the root layer
- dbForceUpdateAccessCnt = 1000
- defaultCacheCapacity = 5000
-)
-
-//type MemStore struct {
-//memtree *memTree
-//entryCnt, capacity uint // stored entries
-//accessCnt uint64 // access counter; oldest is thrown away when full
-//dbAccessCnt uint64
-//ldbStore *LDBStore
-//lock sync.Mutex
-//}
-
-/*
-a hash prefix subtree containing subtrees or one storage entry (but never both)
-
-- access[0] stores the smallest (oldest) access count value in this subtree
-- if it contains more subtrees and its subtree count is at least 4, access[1:2]
- stores the smallest access count in the first and second halves of subtrees
- (so that access[0] = min(access[1], access[2])
-- likewise, if subtree count is at least 8,
- access[1] = min(access[3], access[4])
- access[2] = min(access[5], access[6])
- (access[] is a binary tree inside the multi-bit leveled hash tree)
-*/
-
-//func NewMemStore(d *LDBStore, capacity uint) (m *MemStore) {
-//m = &MemStore{}
-//m.memtree = newMemTree(memTreeFLW, nil, 0)
-//m.ldbStore = d
-//m.setCapacity(capacity)
-//return
-//}
-
-//type memTree struct {
-//subtree []*memTree
-//parent *memTree
-//parentIdx uint
-
-//bits uint // log2(subtree count)
-//width uint // subtree count
-
-//entry *Chunk // if subtrees are present, entry should be nil
-//lastDBaccess uint64
-//access []uint64
-//}
-
-//func newMemTree(b uint, parent *memTree, pidx uint) (node *memTree) {
-//node = new(memTree)
-//node.bits = b
-//node.width = 1 << b
-//node.subtree = make([]*memTree, node.width)
-//node.access = make([]uint64, node.width-1)
-//node.parent = parent
-//node.parentIdx = pidx
-//if parent != nil {
-//parent.subtree[pidx] = node
-//}
-
-//return node
-//}
-
-//func (node *memTree) updateAccess(a uint64) {
-//aidx := uint(0)
-//var aa uint64
-//oa := node.access[0]
-//for node.access[aidx] == oa {
-//node.access[aidx] = a
-//if aidx > 0 {
-//aa = node.access[((aidx-1)^1)+1]
-//aidx = (aidx - 1) >> 1
-//} else {
-//pidx := node.parentIdx
-//node = node.parent
-//if node == nil {
-//return
-//}
-//nn := node.subtree[pidx^1]
-//if nn != nil {
-//aa = nn.access[0]
-//} else {
-//aa = 0
-//}
-//aidx = (node.width + pidx - 2) >> 1
-//}
-
-//if (aa != 0) && (aa < a) {
-//a = aa
-//}
-//}
-//}
-
-//func (s *MemStore) setCapacity(c uint) {
-//s.lock.Lock()
-//defer s.lock.Unlock()
-
-//for c < s.entryCnt {
-//s.removeOldest()
-//}
-//s.capacity = c
-//}
-
-//func (s *MemStore) Counter() uint {
-//return s.entryCnt
-//}
-
-//// entry (not its copy) is going to be in MemStore
-//func (s *MemStore) Put(entry *Chunk) {
-//log.Trace("memstore.put", "key", entry.Key)
-//if s.capacity == 0 {
-//return
-//}
-
-//s.lock.Lock()
-//defer s.lock.Unlock()
-
-//if s.entryCnt >= s.capacity {
-//s.removeOldest()
-//}
-
-//s.accessCnt++
-
-//memstorePutCounter.Inc(1)
-
-//node := s.memtree
-//bitpos := uint(0)
-//for node.entry == nil {
-//l := entry.Key.bits(bitpos, node.bits)
-//st := node.subtree[l]
-//if st == nil {
-//st = newMemTree(memTreeLW, node, l)
-//bitpos += node.bits
-//node = st
-//break
-//}
-//bitpos += node.bits
-//node = st
-//}
-
-//if node.entry != nil {
-
-//if node.entry.Key.isEqual(entry.Key) {
-//node.updateAccess(s.accessCnt)
-//if entry.SData == nil {
-//entry.Size = node.entry.Size
-//entry.SData = node.entry.SData
-//}
-//if entry.ReqC == nil {
-//entry.ReqC = node.entry.ReqC
-//}
-//entry.C = node.entry.C
-//node.entry = entry
-//return
-//}
-
-//for node.entry != nil {
-
-//l := node.entry.Key.bits(bitpos, node.bits)
-//st := node.subtree[l]
-//if st == nil {
-//st = newMemTree(memTreeLW, node, l)
-//}
-//st.entry = node.entry
-//node.entry = nil
-//st.updateAccess(node.access[0])
-
-//l = entry.Key.bits(bitpos, node.bits)
-//st = node.subtree[l]
-//if st == nil {
-//st = newMemTree(memTreeLW, node, l)
-//}
-//bitpos += node.bits
-//node = st
-
-//}
-//}
-
-//node.entry = entry
-//node.lastDBaccess = s.dbAccessCnt
-//node.updateAccess(s.accessCnt)
-//s.entryCnt++
-//}
-
-//func (s *MemStore) Get(hash Key) (chunk *Chunk, err error) {
-//log.Trace("memstore.get", "key", hash)
-//s.lock.Lock()
-//defer s.lock.Unlock()
-
-//node := s.memtree
-//bitpos := uint(0)
-//for node.entry == nil {
-//l := hash.bits(bitpos, node.bits)
-//st := node.subtree[l]
-//if st == nil {
-//log.Trace("memstore.get ErrChunkNotFound", "key", hash)
-//return nil, ErrChunkNotFound
-//}
-//bitpos += node.bits
-//node = st
-//}
-
-//if node.entry.Key.isEqual(hash) {
-//s.accessCnt++
-//node.updateAccess(s.accessCnt)
-//chunk = node.entry
-//if s.dbAccessCnt-node.lastDBaccess > dbForceUpdateAccessCnt {
-//s.dbAccessCnt++
-//node.lastDBaccess = s.dbAccessCnt
-//if s.ldbStore != nil {
-//s.ldbStore.updateAccessCnt(hash)
-//}
-//}
-//} else {
-//err = ErrChunkNotFound
-//}
-
-//log.Trace("memstore.get return", "key", hash, "chunk", chunk, "err", err)
-//return
-//}
-
-//func (s *MemStore) removeOldest() {
-//defer metrics.GetOrRegisterResettingTimer("memstore.purge", metrics.DefaultRegistry).UpdateSince(time.Now())
-
-//node := s.memtree
-//log.Warn("purge memstore")
-//for node.entry == nil {
-
-//aidx := uint(0)
-//av := node.access[aidx]
-
-//for aidx < node.width/2-1 {
-//if av == node.access[aidx*2+1] {
-//node.access[aidx] = node.access[aidx*2+2]
-//aidx = aidx*2 + 1
-//} else if av == node.access[aidx*2+2] {
-//node.access[aidx] = node.access[aidx*2+1]
-//aidx = aidx*2 + 2
-//} else {
-//panic(nil)
-//}
-//}
-//pidx := aidx*2 + 2 - node.width
-//if (node.subtree[pidx] != nil) && (av == node.subtree[pidx].access[0]) {
-//if node.subtree[pidx+1] != nil {
-//node.access[aidx] = node.subtree[pidx+1].access[0]
-//} else {
-//node.access[aidx] = 0
-//}
-//} else if (node.subtree[pidx+1] != nil) && (av == node.subtree[pidx+1].access[0]) {
-//if node.subtree[pidx] != nil {
-//node.access[aidx] = node.subtree[pidx].access[0]
-//} else {
-//node.access[aidx] = 0
-//}
-//pidx++
-//} else {
-//panic(nil)
-//}
-
-////fmt.Println(pidx)
-//node = node.subtree[pidx]
-
-//}
-
-//if node.entry.ReqC == nil {
-//log.Trace(fmt.Sprintf("Memstore Clean: Waiting for chunk %v to be saved", node.entry.Key.Log()))
-//<-node.entry.dbStoredC
-//log.Trace(fmt.Sprintf("Memstore Clean: Chunk %v saved to DBStore. Ready to clear from mem.", node.entry.Key.Log()))
-
-//memstoreRemoveCounter.Inc(1)
-//node.entry = nil
-//s.entryCnt--
-//} else {
-//return
-//}
-
-//node.access[0] = 0
-
-////---
-
-//aidx := uint(0)
-//for {
-//aa := node.access[aidx]
-//if aidx > 0 {
-//aidx = (aidx - 1) >> 1
-//} else {
-//pidx := node.parentIdx
-//node = node.parent
-//if node == nil {
-//return
-//}
-//aidx = (node.width + pidx - 2) >> 1
-//}
-//if (aa != 0) && ((aa < node.access[aidx]) || (node.access[aidx] == 0)) {
-//node.access[aidx] = aa
-//}
-//}
-//}
-
-type MemStore struct {
- m map[string]*Chunk
- mu sync.RWMutex
-}
-
-func NewMemStore(d *LDBStore, capacity uint) (m *MemStore) {
- return &MemStore{
- m: make(map[string]*Chunk),
- }
-}
-
-func (m *MemStore) Get(key Key) (*Chunk, error) {
- m.mu.RLock()
- defer m.mu.RUnlock()
- c, ok := m.m[string(key[:])]
- if !ok {
- return nil, ErrChunkNotFound
- }
- if !bytes.Equal(c.Key, key) {
- panic(fmt.Errorf("MemStore.Get: chunk key %s != req key %s", c.Key.Hex(), key.Hex()))
- }
- return c, nil
-}
-
-func (m *MemStore) Put(c *Chunk) {
- m.mu.Lock()
- defer m.mu.Unlock()
- m.m[string(c.Key[:])] = c
-}
-
-func (m *MemStore) setCapacity(n int) {
-
-}
-
-// Close memstore
-func (s *MemStore) Close() {}
diff --git a/swarm/storage/memstore_lrucache.go b/swarm/storage/memstore_lrucache.go
new file mode 100644
index 0000000000..74b6376571
--- /dev/null
+++ b/swarm/storage/memstore_lrucache.go
@@ -0,0 +1,74 @@
+// Copyright 2018 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 .
+
+// memory storage layer for the package blockhash
+
+package storage
+
+import (
+ "bytes"
+ "fmt"
+
+ lru "github.com/hashicorp/golang-lru"
+)
+
+const (
+ defaultCacheCapacity = 5000
+)
+
+type MemStore struct {
+ //cache *lru.ARCCache
+ cache *lru.Cache
+}
+
+func NewMemStore(_ *LDBStore, capacity uint) (m *MemStore) {
+ onEvicted := func(key interface{}, value interface{}) {
+ v := value.(*Chunk)
+ <-v.dbStoredC
+ }
+ c, err := lru.NewWithEvict(int(capacity), onEvicted)
+ if err != nil {
+ panic(err)
+ }
+
+ return &MemStore{
+ //cache: lru.NewARC(capacity),
+ cache: c,
+ }
+}
+
+func (m *MemStore) Get(key Key) (*Chunk, error) {
+ c, ok := m.cache.Get(string(key))
+ if !ok {
+ return nil, ErrChunkNotFound
+ }
+ chunk := c.(*Chunk)
+ if !bytes.Equal(chunk.Key, key) {
+ panic(fmt.Errorf("MemStore.Get: chunk key %s != req key %s", chunk.Key.Hex(), key.Hex()))
+ }
+ return chunk, nil
+}
+
+func (m *MemStore) Put(c *Chunk) {
+ m.cache.Add(string(c.Key), c)
+}
+
+func (m *MemStore) setCapacity(n int) {
+ //no-op
+}
+
+// Close memstore
+func (s *MemStore) Close() {}
diff --git a/swarm/storage/memstore2_test.go b/swarm/storage/memstore_lrucache_test.go
similarity index 100%
rename from swarm/storage/memstore2_test.go
rename to swarm/storage/memstore_lrucache_test.go
diff --git a/swarm/storage/memstore_map.god b/swarm/storage/memstore_map.god
new file mode 100644
index 0000000000..c2f2855268
--- /dev/null
+++ b/swarm/storage/memstore_map.god
@@ -0,0 +1,77 @@
+// 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 .
+
+// memory storage layer for the package blockhash
+
+package storage
+
+import (
+ "bytes"
+ "fmt"
+ "sync"
+
+ "github.com/ethereum/go-ethereum/metrics"
+)
+
+//metrics variables
+var (
+ memstorePutCounter = metrics.NewRegisteredCounter("storage.db.memstore.put.count", nil)
+ memstoreRemoveCounter = metrics.NewRegisteredCounter("storage.db.memstore.rm.count", nil)
+)
+
+const (
+ memTreeLW = 2 // log2(subtree count) of the subtrees
+ memTreeFLW = 14 // log2(subtree count) of the root layer
+ dbForceUpdateAccessCnt = 1000
+ defaultCacheCapacity = 5000
+)
+
+type MemStore struct {
+ m map[string]*Chunk
+ mu sync.RWMutex
+}
+
+func NewMemStore(d *LDBStore, capacity uint) (m *MemStore) {
+ return &MemStore{
+ m: make(map[string]*Chunk),
+ }
+}
+
+func (m *MemStore) Get(key Key) (*Chunk, error) {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+ c, ok := m.m[string(key[:])]
+ if !ok {
+ return nil, ErrChunkNotFound
+ }
+ if !bytes.Equal(c.Key, key) {
+ panic(fmt.Errorf("MemStore.Get: chunk key %s != req key %s", c.Key.Hex(), key.Hex()))
+ }
+ return c, nil
+}
+
+func (m *MemStore) Put(c *Chunk) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ m.m[string(c.Key[:])] = c
+}
+
+func (m *MemStore) setCapacity(n int) {
+
+}
+
+// Close memstore
+func (s *MemStore) Close() {}
diff --git a/swarm/storage/memstore_tree.god b/swarm/storage/memstore_tree.god
new file mode 100644
index 0000000000..3e5c025daa
--- /dev/null
+++ b/swarm/storage/memstore_tree.god
@@ -0,0 +1,373 @@
+// 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 .
+
+// memory storage layer for the package blockhash
+
+package storage
+
+import (
+ "fmt"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
+)
+
+//metrics variables
+var (
+ memstorePutCounter = metrics.NewRegisteredCounter("storage.db.memstore.put.count", nil)
+ memstoreRemoveCounter = metrics.NewRegisteredCounter("storage.db.memstore.rm.count", nil)
+)
+
+const (
+ memTreeLW = 2 // log2(subtree count) of the subtrees
+ memTreeFLW = 14 // log2(subtree count) of the root layer
+ dbForceUpdateAccessCnt = 1000
+ defaultCacheCapacity = 5000
+)
+
+type MemStore struct {
+ memtree *memTree
+ entryCnt, capacity uint // stored entries
+ accessCnt uint64 // access counter; oldest is thrown away when full
+ dbAccessCnt uint64
+ ldbStore *LDBStore
+ lock sync.Mutex
+}
+
+/*
+a hash prefix subtree containing subtrees or one storage entry (but never both)
+
+- access[0] stores the smallest (oldest) access count value in this subtree
+- if it contains more subtrees and its subtree count is at least 4, access[1:2]
+ stores the smallest access count in the first and second halves of subtrees
+ (so that access[0] = min(access[1], access[2])
+- likewise, if subtree count is at least 8,
+ access[1] = min(access[3], access[4])
+ access[2] = min(access[5], access[6])
+ (access[] is a binary tree inside the multi-bit leveled hash tree)
+*/
+
+func NewMemStore(d *LDBStore, capacity uint) (m *MemStore) {
+ m = &MemStore{}
+ m.memtree = newMemTree(memTreeFLW, nil, 0)
+ m.ldbStore = d
+ m.setCapacity(capacity)
+ return
+}
+
+type memTree struct {
+ subtree []*memTree
+ parent *memTree
+ parentIdx uint
+
+ bits uint // log2(subtree count)
+ width uint // subtree count
+
+ entry *Chunk // if subtrees are present, entry should be nil
+ lastDBaccess uint64
+ access []uint64
+}
+
+func newMemTree(b uint, parent *memTree, pidx uint) (node *memTree) {
+ node = new(memTree)
+ node.bits = b
+ node.width = 1 << b
+ node.subtree = make([]*memTree, node.width)
+ node.access = make([]uint64, node.width-1)
+ node.parent = parent
+ node.parentIdx = pidx
+ if parent != nil {
+ parent.subtree[pidx] = node
+ }
+
+ return node
+}
+
+func (node *memTree) updateAccess(a uint64) {
+ aidx := uint(0)
+ var aa uint64
+ oa := node.access[0]
+ for node.access[aidx] == oa {
+ node.access[aidx] = a
+ if aidx > 0 {
+ aa = node.access[((aidx-1)^1)+1]
+ aidx = (aidx - 1) >> 1
+ } else {
+ pidx := node.parentIdx
+ node = node.parent
+ if node == nil {
+ return
+ }
+ nn := node.subtree[pidx^1]
+ if nn != nil {
+ aa = nn.access[0]
+ } else {
+ aa = 0
+ }
+ aidx = (node.width + pidx - 2) >> 1
+ }
+
+ if (aa != 0) && (aa < a) {
+ a = aa
+ }
+ }
+}
+
+func (s *MemStore) setCapacity(c uint) {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+
+ for c < s.entryCnt {
+ s.removeOldest()
+ }
+ s.capacity = c
+}
+
+func (s *MemStore) Counter() uint {
+ return s.entryCnt
+}
+
+// entry (not its copy) is going to be in MemStore
+func (s *MemStore) Put(entry *Chunk) {
+ log.Trace("memstore.put", "key", entry.Key)
+ if s.capacity == 0 {
+ return
+ }
+
+ s.lock.Lock()
+ defer s.lock.Unlock()
+
+ if s.entryCnt >= s.capacity {
+ s.removeOldest()
+ }
+
+ s.accessCnt++
+
+ memstorePutCounter.Inc(1)
+
+ node := s.memtree
+ bitpos := uint(0)
+ for node.entry == nil {
+ l := entry.Key.bits(bitpos, node.bits)
+ st := node.subtree[l]
+ if st == nil {
+ st = newMemTree(memTreeLW, node, l)
+ bitpos += node.bits
+ node = st
+ break
+ }
+ bitpos += node.bits
+ node = st
+ }
+
+ if node.entry != nil {
+
+ if node.entry.Key.isEqual(entry.Key) {
+ node.updateAccess(s.accessCnt)
+ if entry.SData == nil {
+ entry.Size = node.entry.Size
+ entry.SData = node.entry.SData
+ }
+ if entry.ReqC == nil {
+ entry.ReqC = node.entry.ReqC
+ }
+ entry.C = node.entry.C
+ node.entry = entry
+ return
+ }
+
+ for node.entry != nil {
+
+ l := node.entry.Key.bits(bitpos, node.bits)
+ st := node.subtree[l]
+ if st == nil {
+ st = newMemTree(memTreeLW, node, l)
+ }
+ st.entry = node.entry
+ node.entry = nil
+ st.updateAccess(node.access[0])
+
+ l = entry.Key.bits(bitpos, node.bits)
+ st = node.subtree[l]
+ if st == nil {
+ st = newMemTree(memTreeLW, node, l)
+ }
+ bitpos += node.bits
+ node = st
+
+ }
+ }
+
+ node.entry = entry
+ node.lastDBaccess = s.dbAccessCnt
+ node.updateAccess(s.accessCnt)
+ s.entryCnt++
+}
+
+func (s *MemStore) Get(hash Key) (chunk *Chunk, err error) {
+ log.Trace("memstore.get", "key", hash)
+ s.lock.Lock()
+ defer s.lock.Unlock()
+
+ node := s.memtree
+ bitpos := uint(0)
+ for node.entry == nil {
+ l := hash.bits(bitpos, node.bits)
+ st := node.subtree[l]
+ if st == nil {
+ log.Trace("memstore.get ErrChunkNotFound", "key", hash)
+ return nil, ErrChunkNotFound
+ }
+ bitpos += node.bits
+ node = st
+ }
+
+ if node.entry.Key.isEqual(hash) {
+ s.accessCnt++
+ node.updateAccess(s.accessCnt)
+ chunk = node.entry
+ if s.dbAccessCnt-node.lastDBaccess > dbForceUpdateAccessCnt {
+ s.dbAccessCnt++
+ node.lastDBaccess = s.dbAccessCnt
+ if s.ldbStore != nil {
+ s.ldbStore.updateAccessCnt(hash)
+ }
+ }
+ } else {
+ err = ErrChunkNotFound
+ }
+
+ log.Trace("memstore.get return", "key", hash, "chunk", chunk, "err", err)
+ return
+}
+
+func (s *MemStore) removeOldest() {
+ defer metrics.GetOrRegisterResettingTimer("memstore.purge", metrics.DefaultRegistry).UpdateSince(time.Now())
+
+ node := s.memtree
+ log.Warn("purge memstore")
+ for node.entry == nil {
+
+ aidx := uint(0)
+ av := node.access[aidx]
+
+ for aidx < node.width/2-1 {
+ if av == node.access[aidx*2+1] {
+ node.access[aidx] = node.access[aidx*2+2]
+ aidx = aidx*2 + 1
+ } else if av == node.access[aidx*2+2] {
+ node.access[aidx] = node.access[aidx*2+1]
+ aidx = aidx*2 + 2
+ } else {
+ panic(nil)
+ }
+ }
+ pidx := aidx*2 + 2 - node.width
+ if (node.subtree[pidx] != nil) && (av == node.subtree[pidx].access[0]) {
+ if node.subtree[pidx+1] != nil {
+ node.access[aidx] = node.subtree[pidx+1].access[0]
+ } else {
+ node.access[aidx] = 0
+ }
+ } else if (node.subtree[pidx+1] != nil) && (av == node.subtree[pidx+1].access[0]) {
+ if node.subtree[pidx] != nil {
+ node.access[aidx] = node.subtree[pidx].access[0]
+ } else {
+ node.access[aidx] = 0
+ }
+ pidx++
+ } else {
+ panic(nil)
+ }
+
+ //fmt.Println(pidx)
+ node = node.subtree[pidx]
+
+ }
+
+ if node.entry.ReqC == nil {
+ log.Trace(fmt.Sprintf("Memstore Clean: Waiting for chunk %v to be saved", node.entry.Key.Log()))
+ <-node.entry.dbStoredC
+ log.Trace(fmt.Sprintf("Memstore Clean: Chunk %v saved to DBStore. Ready to clear from mem.", node.entry.Key.Log()))
+
+ memstoreRemoveCounter.Inc(1)
+ node.entry = nil
+ s.entryCnt--
+ } else {
+ return
+ }
+
+ node.access[0] = 0
+
+ //---
+
+ aidx := uint(0)
+ for {
+ aa := node.access[aidx]
+ if aidx > 0 {
+ aidx = (aidx - 1) >> 1
+ } else {
+ pidx := node.parentIdx
+ node = node.parent
+ if node == nil {
+ return
+ }
+ aidx = (node.width + pidx - 2) >> 1
+ }
+ if (aa != 0) && ((aa < node.access[aidx]) || (node.access[aidx] == 0)) {
+ node.access[aidx] = aa
+ }
+ }
+}
+
+// type MemStore struct {
+// m map[string]*Chunk
+// mu sync.RWMutex
+// }
+
+// func NewMemStore(d *DbStore, capacity uint) (m *MemStore) {
+// return &MemStore{
+// m: make(map[string]*Chunk),
+// }
+// }
+
+// func (m *MemStore) Get(key Key) (*Chunk, error) {
+// m.mu.RLock()
+// defer m.mu.RUnlock()
+// c, ok := m.m[string(key[:])]
+// if !ok {
+// return nil, ErrNotFound
+// }
+// if !bytes.Equal(c.Key, key) {
+// panic(fmt.Errorf("MemStore.Get: chunk key %s != req key %s", c.Key.Hex(), key.Hex()))
+// }
+// return c, nil
+// }
+
+// func (m *MemStore) Put(c *Chunk) {
+// m.mu.Lock()
+// defer m.mu.Unlock()
+// m.m[string(c.Key[:])] = c
+// }
+
+// func (m *MemStore) setCapacity(n int) {
+
+// }
+
+// Close memstore
+func (s *MemStore) Close() {}