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