pub struct RoutingFrame {
pub here: Vec<usize>,
pub selection: Selection,
pub slice: Arc<Slice>,
pub dim: usize,
}
Expand description
RoutingFrame
captures the state of a selection being evaluated:
the current coordinate (here
), the remaining selection to apply,
the shape and layout information (slice
), and the current
dimension (dim
).
Each frame represents an independent routing decision and produces
zero or more new frames via next_steps
.
Fields§
§here: Vec<usize>
The current coordinate in the mesh where this frame is being evaluated.
This is the source location for the next routing step.
selection: Selection
The residual selection expression describing where routing should continue.
At each step, only the current dimension (tracked by dim
) of
this selection is considered.
slice: Arc<Slice>
The shape and layout of the full multidimensional space being routed.
This determines the bounds and stride information used to compute coordinates and flat indices.
dim: usize
The current axis of traversal within the selection and slice.
Routing proceeds dimension-by-dimension; this value tracks how many dimensions have already been routed.
Implementations§
Source§impl RoutingFrame
impl RoutingFrame
Sourcepub fn root(selection: Selection, slice: Slice) -> RoutingFrame
pub fn root(selection: Selection, slice: Slice) -> RoutingFrame
Constructs the initial frame at the root coordinate (all
zeros). Selections are expanded as necessary to ensure they
have depth equal to the slice dimensionality. See the docs for
canonicalize_to_dimensions
for the rules.
§Canonical Handling of Zero-Dimensional Slices
A Slice
with zero dimensions represents the empty product
∏_{i=1}^{0} Xᵢ
, which has exactly one element: the empty
tuple. To maintain uniform routing semantics, we canonically
embed such 0D slices as 1D slices of extent 1:
Slice::new(offset, [1], [1])
This embedding preserves the correct number of addressable
points and allows the routing machinery to proceed through the
usual recursive strategy without introducing special cases. The
selected coordinate is vec![0]
, and dim = 0
proceeds as
usual. This makes the routing logic consistent with evaluation
and avoids edge case handling throughout the codebase.
Sourcepub fn advance(&self, here: Vec<usize>, selection: Selection) -> RoutingFrame
pub fn advance(&self, here: Vec<usize>, selection: Selection) -> RoutingFrame
Produces a new frame advanced to the next dimension with updated position and selection.
Sourcepub fn with_selection(&self, selection: Selection) -> RoutingFrame
pub fn with_selection(&self, selection: Selection) -> RoutingFrame
Returns a new frame with the same position and dimension but a different selection.
Sourcepub fn action(&self) -> RoutingAction
pub fn action(&self) -> RoutingAction
Determines the appropriate routing action for this frame.
Returns RoutingAction::Deliver
if the message should be
delivered at this coordinate, or RoutingAction::Forward
if
it should be routed further.
Sourcepub fn location(&self) -> Result<usize, SliceError>
pub fn location(&self) -> Result<usize, SliceError>
Returns the location of this frame in the underlying slice.
Source§impl RoutingFrame
impl RoutingFrame
Sourcepub fn next_steps(
&self,
_chooser: &mut dyn FnMut(&Choice) -> usize,
f: &mut dyn FnMut(RoutingStep) -> ControlFlow<()>,
) -> ControlFlow<()>
pub fn next_steps( &self, _chooser: &mut dyn FnMut(&Choice) -> usize, f: &mut dyn FnMut(RoutingStep) -> ControlFlow<()>, ) -> ControlFlow<()>
Visits the next routing steps from this frame using a
callback-based traversal.
This method structurally recurses on the Selection
expression, yielding RoutingStep
s via the f
callback.
Early termination is supported via ControlFlow::Break
.
Compared to the (old, now removed) [next_steps
] method, this
avoids intermediate allocation, supports interruptibility, and
allows policy-driven handling of RoutingStep::Choice
s via
the chooser
callback.
§Traversal Strategy
The traversal proceeds dimension-by-dimension, structurally mirroring the shape of the selection expression:
Selection::All
andSelection::Range
iterate over a range of coordinates, emitting oneRoutingStep::Forward
per valid index.Selection::Union
andSelection::Intersection
recurse into both branches. Intersection steps are joined at matching coordinates and residual selections are reduced.Selection::Any
randomly selects one index along the current dimension and emits a single step.Selection::True
andSelection::False
emit no steps.
At each step, only the current dimension (tracked via self.dim
)
is evaluated. Future dimensions remain untouched until deeper
recursion.
§Evaluation Semantics
-
Selection::True No further routing is performed — if this frame is at the final dimension, delivery occurs.
-
Selection::False No match — routing halts.
-
Selection::All / Selection::Range Emits one
RoutingStep::Forward
per matching index, each advancing to the next dimension with the inner selection. -
Selection::Union Evaluates both branches independently and emits all resulting steps.
-
Selection::Intersection Emits only those steps where both branches produce the same coordinate, combining the residual selections at that point.
-
Selection::Any Randomly selects one index and emits a single
RoutingStep::Forward
. -
Selection::Choice Defers decision to the caller by invoking the
chooser
function, which resolves the candidate index.
§Delivery Semantics
Message delivery is determined by
RoutingFrame::deliver_here
, which returns true when:
- The frame’s selection is
Selection::True
, and - All dimensions have been traversed (
dim == slice.num_dim()
).
§Panics
Panics if slice.num_dim() == 0
. Use a canonical embedding
(e.g., 0D → 1D) before calling this (see e.g.
RoutingFrame::root
).
§Summary
- Structure-driven: Mirrors the shape of the selection expression.
- Compositional: Each variant defines its own traversal behavior.
- Interruptible: Early termination is supported via
ControlFlow
. - Minimally allocating: Avoids intermediate buffers in
most cases; only
Selection::Intersection
allocates temporary state for pairwise matching. - Policy-ready: Integrates with runtime routing policies
via the
chooser
.
Sourcepub fn deliver_here(&self) -> bool
pub fn deliver_here(&self) -> bool
Returns true if this frame represents a terminal delivery
point — i.e., the selection is True
and all dimensions have
been traversed.
Sourcepub fn should_route(&self) -> bool
pub fn should_route(&self) -> bool
Returns true if the message has not yet reached its final destination and should be forwarded to the next routing step.
Source§impl RoutingFrame
impl RoutingFrame
Trait Implementations§
Source§impl Clone for RoutingFrame
impl Clone for RoutingFrame
Source§fn clone(&self) -> RoutingFrame
fn clone(&self) -> RoutingFrame
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl Debug for RoutingFrame
impl Debug for RoutingFrame
Source§impl<'de> Deserialize<'de> for RoutingFrame
impl<'de> Deserialize<'de> for RoutingFrame
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<RoutingFrame, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<RoutingFrame, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
Source§impl Serialize for RoutingFrame
impl Serialize for RoutingFrame
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
Auto Trait Implementations§
impl Freeze for RoutingFrame
impl RefUnwindSafe for RoutingFrame
impl Send for RoutingFrame
impl Sync for RoutingFrame
impl Unpin for RoutingFrame
impl UnwindSafe for RoutingFrame
Blanket Implementations§
§impl<T> AnySync for T
impl<T> AnySync for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<A, M> Handler<IndexedErasedUnbound<M>> for A
impl<A, M> Handler<IndexedErasedUnbound<M>> for A
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more