func()

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
}