-
Notifications
You must be signed in to change notification settings - Fork 0
/
skiperrors.go
159 lines (138 loc) · 3.63 KB
/
skiperrors.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package skiperrors
import (
"github.com/Deepchain-foundation/lachesis-base/kvdb"
)
// wrapper is a kvdb.Store wrapper around any kvdb.Store.
// It ignores some errors of underlying store.
// NOTE: ignoring is not implemented at Iterator, Batch, .
type wrapper struct {
readWrapper
underlying kvdb.Store
}
type readWrapper struct {
reader kvdb.IteratedReader
errs []error
}
// Wrap returns a wrapped kvdb.Store.
func Wrap(db kvdb.Store, errs ...error) kvdb.Store {
return &wrapper{
readWrapper: readWrapper{
reader: db,
errs: errs,
},
underlying: db,
}
}
func (f *readWrapper) skip(got error) bool {
if got == nil {
return false
}
for _, exp := range f.errs {
if got == exp || got.Error() == exp.Error() {
return true
}
}
return false
}
/*
* implementation:
*/
// Has retrieves if a key is present in the key-value data store.
func (f *readWrapper) Has(key []byte) (bool, error) {
has, err := f.reader.Has(key)
if f.skip(err) {
return false, nil
}
return has, err
}
// Get retrieves the given key if it's present in the key-value data store.
func (f *readWrapper) Get(key []byte) ([]byte, error) {
b, err := f.reader.Get(key)
if f.skip(err) {
return nil, nil
}
return b, err
}
// Put inserts the given value into the key-value data store.
func (f *wrapper) Put(key []byte, value []byte) error {
err := f.underlying.Put(key, value)
if f.skip(err) {
return nil
}
return err
}
// Delete removes the key from the key-value data store.
func (f *wrapper) Delete(key []byte) error {
err := f.underlying.Delete(key)
if f.skip(err) {
return nil
}
return err
}
// NewBatch creates a write-only database that buffers changes to its host db
// until a final write is called.
func (f *wrapper) NewBatch() kvdb.Batch {
return f.underlying.NewBatch()
}
// NewIterator creates a binary-alphabetical iterator over a subset
// of database content with a particular key prefix, starting at a particular
// initial key (or after, if it does not exist).
func (f *readWrapper) NewIterator(prefix []byte, start []byte) kvdb.Iterator {
return f.reader.NewIterator(prefix, start)
}
// GetSnapshot returns a latest snapshot of the underlying DB. A snapshot
// is a frozen snapshot of a DB state at a particular point in time. The
// content of snapshot are guaranteed to be consistent.
//
// The snapshot must be released after use, by calling Release method.
func (f *wrapper) GetSnapshot() (kvdb.Snapshot, error) {
snap, err := f.underlying.GetSnapshot()
if err != nil {
return nil, err
}
return &Snapshot{
readWrapper{
reader: snap,
errs: f.errs,
},
snap,
}, nil
}
// Stat returns a particular internal stat of the database.
func (f *wrapper) Stat(property string) (string, error) {
stat, err := f.underlying.Stat(property)
if f.skip(err) {
return "", nil
}
return stat, err
}
// Compact flattens the underlying data store for the given key range. In essence,
// deleted and overwritten versions are discarded, and the data is rearranged to
// reduce the cost of operations needed to access them.
//
// A nil start is treated as a key before all keys in the data store; a nil limit
// is treated as a key after all keys in the data store. If both is nil then it
// will compact entire data store.
func (f *wrapper) Compact(start []byte, limit []byte) error {
err := f.underlying.Compact(start, limit)
if f.skip(err) {
return nil
}
return err
}
// Close closes database.
func (f *wrapper) Close() error {
err := f.underlying.Close()
if f.skip(err) {
return nil
}
return err
}
// Snapshot is a DB snapshot.
type Snapshot struct {
readWrapper
snap kvdb.Snapshot
}
func (s *Snapshot) Release() {
s.snap.Release()
}