diff options
-rw-r--r-- | db.go | 5 | ||||
-rw-r--r-- | freelist.go | 24 | ||||
-rw-r--r-- | page.go | 2 | ||||
-rw-r--r-- | tx.go | 2 |
4 files changed, 16 insertions, 17 deletions
@@ -552,7 +552,10 @@ func (db *DB) removeTx(tx *Tx) { // Remove the transaction. for i, t := range db.txs { if t == tx { - db.txs = append(db.txs[:i], db.txs[i+1:]...) + last := len(db.txs) - 1 + db.txs[i] = db.txs[last] + db.txs[last] = nil + db.txs = db.txs[:last] break } } diff --git a/freelist.go b/freelist.go index 53efa8f..aba48f5 100644 --- a/freelist.go +++ b/freelist.go @@ -24,7 +24,12 @@ func newFreelist() *freelist { // size returns the size of the page after serialization. func (f *freelist) size() int { - return pageHeaderSize + (int(unsafe.Sizeof(pgid(0))) * f.count()) + n := f.count() + if n >= 0xFFFF { + // The first element will be used to store the count. See freelist.write. + n++ + } + return pageHeaderSize + (int(unsafe.Sizeof(pgid(0))) * n) } // count returns count of pages on the freelist @@ -46,19 +51,10 @@ func (f *freelist) pending_count() int { return count } -// lenall returns the combined number of all free ids and all pending ids. -func (f *freelist) lenall() int { - n := len(f.ids) - for _, list := range f.pending { - n += len(list) - } - return n -} - -// all copies into dst a list of all free ids and all pending ids in one sorted list. -// f.lenall returns the minimum length required for dst. +// copyall copies into dst a list of all free ids and all pending ids in one sorted list. +// f.count returns the minimum length required for dst. func (f *freelist) copyall(dst []pgid) { - m := make(pgids, 0, len(f.pending)) // len(f.pending) undercounts, but it is a start + m := make(pgids, 0, f.pending_count()) for _, list := range f.pending { m = append(m, list...) } @@ -200,7 +196,7 @@ func (f *freelist) write(p *page) error { // The page.count can only hold up to 64k elements so if we overflow that // number then we handle it by putting the size in the first element. - lenids := f.lenall() + lenids := f.count() if lenids == 0 { p.count = uint16(lenids) } else if lenids < 0xFFFF { @@ -154,7 +154,7 @@ func (a pgids) merge(b pgids) pgids { return merged } -// merge copies the sorted union of a and b into dst. +// mergepgids copies the sorted union of a and b into dst. // If dst is too small, it panics. func mergepgids(dst, a, b pgids) { if len(dst) < len(a)+len(b) { @@ -381,7 +381,7 @@ func (tx *Tx) Check() <-chan error { func (tx *Tx) check(ch chan error) { // Check if any pages are double freed. freed := make(map[pgid]bool) - all := make([]pgid, tx.db.freelist.lenall()) + all := make([]pgid, tx.db.freelist.count()) tx.db.freelist.copyall(all) for _, id := range all { if freed[id] { |