45.7 Reservations

A reservation temporarily prevents a segment from becoming eligible for the delta-FSS, even when its utilisation is zero. Reservations are transient and are not stored in a checkpoint.

Why segments are reserved

  • A serial-element reader reserves a segment while accessing a packet that cleaning may make obsolete.
  • The SegmentWriter reserves the current segment being prepared in memory and its preallocated next segment.
  • LargeSUT reserves segments occupied by SUT sections, whose packet utilisation is zero even though the segments are in use.

The RPM lookup of a packet position and reservation of its segment must form one safe logical operation. Otherwise a cleaner could relocate the packet and free its old segment between the lookup and reservation.

Relationship with zero utilisation

A segment is transferred to the delta-FSS only when its utilisation and reservation count are both zero. If utilisation reaches zero while reservations remain, the final unreservation performs the eligibility transition. Reserving the current log-tail segment also handles temporary transitions to zero while packets are removed before their replacements are written.

AllocateSegId() and AllocateGivenSegId() implicitly reserve their result. Their caller must eventually unreserve it. The latter operation is used while recovery replays historical segment allocation.

Lifetime and diagnostics

All reservations should have been released when an LSS is closed. A remaining reservation indicates a lifetime error analogous to a memory leak and can cause the store file to grow because an otherwise free segment never becomes reusable. SegmentUnreserver provides RAII-based release for relevant operations.

Implementation

The current implementation represents a reservation count by repeating the SegId in a vector. A segment is reserved if the vector contains its SegId; unreserving removes one occurrence. The vector contains only active reservations and is expected to remain small.


class Reservations
{
public:
    ~Reservations();
    void Write(xostream& os) const;
    bool IsSegmentReserved(SegId segid) const;
    void ReserveSegment(SegId segid);
    bool UnreserveSegment(SegId segid);

private:
    // Store all SegIds that are reserved, order doesn't matter, a given SegId can be repeated.
    std::vector<SegId> values_;
};