Skip to main content

ExternalBlockAssignments

Struct ExternalBlockAssignments 

Source
pub struct ExternalBlockAssignments { /* private fields */ }
Expand description

Per-tier block_id tracking with an offset into the sequence.

Maintains an ordered mapping of BlockIdSequenceHash for assigned blocks, a staging area for blocks whose hashes have been computed but not yet committed, plus a FIFO queue of block_ids waiting for assignment. Index i in the assigned map corresponds to sequence position offset + i.

The three-phase lifecycle is:

  • Unassigned — block_ids queued for assignment (no hash yet).
  • Staged — block_ids paired with their SequenceHash but not yet committed.
  • Assigned — committed BlockId → SequenceHash pairs in positional order.

Multiple ExternalBlockAssignments instances can operate on the same &[TokenBlock] at different offsets (multi-tier).

Implementations§

Source§

impl ExternalBlockAssignments

Source

pub fn new(offset: usize) -> Self

Creates a new ExternalBlockAssignments starting at the given offset.

Source

pub fn offset(&self) -> usize

Returns the starting position in the sequence.

Source

pub fn contains(&self, block_id: &BlockId) -> bool

Checks whether a block_id is known (assigned, staged, or unassigned).

Source

pub fn get_assigned(&self, index: usize) -> Option<(BlockId, SequenceHash)>

Positional access: returns (BlockId, SequenceHash) at the given index (relative to offset) in the assigned collection.

Source

pub fn assigned_count(&self) -> usize

Returns the number of assigned blocks.

Source

pub fn staged_count(&self) -> usize

Returns the number of staged blocks.

Source

pub fn unassigned_count(&self) -> usize

Returns the number of unassigned (pending) block_ids.

Source

pub fn get_staged(&self, index: usize) -> Option<(BlockId, SequenceHash)>

Positional access: returns (BlockId, SequenceHash) at the given index (relative to the start of staged) in the staged collection.

Source

pub fn assigned_iter( &self, ) -> impl Iterator<Item = (BlockId, SequenceHash)> + '_

Iterates over assigned blocks in positional order, yielding (BlockId, SequenceHash).

Source

pub fn staged_iter(&self) -> impl Iterator<Item = (BlockId, SequenceHash)> + '_

Iterates over staged blocks in staging order, yielding (BlockId, SequenceHash).

Source

pub fn unassigned_iter(&self) -> impl Iterator<Item = BlockId> + '_

Iterates over unassigned block_ids in FIFO order.

Source

pub fn clear(&mut self)

Clears all assigned, staged, and unassigned blocks, preserving the offset.

Source

pub fn take_staged(&mut self) -> Vec<(BlockId, SequenceHash)>

Takes all staged blocks, returning them as a Vec.

Source

pub fn next_position(&self) -> usize

Returns the next sequence position to be assigned: offset + assigned_count + staged_count.

Source

pub fn assigned_positions(&self) -> Range<usize>

Absolute position range of assigned blocks: offset..offset + assigned_count.

Source

pub fn staged_positions(&self) -> Range<usize>

Absolute position range of staged blocks: offset + assigned_count .. offset + assigned_count + staged_count.

Source

pub fn get_at_position(&self, abs_pos: usize) -> Option<(BlockId, SequenceHash)>

Get the assigned (BlockId, SequenceHash) at an absolute sequence position.

Returns None if abs_pos is outside assigned_positions().

Source

pub fn pending_positions(&self) -> Range<usize>

Absolute position range that pending (unassigned) blocks will occupy once flushed: next_position()..next_position() + unassigned_count().

Source

pub fn get_pending_at_position(&self, abs_pos: usize) -> Option<BlockId>

Get the pending BlockId at an absolute sequence position (FIFO order).

Position next_position() maps to the first unassigned block, next_position() + 1 to the second, etc. Returns None if abs_pos is outside pending_positions().

Source

pub fn extend_block_ids( &mut self, block_ids: impl IntoIterator<Item = BlockId>, ) -> Result<(), BlockSequenceError>

Add new block_ids to the unassigned queue.

block_ids is the full, ordered list of block IDs allocated to this assignment set. Known IDs (already in assigned, staged, or unassigned) must form a contiguous prefix and are silently skipped. New IDs are appended to the unassigned FIFO queue.

This method does not assign blocks — call assign_pending to pair unassigned IDs with available sequence blocks.

§Block ID rules

The list is partitioned into a known prefix and a new suffix:

  • Known prefix — IDs already present in assigned, staged, or unassigned. These are silently skipped. They must appear contiguously at the front of the list; interleaving a known ID after an unknown one is an OrderingViolation.
  • New suffix — IDs not yet seen. These are appended (in order) to the unassigned FIFO queue.
§Algorithm (two-phase, atomic)
  1. Validate & collect — iterate block_ids. Known IDs must form a contiguous prefix (skip them). Unknown IDs are collected into a temp buffer. If a known ID appears after an unknown one → OrderingViolation error. No state is mutated until validation passes.
  2. Commit — push all new IDs to the unassigned queue.
Source

pub fn extend_assigned( &mut self, items: impl IntoIterator<Item = (BlockId, SequenceHash)>, ) -> Result<usize, BlockSequenceError>

Inserts pre-matched (BlockId, SequenceHash) pairs directly into the assigned collection.

This is the entry point for blocks whose hashes are already known (e.g. cache hits). Two-phase atomic: collects all items, validates no duplicate BlockIds across all three collections, then commits to assigned.

Source

pub fn stage_pending( &mut self, sequence_blocks: &[TokenBlock], ) -> Result<Range<usize>, BlockSequenceError>

FIFO drain from unassigned into staged, pairing each block_id with the sequence hash from the corresponding TokenBlock.

Staging starts at sequence_blocks[self.next_position()] and proceeds forward, consuming one unassigned ID per available block. The loop stops when either the unassigned queue is empty or there are no more sequence blocks.

Returns the range of newly staged indices (relative to the start of the staged collection before this call).

Each staged pair is validated: the position embedded in the block’s kvbm_sequence_hash() must equal the expected sequence index. A mismatch returns BlockSequenceError::PositionMismatch.

Source

pub fn commit_staged(&mut self) -> Range<usize>

Moves all staged blocks into assigned (infallible).

Returns the range of newly assigned indices (relative to the start of the assigned collection before this call).

Source

pub fn assign_pending( &mut self, sequence_blocks: &[TokenBlock], ) -> Result<Range<usize>, BlockSequenceError>

Drain the unassigned FIFO queue into assigned, pairing each block_id with the next available TokenBlock starting at next_position().

This is a convenience method equivalent to calling stage_pending followed by commit_staged.

Returns the range of newly assigned indices (relative to offset). An empty range means no new assignments were made.

Trait Implementations§

Source§

impl Debug for ExternalBlockAssignments

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more