forked from dinstein/fabric
/
persistor.go
127 lines (99 loc) · 3.19 KB
/
persistor.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package db
import (
"github.com/tecbot/gorocksdb"
"strings"
)
//some per-def prefix
const RawLegacyPBFTPrefix = "consensus.chkpt."
var persistorRegChecker = map[string]int{}
var persistorReg []string
type PersistorKey int
func PersistKeyRegister(k string) PersistorKey {
if _, ok := persistorRegChecker[k]; ok {
panic(k + " is duplicated persist key, select another one")
}
ret := len(persistorReg)
persistorRegChecker[k] = ret
persistorReg = append(persistorReg, k)
return PersistorKey(ret)
}
func GetPersistKey(k string) PersistorKey {
if v, ok := persistorRegChecker[k]; !ok {
panic(k + " is not registried")
} else {
return PersistorKey(v)
}
}
func ListPersistorKeys() []string { return persistorReg }
// Persistor enables module to persist and restore data to the database
// type Persistor interface {
// StoreByKeys(keys []string, value []byte) error
// Store(key string, value []byte) error
// LoadByKeys(keys []string) ([]byte, error)
// Load(key string) ([]byte, error)
// }
type persistor struct {
prefix string
iteratingPrefix []byte
iterator *gorocksdb.Iterator
}
func NewPersistor(index PersistorKey) *persistor {
return &persistor{prefix: persistorReg[index]}
}
func (p *persistor) buildStoreKey(keys []string) []byte {
return []byte(strings.Join(append([]string{p.prefix}, keys...), "."))
}
func (p *persistor) EndIteration() {
p.iterator.Close()
p.iterator = nil
}
func (p *persistor) StartIteration(keys []string) {
p.iteratingPrefix = p.buildStoreKey(keys)
p.iterator = GetGlobalDBHandle().GetIterator(PersistCF)
p.iterator.Seek(p.iteratingPrefix)
}
//API for iteration
func (p *persistor) Valid() bool {
if p.iterator == nil {
return false
}
return p.iterator.ValidForPrefix(p.iteratingPrefix)
}
func (p *persistor) Next() { p.iterator.Next() }
func (p *persistor) PeekKey() []byte {
//Value/Key() in iterator need not to be Free() but its Data()
//must be copied
//ret = append(ret, it.Value().Data()) --- THIS IS WRONG
//ret = append(ret, makeCopy(it.Value().Data()))
return p.iterator.Key().Data()
}
func (p *persistor) Key() []byte {
return makeCopy(p.PeekKey())
}
func (p *persistor) PeekValue() []byte {
return p.iterator.Value().Data()
}
func (p *persistor) Value() []byte {
return makeCopy(p.PeekValue())
}
// Store enables a peer to persist the given key series,value pair to the database
func (p *persistor) StoreByKeys(keys []string, value []byte) error {
dbhandler := GetGlobalDBHandle()
//dbg.Infof("add db.PersistCF: <%s> --> <%x>", key, value)
return dbhandler.PutValue(PersistCF, p.buildStoreKey(keys), value)
}
func (p *persistor) StoreOnBatch(wb *gorocksdb.WriteBatch, keys []string, value []byte) {
dbhandler := GetGlobalDBHandle()
wb.PutCF(dbhandler.persistCF, p.buildStoreKey(keys), value)
}
// Load enables a peer to read the value that corresponds to the given database key
func (p *persistor) LoadByKeys(keys []string) ([]byte, error) {
dbhandler := GetGlobalDBHandle()
return dbhandler.GetValue(PersistCF, p.buildStoreKey(keys))
}
func (p *persistor) Store(key string, value []byte) error {
return p.StoreByKeys([]string{key}, value)
}
func (p *persistor) Load(key string) ([]byte, error) {
return p.LoadByKeys([]string{key})
}