@@ -13,25 +13,12 @@ import (
13
13
14
14
berrors "go.etcd.io/bbolt/errors"
15
15
"go.etcd.io/bbolt/internal/common"
16
+ fl "go.etcd.io/bbolt/internal/freelist"
16
17
)
17
18
18
19
// The time elapsed between consecutive file locking attempts.
19
20
const flockRetryTimeout = 50 * time .Millisecond
20
21
21
- // FreelistType is the type of the freelist backend
22
- type FreelistType string
23
-
24
- // TODO(ahrtr): eventually we should (step by step)
25
- // 1. default to `FreelistMapType`;
26
- // 2. remove the `FreelistArrayType`, do not export `FreelistMapType`
27
- // and remove field `FreelistType' from both `DB` and `Options`;
28
- const (
29
- // FreelistArrayType indicates backend freelist type is array
30
- FreelistArrayType = FreelistType ("array" )
31
- // FreelistMapType indicates backend freelist type is hashmap
32
- FreelistMapType = FreelistType ("hashmap" )
33
- )
34
-
35
22
// DB represents a collection of buckets persisted to a file on disk.
36
23
// All data access is performed through transactions which can be obtained through the DB.
37
24
// All the functions on DB will return a ErrDatabaseNotOpen if accessed before Open() is called.
@@ -70,7 +57,7 @@ type DB struct {
70
57
// The alternative one is using hashmap, it is faster in almost all circumstances
71
58
// but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe.
72
59
// The default type is array
73
- FreelistType FreelistType
60
+ FreelistType fl. FreelistType
74
61
75
62
// When true, skips the truncate call when growing the database.
76
63
// Setting this to true is only safe on non-ext3/ext4 systems.
@@ -134,8 +121,9 @@ type DB struct {
134
121
rwtx * Tx
135
122
txs []* Tx
136
123
137
- freelist * freelist
138
- freelistLoad sync.Once
124
+ freelist fl.Freelist
125
+ freelistSerializer fl.Serializable
126
+ freelistLoad sync.Once
139
127
140
128
pagePool sync.Pool
141
129
@@ -190,6 +178,7 @@ func Open(path string, mode os.FileMode, options *Options) (db *DB, err error) {
190
178
db .NoFreelistSync = options .NoFreelistSync
191
179
db .PreLoadFreelist = options .PreLoadFreelist
192
180
db .FreelistType = options .FreelistType
181
+ db .freelistSerializer = fl.Serializer {}
193
182
db .Mlock = options .Mlock
194
183
195
184
// Set default values for later DB operations.
@@ -416,15 +405,16 @@ func (db *DB) getPageSizeFromSecondMeta() (int, bool, error) {
416
405
// concurrent accesses being made to the freelist.
417
406
func (db * DB ) loadFreelist () {
418
407
db .freelistLoad .Do (func () {
419
- db .freelist = newFreelist (db .FreelistType )
408
+ db .freelist = fl . NewFreelist (db .FreelistType )
420
409
if ! db .hasSyncedFreelist () {
421
410
// Reconstruct free list by scanning the DB.
422
- db .freelist .readIDs (db .freepages ())
411
+ db .freelist .Init (db .freepages ())
423
412
} else {
424
413
// Read free list from freelist page.
425
- db .freelist . read ( db .page (db .meta ().Freelist ()))
414
+ db .freelistSerializer . Read ( db . freelist , db .page (db .meta ().Freelist ()))
426
415
}
427
- db .stats .FreePageN = db .freelist .free_count ()
416
+ db .stats .FreePageN = db .freelist .FreeCount ()
417
+ db .stats .PendingPageN = db .freelist .PendingCount ()
428
418
})
429
419
}
430
420
@@ -854,14 +844,14 @@ func (db *DB) freePages() {
854
844
minid = db .txs [0 ].meta .Txid ()
855
845
}
856
846
if minid > 0 {
857
- db .freelist .release (minid - 1 )
847
+ db .freelist .Release (minid - 1 )
858
848
}
859
849
// Release unused txid extents.
860
850
for _ , t := range db .txs {
861
- db .freelist .releaseRange (minid , t .meta .Txid ()- 1 )
851
+ db .freelist .ReleaseRange (minid , t .meta .Txid ()- 1 )
862
852
minid = t .meta .Txid () + 1
863
853
}
864
- db .freelist .releaseRange (minid , common .Txid (0xFFFFFFFFFFFFFFFF ))
854
+ db .freelist .ReleaseRange (minid , common .Txid (0xFFFFFFFFFFFFFFFF ))
865
855
// Any page both allocated and freed in an extent is safe to release.
866
856
}
867
857
@@ -1176,7 +1166,7 @@ func (db *DB) allocate(txid common.Txid, count int) (*common.Page, error) {
1176
1166
p .SetOverflow (uint32 (count - 1 ))
1177
1167
1178
1168
// Use pages from the freelist if they are available.
1179
- p .SetId (db .freelist .allocate (txid , count ))
1169
+ p .SetId (db .freelist .Allocate (txid , count ))
1180
1170
if p .Id () != 0 {
1181
1171
return p , nil
1182
1172
}
@@ -1305,7 +1295,7 @@ type Options struct {
1305
1295
// The alternative one is using hashmap, it is faster in almost all circumstances
1306
1296
// but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe.
1307
1297
// The default type is array
1308
- FreelistType FreelistType
1298
+ FreelistType fl. FreelistType
1309
1299
1310
1300
// Open database in read-only mode. Uses flock(..., LOCK_SH |LOCK_NB) to
1311
1301
// grab a shared lock (UNIX).
@@ -1360,7 +1350,7 @@ func (o *Options) String() string {
1360
1350
var DefaultOptions = & Options {
1361
1351
Timeout : 0 ,
1362
1352
NoGrowSync : false ,
1363
- FreelistType : FreelistArrayType ,
1353
+ FreelistType : fl . FreelistArrayType ,
1364
1354
}
1365
1355
1366
1356
// Stats represents statistics about the database.
0 commit comments