pub struct WindowRt {
pub spec: WindowSpec,
pub shape: WindowShape,
pub idle_ticks: u64,
/* private fields */
}Expand description
One index’s window state on one shard.
Fields§
§spec: WindowSpecThe declared window — width, column and retention — as the catalog recorded it. Fixed for the life of the index; everything else here is state that moves under it.
shape: WindowShapeWhich tree shape the boundary lives in — a plain i64 index or
a composite the window column leads (see WindowShape).
idle_ticks: u64Ticks that cost exactly one comparison (the idle-convergence gate counter).
Implementations§
Source§impl WindowRt
impl WindowRt
Sourcepub fn new(spec: WindowSpec, shape: WindowShape) -> Self
pub fn new(spec: WindowSpec, shape: WindowShape) -> Self
An empty window state: boundary at i64::MIN so the first row
admitted sets it, no cold segments, and a fresh bloom. Nothing is
read from disk here — a restart rebuilds by replaying, not by
trusting a persisted boundary.
Sourcepub fn has_cold(&self) -> bool
pub fn has_cold(&self) -> bool
Whether any rows have been frozen out of the live tree. A query
that answers false here can skip the cold merge entirely, which
is the common case and the reason this is a field check rather
than a directory scan.
Sourcepub fn boundary(&self) -> i64
pub fn boundary(&self) -> i64
The current eviction boundary: entries with window value below
this are cold. i64::MIN = nothing has evicted yet. Read by
the window-narrowing observation (a query’s lower - boundary
margin), never interpreted beyond ordering.
Sourcepub fn on_row_write(&mut self, row_key: &[u8])
pub fn on_row_write(&mut self, row_key: &[u8])
The write path saw row_key change: shadow whatever cold entry
it may have RIGHT NOW. A bloom false positive spends one stray
map entry that shadows nothing, which is the point: the reach
is the current sequence, and anything this row is given later
is sealed above it.
Sourcepub fn audit(&self, ty: ValType) -> Option<WindowAudit>
pub fn audit(&self, ty: ValType) -> Option<WindowAudit>
What an audit needs from the cold side: the boundary, the tree
shape, and how many entries are actually down there. None
until something has slid.
The count is over each segment’s OWN extent rather than a value range, because the caller wants “everything cold” and building an unbounded upper bound differs per tree shape — a segment already knows its own first and last key.
Sourcepub fn cold_count(
&self,
ty: ValType,
min: &IndexValue,
max: &IndexValue,
) -> Result<u64, String>
pub fn cold_count( &self, ty: ValType, min: &IndexValue, max: &IndexValue, ) -> Result<u64, String>
Cold count of values in [min, max]: fast whole-segment
arithmetic while no tombstones exist (the common state), a
decode walk once any do. Err = a segment refused (corrupt
derived spill) — the query reports it, never a partial number.
Sourcepub fn cold_hits(
&self,
ty: ValType,
min: &IndexValue,
max: &IndexValue,
cursor: Option<&Cursor>,
limit: usize,
) -> Result<Vec<(Vec<u8>, IndexValue)>, String>
pub fn cold_hits( &self, ty: ValType, min: &IndexValue, max: &IndexValue, cursor: Option<&Cursor>, limit: usize, ) -> Result<Vec<(Vec<u8>, IndexValue)>, String>
Cold hits of [min, max] in value order, tombstones skipped
and — when a page resumes — everything at or before cursor
skipped BEFORE the limit counts, at most limit. (Counting
first and filtering at the merge starves the cold side on any
page after the first: the limit fills with pre-cursor entries
that are then all dropped.) Segments hold disjoint ascending
value ranges (each slide covers [old_w, new_w)), so chaining
them in creation order IS value order. Err on a corrupt
segment — never a silent partial page.
Sourcepub fn cold_claused_count(
&self,
ty: ValType,
min: &IndexValue,
max: &IndexValue,
filters: &[(usize, ValueTest)],
) -> Result<u64, String>
pub fn cold_claused_count( &self, ty: ValType, min: &IndexValue, max: &IndexValue, filters: &[(usize, ValueTest)], ) -> Result<u64, String>
The clause-carrying cold count: the FILTER predicates applied
to each live cold entry’s payload values. Err on a corrupt
segment — the query reports it, never a partial number.
Sourcepub fn cold_claused(
&self,
ty: ValType,
min: &IndexValue,
max: &IndexValue,
cursor: Option<&Cursor>,
c: &ScalarClauses<'_>,
) -> Result<(Vec<ScalarHit>, Vec<Vec<FacetBucket>>), String>
pub fn cold_claused( &self, ty: ValType, min: &IndexValue, max: &IndexValue, cursor: Option<&Cursor>, c: &ScalarClauses<'_>, ) -> Result<(Vec<ScalarHit>, Vec<Vec<FacetBucket>>), String>
The clause-carrying cold page: every live cold entry in
[min, max] (past cursor when one rides), decoded and fed to
the shared clause walk — the same FILTER / SORT / DISTINCT /
FACET semantics the hot tree runs, over the frozen payloads.
Sourcepub fn pending_rows(&self, seg: &Segment) -> Option<Vec<Vec<u8>>>
pub fn pending_rows(&self, seg: &Segment) -> Option<Vec<Vec<u8>>>
The row keys that would evict if the boundary advanced now —
the row-eviction half reads this BEFORE Self::slide cuts
the index, so a failed row eviction leaves both layers hot and
the next tick retries the whole batch. No state changes.
Sourcepub fn slide(
&mut self,
index_name: &[u8],
seg: &mut Segment,
segs_dir: &Path,
) -> Result<bool, String>
pub fn slide( &mut self, index_name: &[u8], seg: &mut Segment, segs_dir: &Path, ) -> Result<bool, String>
Advance the boundary and evict the out-of-window tree prefix into a segment. One comparison when there is nothing to do. Build-then-cut: an I/O failure leaves the tree untouched and the boundary unmoved — the next tick retries.