@@ -13,25 +13,12 @@ import (
1313
1414 berrors "go.etcd.io/bbolt/errors"
1515 "go.etcd.io/bbolt/internal/common"
16+ fl "go.etcd.io/bbolt/internal/freelist"
1617)
1718
1819// The time elapsed between consecutive file locking attempts.
1920const flockRetryTimeout = 50 * time .Millisecond
2021
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-
3522// DB represents a collection of buckets persisted to a file on disk.
3623// All data access is performed through transactions which can be obtained through the DB.
3724// All the functions on DB will return a ErrDatabaseNotOpen if accessed before Open() is called.
@@ -70,7 +57,7 @@ type DB struct {
7057 // The alternative one is using hashmap, it is faster in almost all circumstances
7158 // but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe.
7259 // The default type is array
73- FreelistType FreelistType
60+ FreelistType fl. FreelistType
7461
7562 // When true, skips the truncate call when growing the database.
7663 // Setting this to true is only safe on non-ext3/ext4 systems.
@@ -134,8 +121,9 @@ type DB struct {
134121 rwtx * Tx
135122 txs []* Tx
136123
137- freelist * freelist
138- freelistLoad sync.Once
124+ freelist fl.Freelist
125+ freelistSerializer fl.Serializable
126+ freelistLoad sync.Once
139127
140128 pagePool sync.Pool
141129
@@ -190,6 +178,7 @@ func Open(path string, mode os.FileMode, options *Options) (db *DB, err error) {
190178 db .NoFreelistSync = options .NoFreelistSync
191179 db .PreLoadFreelist = options .PreLoadFreelist
192180 db .FreelistType = options .FreelistType
181+ db .freelistSerializer = fl.Serializer {}
193182 db .Mlock = options .Mlock
194183
195184 // Set default values for later DB operations.
@@ -416,15 +405,16 @@ func (db *DB) getPageSizeFromSecondMeta() (int, bool, error) {
416405// concurrent accesses being made to the freelist.
417406func (db * DB ) loadFreelist () {
418407 db .freelistLoad .Do (func () {
419- db .freelist = newFreelist (db .FreelistType )
408+ db .freelist = fl . NewFreelist (db .FreelistType )
420409 if ! db .hasSyncedFreelist () {
421410 // Reconstruct free list by scanning the DB.
422- db .freelist .readIDs (db .freepages ())
411+ db .freelist .Init (db .freepages ())
423412 } else {
424413 // 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 ()))
426415 }
427- db .stats .FreePageN = db .freelist .free_count ()
416+ db .stats .FreePageN = db .freelist .FreeCount ()
417+ db .stats .PendingPageN = db .freelist .PendingCount ()
428418 })
429419}
430420
@@ -854,14 +844,14 @@ func (db *DB) freePages() {
854844 minid = db .txs [0 ].meta .Txid ()
855845 }
856846 if minid > 0 {
857- db .freelist .release (minid - 1 )
847+ db .freelist .Release (minid - 1 )
858848 }
859849 // Release unused txid extents.
860850 for _ , t := range db .txs {
861- db .freelist .releaseRange (minid , t .meta .Txid ()- 1 )
851+ db .freelist .ReleaseRange (minid , t .meta .Txid ()- 1 )
862852 minid = t .meta .Txid () + 1
863853 }
864- db .freelist .releaseRange (minid , common .Txid (0xFFFFFFFFFFFFFFFF ))
854+ db .freelist .ReleaseRange (minid , common .Txid (0xFFFFFFFFFFFFFFFF ))
865855 // Any page both allocated and freed in an extent is safe to release.
866856}
867857
@@ -1176,7 +1166,7 @@ func (db *DB) allocate(txid common.Txid, count int) (*common.Page, error) {
11761166 p .SetOverflow (uint32 (count - 1 ))
11771167
11781168 // 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 ))
11801170 if p .Id () != 0 {
11811171 return p , nil
11821172 }
@@ -1305,7 +1295,7 @@ type Options struct {
13051295 // The alternative one is using hashmap, it is faster in almost all circumstances
13061296 // but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe.
13071297 // The default type is array
1308- FreelistType FreelistType
1298+ FreelistType fl. FreelistType
13091299
13101300 // Open database in read-only mode. Uses flock(..., LOCK_SH |LOCK_NB) to
13111301 // grab a shared lock (UNIX).
@@ -1360,7 +1350,7 @@ func (o *Options) String() string {
13601350var DefaultOptions = & Options {
13611351 Timeout : 0 ,
13621352 NoGrowSync : false ,
1363- FreelistType : FreelistArrayType ,
1353+ FreelistType : fl . FreelistArrayType ,
13641354}
13651355
13661356// Stats represents statistics about the database.
0 commit comments