in pq/ack.go [227:281]
func (a *acker) collectFreePages(c *txCursor, endID uint64) ([]txfile.PageID, bool, reason) {
const op = "pq/collect-acked-pages"
var (
ids []txfile.PageID
lastID uint64
cleanAll = false
)
for {
hdr, err := c.PageHeader()
if err != nil {
return nil, false, a.errWrap(op, err)
}
next := hdr.next.Get()
// stop searching if current page is the last page. The last page must
// be active for the writer to add more events and link new pages.
isWritePage := next == 0
// stop searching if endID is in the current write page
dataOnlyPage := hdr.off.Get() == 0 // no event starts within this page
if !dataOnlyPage {
lastID = hdr.last.Get()
// inc 'lastID', so to hold on current page if endID would point to next
// the page. This helps the reader, potentially pointing to the current
// page, if next page has not been committed when reading events.
lastID++
// remove page if endID points past current data page
keepPage := isWritePage || idLessEq(endID, lastID)
if keepPage {
break
}
}
if isWritePage {
cleanAll = true
invariant.Checkf(lastID+1 == endID, "last event ID (%v) and ack event id (%v) missmatch", lastID, endID)
break
}
// found intermediate page with ACKed events/contents
// -> add page id to freelist and advance to next page
ids = append(ids, c.cursor.page)
ok, err := c.AdvancePage()
if err != nil {
return nil, false, a.errWrap(op, err)
}
invariant.Check(ok, "page list linkage broken")
}
return ids, cleanAll, nil
}