erigon-pulse/ethdb/storage_index.go
b00ris df8798b94b
Thin history for storage (#324)
* save state

* save state

* fmt

* add check to test

* move incarnation length to common

* remove line

* fix lint
2020-01-15 17:55:43 +03:00

89 lines
1.8 KiB
Go

package ethdb
import (
"bytes"
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ugorji/go/codec"
)
func NewStorageIndex() StorageIndex {
return make(StorageIndex)
}
type StorageIndex map[common.Hash]*HistoryIndex
func (si StorageIndex) Encode() ([]byte, error) {
var w bytes.Buffer
var handle codec.CborHandle
//handle.WriterBufferSize = 1024
encoder := codec.NewEncoder(&w, &handle)
err := encoder.Encode(si)
if err != nil {
return nil, err
}
return w.Bytes(), nil
}
func (si StorageIndex) Decode(s []byte) error {
if len(s) == 0 {
return nil
}
var handle codec.CborHandle
decoder := codec.NewDecoder(bytes.NewBuffer(s), &handle)
return decoder.Decode(si)
}
func (si StorageIndex) Append(key common.Hash, val uint64) {
if _, ok := si[key]; !ok {
si[key] = new(HistoryIndex)
}
si[key] = si[key].Append(val)
}
//most common operation is remove one from the tail
func (si StorageIndex) Remove(key common.Hash, val uint64) {
if v, ok := si[key]; ok && v != nil {
v = v.Remove(val)
if len(*v) == 0 {
delete(si, key)
} else {
si[key] = v
}
}
}
func (si StorageIndex) Search(key common.Hash, val uint64) (uint64, bool) {
if v, ok := si[key]; ok && v != nil {
return v.Search(val)
}
return 0, false
}
func AppendToStorageIndex(b []byte, key []byte, timestamp uint64) ([]byte, error) {
v := NewStorageIndex()
if err := v.Decode(b); err != nil {
return nil, err
}
v.Append(common.BytesToHash(key), timestamp)
return v.Encode()
}
func RemoveFromStorageIndex(b []byte, timestamp uint64) ([]byte, bool, error) {
v := NewStorageIndex()
if err := v.Decode(b); err != nil {
return nil, false, err
}
for key := range v {
v.Remove(key, timestamp)
}
res, err := v.Encode()
if len(v) == 0 {
return res, true, err
}
return res, false, err
}