forked from iotaledger/wasp-legacy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase.go
More file actions
185 lines (150 loc) · 5.2 KB
/
Copy pathdatabase.go
File metadata and controls
185 lines (150 loc) · 5.2 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package database
import (
"errors"
"fmt"
"sync"
"github.com/iotaledger/hive.go/kvstore"
hivedb "github.com/iotaledger/hive.go/kvstore/database"
"github.com/iotaledger/hive.go/runtime/ioutils"
"github.com/iotaledger/wasp/packages/chaindb"
)
var (
AllowedEnginesDefault = []hivedb.Engine{
hivedb.EngineAuto,
hivedb.EngineMapDB,
hivedb.EngineRocksDB,
}
AllowedEnginesStorage = []hivedb.Engine{
hivedb.EngineRocksDB,
}
AllowedEnginesStorageAuto = append(AllowedEnginesStorage, hivedb.EngineAuto)
)
type StoreVersionUpdateFunc func(store kvstore.KVStore, oldVersion byte, newVersion byte) error
// Database holds the underlying KVStore and database specific functions.
type Database struct {
databaseDir string
store kvstore.KVStore
engine hivedb.Engine
compactionSupported bool
compactionRunningFunc func() bool
writeMutex sync.Mutex
}
// New creates a new Database instance.
func New(databaseDirectory string, kvStore kvstore.KVStore, engine hivedb.Engine, compactionSupported bool, compactionRunningFunc func() bool) *Database {
return &Database{
databaseDir: databaseDirectory,
store: kvStore,
engine: engine,
compactionSupported: compactionSupported,
compactionRunningFunc: compactionRunningFunc,
}
}
// KVStore returns the underlying KVStore.
func (db *Database) KVStore() kvstore.KVStore {
return db.store
}
// Engine returns the database engine.
func (db *Database) Engine() hivedb.Engine {
return db.engine
}
// CompactionSupported returns whether the database engine supports compaction.
func (db *Database) CompactionSupported() bool {
return db.compactionSupported
}
// CompactionRunning returns whether a compaction is running.
func (db *Database) CompactionRunning() bool {
if db.compactionRunningFunc == nil {
return false
}
return db.compactionRunningFunc()
}
// Size returns the size of the database.
func (db *Database) Size() (int64, error) {
if db.engine == hivedb.EngineMapDB {
// in-memory database does not support this method.
return 0, nil
}
return ioutils.FolderSize(db.databaseDir)
}
// CheckEngine is a wrapper around hivedb.CheckEngine to throw a custom error message in case of engine mismatch.
func CheckEngine(dbPath string, createDatabaseIfNotExists bool, dbEngine hivedb.Engine, allowedEngines ...hivedb.Engine) (hivedb.Engine, error) {
tmpAllowedEngines := AllowedEnginesDefault
if len(allowedEngines) > 0 {
tmpAllowedEngines = allowedEngines
}
targetEngine, err := hivedb.CheckEngine(dbPath, createDatabaseIfNotExists, dbEngine, tmpAllowedEngines)
if err != nil {
if errors.Is(err, hivedb.ErrEngineMismatch) {
//nolint:stylecheck // this error message is shown to the user
return hivedb.EngineUnknown, fmt.Errorf("database (%s) engine does not match the configuration: '%v' != '%v'", dbPath, targetEngine, dbEngine[0])
}
return hivedb.EngineUnknown, err
}
return targetEngine, nil
}
// DatabaseWithDefaultSettings returns a database with default settings.
// It also checks if the database engine is correct.
//
//nolint:revive
func DatabaseWithDefaultSettings(path string, createDatabaseIfNotExists bool, dbEngine hivedb.Engine, autoFlush bool, allowedEngines ...hivedb.Engine) (*Database, error) {
tmpAllowedEngines := AllowedEnginesDefault
if len(allowedEngines) > 0 {
tmpAllowedEngines = allowedEngines
}
targetEngine, err := CheckEngine(path, createDatabaseIfNotExists, dbEngine, tmpAllowedEngines...)
if err != nil {
return nil, err
}
switch targetEngine {
case hivedb.EngineRocksDB:
return newDatabaseRocksDB(path, autoFlush)
case hivedb.EngineMapDB:
return newDatabaseMapDB(), nil
default:
return nil, fmt.Errorf("unknown database engine: %s, supported engines: rocksdb/mapdb", dbEngine)
}
}
type databaseWithHealthTracker struct {
database *Database
storeHealthTracker *kvstore.StoreHealthTracker
}
func newDatabaseWithHealthTracker(path string, dbEngine hivedb.Engine, autoFlush bool, storeVersion byte, storeVersionUpdateFunc StoreVersionUpdateFunc) (*databaseWithHealthTracker, error) {
db, err := DatabaseWithDefaultSettings(path, true, dbEngine, autoFlush, AllowedEnginesDefault...)
if err != nil {
return nil, err
}
var hiveStoreVersionUpdateFunc kvstore.StoreVersionUpdateFunc
if storeVersionUpdateFunc != nil {
hiveStoreVersionUpdateFunc = func(oldVersion, newVersion byte) error {
return storeVersionUpdateFunc(db.KVStore(), oldVersion, newVersion)
}
}
healthTracker, err := kvstore.NewStoreHealthTracker(db.KVStore(), []byte{chaindb.PrefixHealthTracker}, storeVersion, hiveStoreVersionUpdateFunc)
if err != nil {
return nil, err
}
return &databaseWithHealthTracker{
database: db,
storeHealthTracker: healthTracker,
}, nil
}
func (db *databaseWithHealthTracker) Flush() error {
var err error
if errTmp := db.database.KVStore().Flush(); errTmp != nil {
err = errTmp
}
if errTmp := db.storeHealthTracker.Flush(); errTmp != nil {
err = errTmp
}
return err
}
func (db *databaseWithHealthTracker) Close() error {
var err error
if errTmp := db.database.KVStore().Close(); errTmp != nil {
err = errTmp
}
if errTmp := db.storeHealthTracker.Close(); errTmp != nil {
err = errTmp
}
return err
}