Merge pull request #460 from ahrtr/freelist_type_20230412

Move FreelistType from `internal/common` to top level package `bbolt`
This commit is contained in:
Benjamin Wang 2023-04-13 20:03:32 +08:00 committed by GitHub
commit bc572b8783
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 33 deletions

21
db.go
View File

@ -18,13 +18,18 @@ import (
// The time elapsed between consecutive file locking attempts. // The time elapsed between consecutive file locking attempts.
const flockRetryTimeout = 50 * time.Millisecond const flockRetryTimeout = 50 * time.Millisecond
// Export both FreelistArrayType and FreelistMapType so as to keep API compatibility. // FreelistType is the type of the freelist backend
type FreelistType string
// TODO(ahrtr): eventually we should (step by step) // TODO(ahrtr): eventually we should (step by step)
// 1. default to FreelistMapType; // 1. default to `FreelistMapType`;
// 2. remove the FreelistArrayType and do not export FreelistMapType; // 2. remove the `FreelistArrayType`, do not export `FreelistMapType`
// and remove field `FreelistType' from both `DB` and `Options`;
const ( const (
FreelistArrayType = common.FreelistArrayType // FreelistArrayType indicates backend freelist type is array
FreelistMapType = common.FreelistMapType FreelistArrayType = FreelistType("array")
// FreelistMapType indicates backend freelist type is hashmap
FreelistMapType = FreelistType("hashmap")
) )
// DB represents a collection of buckets persisted to a file on disk. // DB represents a collection of buckets persisted to a file on disk.
@ -59,7 +64,7 @@ type DB struct {
// The alternative one is using hashmap, it is faster in almost all circumstances // The alternative one is using hashmap, it is faster in almost all circumstances
// but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe. // but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe.
// The default type is array // The default type is array
FreelistType common.FreelistType FreelistType FreelistType
// When true, skips the truncate call when growing the database. // When true, skips the truncate call when growing the database.
// Setting this to true is only safe on non-ext3/ext4 systems. // Setting this to true is only safe on non-ext3/ext4 systems.
@ -1211,7 +1216,7 @@ type Options struct {
// The alternative one is using hashmap, it is faster in almost all circumstances // The alternative one is using hashmap, it is faster in almost all circumstances
// but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe. // but it doesn't guarantee that it offers the smallest page id available. In normal case it is safe.
// The default type is array // The default type is array
FreelistType common.FreelistType FreelistType FreelistType
// Open database in read-only mode. Uses flock(..., LOCK_SH |LOCK_NB) to // Open database in read-only mode. Uses flock(..., LOCK_SH |LOCK_NB) to
// grab a shared lock (UNIX). // grab a shared lock (UNIX).
@ -1253,7 +1258,7 @@ type Options struct {
var DefaultOptions = &Options{ var DefaultOptions = &Options{
Timeout: 0, Timeout: 0,
NoGrowSync: false, NoGrowSync: false,
FreelistType: common.FreelistArrayType, FreelistType: FreelistArrayType,
} }
// Stats represents statistics about the database. // Stats represents statistics about the database.

View File

@ -22,7 +22,7 @@ type pidSet map[common.Pgid]struct{}
// freelist represents a list of all pages that are available for allocation. // freelist represents a list of all pages that are available for allocation.
// It also tracks pages that have been freed but are still in use by open transactions. // It also tracks pages that have been freed but are still in use by open transactions.
type freelist struct { type freelist struct {
freelistType common.FreelistType // freelist type freelistType FreelistType // freelist type
ids []common.Pgid // all free and available free page ids. ids []common.Pgid // all free and available free page ids.
allocs map[common.Pgid]common.Txid // mapping of Txid that allocated a pgid. allocs map[common.Pgid]common.Txid // mapping of Txid that allocated a pgid.
pending map[common.Txid]*txPending // mapping of soon-to-be free page ids by tx. pending map[common.Txid]*txPending // mapping of soon-to-be free page ids by tx.
@ -38,7 +38,7 @@ type freelist struct {
} }
// newFreelist returns an empty, initialized freelist. // newFreelist returns an empty, initialized freelist.
func newFreelist(freelistType common.FreelistType) *freelist { func newFreelist(freelistType FreelistType) *freelist {
f := &freelist{ f := &freelist{
freelistType: freelistType, freelistType: freelistType,
allocs: make(map[common.Pgid]common.Txid), allocs: make(map[common.Pgid]common.Txid),
@ -49,7 +49,7 @@ func newFreelist(freelistType common.FreelistType) *freelist {
backwardMap: make(map[common.Pgid]uint64), backwardMap: make(map[common.Pgid]uint64),
} }
if freelistType == common.FreelistMapType { if freelistType == FreelistMapType {
f.allocate = f.hashmapAllocate f.allocate = f.hashmapAllocate
f.free_count = f.hashmapFreeCount f.free_count = f.hashmapFreeCount
f.mergeSpans = f.hashmapMergeSpans f.mergeSpans = f.hashmapMergeSpans

View File

@ -181,7 +181,7 @@ func TestFreelist_releaseRange(t *testing.T) {
func TestFreelistHashmap_allocate(t *testing.T) { func TestFreelistHashmap_allocate(t *testing.T) {
f := newTestFreelist() f := newTestFreelist()
if f.freelistType != common.FreelistMapType { if f.freelistType != FreelistMapType {
t.Skip() t.Skip()
} }
@ -211,7 +211,7 @@ func TestFreelistHashmap_allocate(t *testing.T) {
// Ensure that a freelist can find contiguous blocks of pages. // Ensure that a freelist can find contiguous blocks of pages.
func TestFreelistArray_allocate(t *testing.T) { func TestFreelistArray_allocate(t *testing.T) {
f := newTestFreelist() f := newTestFreelist()
if f.freelistType != common.FreelistArrayType { if f.freelistType != FreelistArrayType {
t.Skip() t.Skip()
} }
ids := []common.Pgid{3, 4, 5, 6, 7, 9, 12, 13, 18} ids := []common.Pgid{3, 4, 5, 6, 7, 9, 12, 13, 18}
@ -403,7 +403,7 @@ func Test_freelist_mergeWithExist(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
f := newTestFreelist() f := newTestFreelist()
if f.freelistType == common.FreelistArrayType { if f.freelistType == FreelistArrayType {
t.Skip() t.Skip()
} }
f.readIDs(tt.ids) f.readIDs(tt.ids)
@ -427,9 +427,9 @@ func Test_freelist_mergeWithExist(t *testing.T) {
// newTestFreelist get the freelist type from env and initial the freelist // newTestFreelist get the freelist type from env and initial the freelist
func newTestFreelist() *freelist { func newTestFreelist() *freelist {
freelistType := common.FreelistArrayType freelistType := FreelistArrayType
if env := os.Getenv(TestFreelistType); env == string(common.FreelistMapType) { if env := os.Getenv(TestFreelistType); env == string(FreelistMapType) {
freelistType = common.FreelistMapType freelistType = FreelistMapType
} }
return newFreelist(freelistType) return newFreelist(freelistType)
@ -437,7 +437,7 @@ func newTestFreelist() *freelist {
func Test_freelist_hashmapGetFreePageIDs(t *testing.T) { func Test_freelist_hashmapGetFreePageIDs(t *testing.T) {
f := newTestFreelist() f := newTestFreelist()
if f.freelistType == common.FreelistArrayType { if f.freelistType == FreelistArrayType {
t.Skip() t.Skip()
} }
@ -461,7 +461,7 @@ func Test_freelist_hashmapGetFreePageIDs(t *testing.T) {
func Benchmark_freelist_hashmapGetFreePageIDs(b *testing.B) { func Benchmark_freelist_hashmapGetFreePageIDs(b *testing.B) {
f := newTestFreelist() f := newTestFreelist()
if f.freelistType == common.FreelistArrayType { if f.freelistType == FreelistArrayType {
b.Skip() b.Skip()
} }

View File

@ -13,7 +13,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
bolt "go.etcd.io/bbolt" bolt "go.etcd.io/bbolt"
"go.etcd.io/bbolt/internal/common"
) )
var statsFlag = flag.Bool("stats", false, "show performance stats") var statsFlag = flag.Bool("stats", false, "show performance stats")
@ -50,9 +49,9 @@ func MustOpenDBWithOption(t testing.TB, f string, o *bolt.Options) *DB {
o = bolt.DefaultOptions o = bolt.DefaultOptions
} }
freelistType := common.FreelistArrayType freelistType := bolt.FreelistArrayType
if env := os.Getenv(TestFreelistType); env == string(common.FreelistMapType) { if env := os.Getenv(TestFreelistType); env == string(bolt.FreelistMapType) {
freelistType = common.FreelistMapType freelistType = bolt.FreelistMapType
} }
o.FreelistType = freelistType o.FreelistType = freelistType

View File

@ -36,15 +36,5 @@ const (
// DefaultPageSize is the default page size for db which is set to the OS page size. // DefaultPageSize is the default page size for db which is set to the OS page size.
var DefaultPageSize = os.Getpagesize() var DefaultPageSize = os.Getpagesize()
// FreelistType is the type of the freelist backend
type FreelistType string
const (
// FreelistArrayType indicates backend freelist type is array
FreelistArrayType = FreelistType("array")
// FreelistMapType indicates backend freelist type is hashmap
FreelistMapType = FreelistType("hashmap")
)
// Txid represents the internal transaction identifier. // Txid represents the internal transaction identifier.
type Txid uint64 type Txid uint64