aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db.go5
-rw-r--r--freelist.go24
-rw-r--r--page.go2
-rw-r--r--tx.go2
4 files changed, 16 insertions, 17 deletions
diff --git a/db.go b/db.go
index 48da059..f352ff1 100644
--- a/db.go
+++ b/db.go
@@ -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 {
diff --git a/page.go b/page.go
index ccc6666..cde403a 100644
--- a/page.go
+++ b/page.go
@@ -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) {
diff --git a/tx.go b/tx.go
index 37a8ca1..6700308 100644
--- a/tx.go
+++ b/tx.go
@@ -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] {