Skip to content

Commit f2b2bba

Browse files
committed
move method freePages into freelist.go
The motivation is to get all freelist related logic included in freelist.go. We are going to introduce freelist interface in the next step. Signed-off-by: Benjamin Wang <benjamin.ahrtr@gmail.com>
1 parent cc78a5a commit f2b2bba

File tree

2 files changed

+49
-28
lines changed

2 files changed

+49
-28
lines changed

db.go

+7-28
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"io"
77
"os"
88
"runtime"
9-
"sort"
109
"sync"
1110
"time"
1211
"unsafe"
@@ -797,6 +796,9 @@ func (db *DB) beginTx() (*Tx, error) {
797796
// Keep track of transaction until it closes.
798797
db.txs = append(db.txs, t)
799798
n := len(db.txs)
799+
if db.freelist != nil {
800+
db.freelist.addReadonlyTXID(t.meta.Txid())
801+
}
800802

801803
// Unlock the meta pages.
802804
db.metalock.Unlock()
@@ -841,36 +843,10 @@ func (db *DB) beginRWTx() (*Tx, error) {
841843
t := &Tx{writable: true}
842844
t.init(db)
843845
db.rwtx = t
844-
db.freePages()
846+
db.freelist.freePages()
845847
return t, nil
846848
}
847849

848-
// freePages releases any pages associated with closed read-only transactions.
849-
func (db *DB) freePages() {
850-
// Free all pending pages prior to earliest open transaction.
851-
sort.Sort(txsById(db.txs))
852-
minid := common.Txid(0xFFFFFFFFFFFFFFFF)
853-
if len(db.txs) > 0 {
854-
minid = db.txs[0].meta.Txid()
855-
}
856-
if minid > 0 {
857-
db.freelist.release(minid - 1)
858-
}
859-
// Release unused txid extents.
860-
for _, t := range db.txs {
861-
db.freelist.releaseRange(minid, t.meta.Txid()-1)
862-
minid = t.meta.Txid() + 1
863-
}
864-
db.freelist.releaseRange(minid, common.Txid(0xFFFFFFFFFFFFFFFF))
865-
// Any page both allocated and freed in an extent is safe to release.
866-
}
867-
868-
type txsById []*Tx
869-
870-
func (t txsById) Len() int { return len(t) }
871-
func (t txsById) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
872-
func (t txsById) Less(i, j int) bool { return t[i].meta.Txid() < t[j].meta.Txid() }
873-
874850
// removeTx removes a transaction from the database.
875851
func (db *DB) removeTx(tx *Tx) {
876852
// Release the read lock on the mmap.
@@ -890,6 +866,9 @@ func (db *DB) removeTx(tx *Tx) {
890866
}
891867
}
892868
n := len(db.txs)
869+
if db.freelist != nil {
870+
db.freelist.removeReadonlyTXID(tx.meta.Txid())
871+
}
893872

894873
// Unlock the meta pages.
895874
db.metalock.Unlock()

freelist.go

+42
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type pidSet map[common.Pgid]struct{}
2424
type freelist struct {
2525
freelistType FreelistType // freelist type
2626
ids []common.Pgid // all free and available free page ids.
27+
readonlyTXIDs []common.Txid // all readonly transaction IDs.
2728
allocs map[common.Pgid]common.Txid // mapping of Txid that allocated a pgid.
2829
pending map[common.Txid]*txPending // mapping of soon-to-be free page ids by tx.
2930
cache map[common.Pgid]struct{} // fast lookup of all free and pending page ids.
@@ -326,3 +327,44 @@ func (f *freelist) reindex() {
326327
}
327328
}
328329
}
330+
331+
func (f *freelist) addReadonlyTXID(tid common.Txid) {
332+
f.readonlyTXIDs = append(f.readonlyTXIDs, tid)
333+
}
334+
335+
func (f *freelist) removeReadonlyTXID(tid common.Txid) {
336+
for i := range f.readonlyTXIDs {
337+
if f.readonlyTXIDs[i] == tid {
338+
last := len(f.readonlyTXIDs) - 1
339+
f.readonlyTXIDs[i] = f.readonlyTXIDs[last]
340+
f.readonlyTXIDs = f.readonlyTXIDs[:last]
341+
break
342+
}
343+
}
344+
}
345+
346+
type txIDx []common.Txid
347+
348+
func (t txIDx) Len() int { return len(t) }
349+
func (t txIDx) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
350+
func (t txIDx) Less(i, j int) bool { return t[i] < t[j] }
351+
352+
// freePages releases any pages associated with closed read-only transactions.
353+
func (f *freelist) freePages() {
354+
// Free all pending pages prior to earliest open transaction.
355+
sort.Sort(txIDx(f.readonlyTXIDs))
356+
minid := common.Txid(0xFFFFFFFFFFFFFFFF)
357+
if len(f.readonlyTXIDs) > 0 {
358+
minid = f.readonlyTXIDs[0]
359+
}
360+
if minid > 0 {
361+
f.release(minid - 1)
362+
}
363+
// Release unused txid extents.
364+
for _, tid := range f.readonlyTXIDs {
365+
f.releaseRange(minid, tid-1)
366+
minid = tid + 1
367+
}
368+
f.releaseRange(minid, common.Txid(0xFFFFFFFFFFFFFFFF))
369+
// Any page both allocated and freed in an extent is safe to release.
370+
}

0 commit comments

Comments
 (0)