add getFreePageIDs (#140)

pull/138/head
Xingyu Chen 2019-01-21 15:42:17 +08:00 committed by Xiang Li
parent c5638469ec
commit f0ad07c7d4
3 changed files with 23 additions and 19 deletions

2
db.go
View File

@ -291,7 +291,7 @@ func (db *DB) loadFreelist() {
// Read free list from freelist page. // Read free list from freelist page.
db.freelist.read(db.page(db.meta().freelist)) db.freelist.read(db.page(db.meta().freelist))
} }
db.stats.FreePageN = len(db.freelist.ids) db.stats.FreePageN = len(db.freelist.getFreePageIDs())
}) })
} }

View File

@ -69,7 +69,7 @@ func (f *freelist) copyall(dst []pgid) {
m = append(m, txp.ids...) m = append(m, txp.ids...)
} }
sort.Sort(m) sort.Sort(m)
mergepgids(dst, f.ids, m) mergepgids(dst, f.getFreePageIDs(), m)
} }
// allocate returns the starting page id of a contiguous list of pages of a given size. // allocate returns the starting page id of a contiguous list of pages of a given size.
@ -266,6 +266,10 @@ func (f *freelist) readIDs(ids []pgid) {
f.reindex() f.reindex()
} }
func (f *freelist) getFreePageIDs() []pgid {
return f.ids
}
// write writes the page ids onto a freelist page. All free and pending ids are // write writes the page ids onto a freelist page. All free and pending ids are
// saved to disk since in the event of a program crash, all pending ids will // saved to disk since in the event of a program crash, all pending ids will
// become free. // become free.
@ -307,7 +311,7 @@ func (f *freelist) reload(p *page) {
// Check each page in the freelist and build a new available freelist // Check each page in the freelist and build a new available freelist
// with any pages not in the pending lists. // with any pages not in the pending lists.
var a []pgid var a []pgid
for _, id := range f.ids { for _, id := range f.getFreePageIDs() {
if !pcache[id] { if !pcache[id] {
a = append(a, id) a = append(a, id)
} }
@ -318,8 +322,8 @@ func (f *freelist) reload(p *page) {
// reindex rebuilds the free cache based on available and pending free lists. // reindex rebuilds the free cache based on available and pending free lists.
func (f *freelist) reindex() { func (f *freelist) reindex() {
f.cache = make(map[pgid]bool, len(f.ids)) f.cache = make(map[pgid]bool, len(f.getFreePageIDs()))
for _, id := range f.ids { for _, id := range f.getFreePageIDs() {
f.cache[id] = true f.cache[id] = true
} }
for _, txp := range f.pending { for _, txp := range f.pending {

View File

@ -34,13 +34,13 @@ func TestFreelist_release(t *testing.T) {
f.free(102, &page{id: 39}) f.free(102, &page{id: 39})
f.release(100) f.release(100)
f.release(101) f.release(101)
if exp := []pgid{9, 12, 13}; !reflect.DeepEqual(exp, f.ids) { if exp := []pgid{9, 12, 13}; !reflect.DeepEqual(exp, f.getFreePageIDs()) {
t.Fatalf("exp=%v; got=%v", exp, f.ids) t.Fatalf("exp=%v; got=%v", exp, f.getFreePageIDs())
} }
f.release(102) f.release(102)
if exp := []pgid{9, 12, 13, 39}; !reflect.DeepEqual(exp, f.ids) { if exp := []pgid{9, 12, 13, 39}; !reflect.DeepEqual(exp, f.getFreePageIDs()) {
t.Fatalf("exp=%v; got=%v", exp, f.ids) t.Fatalf("exp=%v; got=%v", exp, f.getFreePageIDs())
} }
} }
@ -167,8 +167,8 @@ func TestFreelist_releaseRange(t *testing.T) {
f.releaseRange(r.begin, r.end) f.releaseRange(r.begin, r.end)
} }
if exp := c.wantFree; !reflect.DeepEqual(exp, f.ids) { if exp := c.wantFree; !reflect.DeepEqual(exp, f.getFreePageIDs()) {
t.Errorf("exp=%v; got=%v for %s", exp, f.ids, c.title) t.Errorf("exp=%v; got=%v for %s", exp, f.getFreePageIDs(), c.title)
} }
} }
} }
@ -199,8 +199,8 @@ func TestFreelist_allocate(t *testing.T) {
if id := int(f.allocate(1, 0)); id != 0 { if id := int(f.allocate(1, 0)); id != 0 {
t.Fatalf("exp=0; got=%v", id) t.Fatalf("exp=0; got=%v", id)
} }
if exp := []pgid{9, 18}; !reflect.DeepEqual(exp, f.ids) { if exp := []pgid{9, 18}; !reflect.DeepEqual(exp, f.getFreePageIDs()) {
t.Fatalf("exp=%v; got=%v", exp, f.ids) t.Fatalf("exp=%v; got=%v", exp, f.getFreePageIDs())
} }
if id := int(f.allocate(1, 1)); id != 9 { if id := int(f.allocate(1, 1)); id != 9 {
@ -212,8 +212,8 @@ func TestFreelist_allocate(t *testing.T) {
if id := int(f.allocate(1, 1)); id != 0 { if id := int(f.allocate(1, 1)); id != 0 {
t.Fatalf("exp=0; got=%v", id) t.Fatalf("exp=0; got=%v", id)
} }
if exp := []pgid{}; !reflect.DeepEqual(exp, f.ids) { if exp := []pgid{}; !reflect.DeepEqual(exp, f.getFreePageIDs()) {
t.Fatalf("exp=%v; got=%v", exp, f.ids) t.Fatalf("exp=%v; got=%v", exp, f.getFreePageIDs())
} }
} }
@ -235,8 +235,8 @@ func TestFreelist_read(t *testing.T) {
f.read(page) f.read(page)
// Ensure that there are two page ids in the freelist. // Ensure that there are two page ids in the freelist.
if exp := []pgid{23, 50}; !reflect.DeepEqual(exp, f.ids) { if exp := []pgid{23, 50}; !reflect.DeepEqual(exp, f.getFreePageIDs()) {
t.Fatalf("exp=%v; got=%v", exp, f.ids) t.Fatalf("exp=%v; got=%v", exp, f.getFreePageIDs())
} }
} }
@ -258,8 +258,8 @@ func TestFreelist_write(t *testing.T) {
// Ensure that the freelist is correct. // Ensure that the freelist is correct.
// All pages should be present and in reverse order. // All pages should be present and in reverse order.
if exp := []pgid{3, 11, 12, 28, 39}; !reflect.DeepEqual(exp, f2.ids) { if exp := []pgid{3, 11, 12, 28, 39}; !reflect.DeepEqual(exp, f2.getFreePageIDs()) {
t.Fatalf("exp=%v; got=%v", exp, f2.ids) t.Fatalf("exp=%v; got=%v", exp, f2.getFreePageIDs())
} }
} }