Skip to content

Commit

Permalink
move method freePages into freelist.go
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
ahrtr committed Jul 1, 2024
1 parent cc78a5a commit f219a03
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 28 deletions.
31 changes: 3 additions & 28 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"io"
"os"
"runtime"
"sort"
"sync"
"time"
"unsafe"
Expand Down Expand Up @@ -797,6 +796,7 @@ func (db *DB) beginTx() (*Tx, error) {
// Keep track of transaction until it closes.
db.txs = append(db.txs, t)
n := len(db.txs)
db.freelist.addReadonlyTXID(t.meta.Txid())

// Unlock the meta pages.
db.metalock.Unlock()
Expand Down Expand Up @@ -841,36 +841,10 @@ func (db *DB) beginRWTx() (*Tx, error) {
t := &Tx{writable: true}
t.init(db)
db.rwtx = t
db.freePages()
db.freelist.freePages()
return t, nil
}

// freePages releases any pages associated with closed read-only transactions.
func (db *DB) freePages() {
// Free all pending pages prior to earliest open transaction.
sort.Sort(txsById(db.txs))
minid := common.Txid(0xFFFFFFFFFFFFFFFF)
if len(db.txs) > 0 {
minid = db.txs[0].meta.Txid()
}
if minid > 0 {
db.freelist.release(minid - 1)
}
// Release unused txid extents.
for _, t := range db.txs {
db.freelist.releaseRange(minid, t.meta.Txid()-1)
minid = t.meta.Txid() + 1
}
db.freelist.releaseRange(minid, common.Txid(0xFFFFFFFFFFFFFFFF))
// Any page both allocated and freed in an extent is safe to release.
}

type txsById []*Tx

func (t txsById) Len() int { return len(t) }
func (t txsById) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
func (t txsById) Less(i, j int) bool { return t[i].meta.Txid() < t[j].meta.Txid() }

// removeTx removes a transaction from the database.
func (db *DB) removeTx(tx *Tx) {
// Release the read lock on the mmap.
Expand All @@ -890,6 +864,7 @@ func (db *DB) removeTx(tx *Tx) {
}
}
n := len(db.txs)
db.freelist.removeReadonlyTXID(tx.meta.Txid())

// Unlock the meta pages.
db.metalock.Unlock()
Expand Down
42 changes: 42 additions & 0 deletions freelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type pidSet map[common.Pgid]struct{}
type freelist struct {
freelistType FreelistType // freelist type
ids []common.Pgid // all free and available free page ids.
readonlyTXIDs []common.Txid // all readonly transaction IDs.
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.
cache map[common.Pgid]struct{} // fast lookup of all free and pending page ids.
Expand Down Expand Up @@ -326,3 +327,44 @@ func (f *freelist) reindex() {
}
}
}

func (f *freelist) addReadonlyTXID(tid common.Txid) {
f.readonlyTXIDs = append(f.readonlyTXIDs, tid)
}

func (f *freelist) removeReadonlyTXID(tid common.Txid) {
for i := range f.readonlyTXIDs {
if f.readonlyTXIDs[i] == tid {
last := len(f.readonlyTXIDs) - 1
f.readonlyTXIDs[i] = f.readonlyTXIDs[last]
f.readonlyTXIDs = f.readonlyTXIDs[:last]
break
}
}
}

type txIDx []common.Txid

func (t txIDx) Len() int { return len(t) }
func (t txIDx) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
func (t txIDx) Less(i, j int) bool { return t[i] < t[j] }

// freePages releases any pages associated with closed read-only transactions.
func (f *freelist) freePages() {
// Free all pending pages prior to earliest open transaction.
sort.Sort(txIDx(f.readonlyTXIDs))
minid := common.Txid(0xFFFFFFFFFFFFFFFF)
if len(f.readonlyTXIDs) > 0 {
minid = f.readonlyTXIDs[0]
}
if minid > 0 {
f.release(minid - 1)
}
// Release unused txid extents.
for _, tid := range f.readonlyTXIDs {
f.releaseRange(minid, tid-1)
minid = tid + 1
}
f.releaseRange(minid, common.Txid(0xFFFFFFFFFFFFFFFF))
// Any page both allocated and freed in an extent is safe to release.
}

0 comments on commit f219a03

Please sign in to comment.