-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmemstore.go
99 lines (81 loc) · 2.11 KB
/
memstore.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package sparkle
import (
"sync"
"github.com/umran/crypto"
)
// MemStore ...
type MemStore struct {
mux *sync.Mutex
currentEpoch uint64
values map[string]map[uint64]crypto.Hash
epochsByRoot map[string]uint64
rootsByEpoch map[uint64]crypto.Hash
}
// ExecTx ...
func (ms *MemStore) ExecTx(handler func(Transaction) error) error {
ms.mux.Lock()
defer ms.mux.Unlock()
return handler(&MemStoreTransaction{
store: ms,
})
}
// MemStoreTransaction ...
type MemStoreTransaction struct {
store *MemStore
}
// GetValue ...
func (tx *MemStoreTransaction) GetValue(key string, maxEpoch uint64) (crypto.Hash, error) {
versions := tx.store.values[key]
if versions == nil {
return nil, nil
}
var (
latestEpoch uint64
latestVersion crypto.Hash
)
for epoch, version := range versions {
if epoch >= latestEpoch && epoch <= maxEpoch {
latestEpoch = epoch
latestVersion = version
}
}
return latestVersion, nil
}
// SetValue ...
func (tx *MemStoreTransaction) SetValue(key string, value crypto.Hash) error {
_, ok := tx.store.values[key]
if !ok {
tx.store.values[key] = make(map[uint64]crypto.Hash)
}
tx.store.values[key][tx.store.currentEpoch] = value
return nil
}
// CurrentEpoch ...
func (tx *MemStoreTransaction) CurrentEpoch() (uint64, error) {
return tx.store.currentEpoch, nil
}
// CommitRoot ...
func (tx *MemStoreTransaction) CommitRoot(root crypto.Hash) error {
tx.store.rootsByEpoch[tx.store.currentEpoch] = root
tx.store.epochsByRoot[root.HexString()] = tx.store.currentEpoch
tx.store.currentEpoch++
return nil
}
// GetEpochByRoot ...
func (tx *MemStoreTransaction) GetEpochByRoot(root crypto.Hash) (uint64, error) {
return tx.store.epochsByRoot[root.HexString()], nil
}
// GetRootByEpoch ...
func (tx *MemStoreTransaction) GetRootByEpoch(epoch uint64) (crypto.Hash, error) {
return tx.store.rootsByEpoch[epoch], nil
}
// NewMemStore ...
func NewMemStore() *MemStore {
return &MemStore{
mux: new(sync.Mutex),
currentEpoch: 0,
values: make(map[string]map[uint64]crypto.Hash),
epochsByRoot: make(map[string]uint64),
rootsByEpoch: make(map[uint64]crypto.Hash),
}
}