Skip to main content

NeighborCache

Struct NeighborCache 

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

Ready results plus in-flight/failed bookkeeping.

Implementations§

Source§

impl NeighborCache

Source

pub fn new() -> Self

Source

pub fn get(&self, k: &CacheKey) -> Option<&NeighborResult>

Source

pub fn error(&self, k: &CacheKey) -> Option<&str>

Source

pub fn mark_wanted(&mut self, k: CacheKey)

Queue a miss for fetching. Idempotent: a key already ready, in flight, failed, or already queued is not queued again — so holding a navigation key cannot stampede the backend and a failure cannot retry-loop.

Source

pub fn take_wanted(&mut self) -> Vec<(CacheKey, u64)>

Drain queued keys, marking each in flight under a fresh epoch. The epoch identifies THIS attempt: the host must hand it back to fill/fail so a settle can be matched to the attempt that produced it. Without that, two outstanding attempts for one key (possible after a cancel, since the key carries no slot and re-queues) are indistinguishable.

Source

pub fn fill(&mut self, k: CacheKey, epoch: u64, res: NeighborResult)

Store a received result for the attempt tagged epoch. pending is a client-side concept — it means “this placeholder stands in for a fetch we have not received yet” — so a value decoded off the wire is never trusted: a host or proxy echoing {"pending":true} would otherwise land a permanent cache HIT that reports pending, wedging the view on a spinner that can never resolve.

Source

pub fn fail(&mut self, k: CacheKey, epoch: u64, err: String)

Record a failure for the attempt tagged epoch.

Source

pub fn cancel(&mut self, k: &CacheKey)

Cancel a fetch. A key still queued is simply dequeued; a key in flight loses its slot, so is_loading() goes quiet at once and the stale settle is discarded by the epoch check in fill/fail. Cancellation is not sticky: the key carries no slot afterwards, so mark_wanted queues it again.

Source

pub fn is_in_flight(&self, k: &CacheKey) -> bool

Whether a fetch for k is currently outstanding. Hosts holding per-fetch resources (an AbortController, say) use this to prune.

Source

pub fn take_dirty(&mut self) -> bool

True once since the last call; consumed by the renderer.

Source

pub fn take_failures(&mut self) -> Vec<(CacheKey, String)>

Drain failures that have not yet been reported. The Slot::Failed record remains, so a failed key still does not auto-retry.

Source

pub fn take_new_arrivals(&mut self) -> Vec<CacheKey>

Drain the keys filled since the last call, so a host can absorb only what actually arrived instead of re-walking every ready result.

Source

pub fn clear_failures(&mut self)

Forget every recorded failure, so those keys can be queued again by a subsequent mark_wanted. Ready and in-flight entries are untouched. Failures are never cleared automatically — that would hammer a down backend — so this is the hook behind an explicit host “retry”.

Source

pub fn reset(&mut self)

Forget everything: entries, in-flight slots, the queue, the dirty flag, undrained failures and arrivals, and the settled high-water map.

A load REPLACES the dataset, so every cached neighborhood now describes a graph that no longer exists. Keeping them would serve the old graph’s neighbors for any id the new one happens to reuse — and id reuse is the norm rather than the exception for generated or synthetically-keyed datasets, where w0/c0 mean something different in each. Recorded failures are wrong for exactly the same reason, and worse for being sticky: a node that failed under the old dataset would be a permanent dead end under the new one.

next_epoch deliberately does NOT restart. Fetches issued for the old dataset are still on the wire, and rewinding the counter would let one of them settle under an epoch a post-reset attempt also claims. Instead the counter’s current value becomes an epoch floor: every attempt drawn before this reset is at or below it, and is_stale discards it on arrival. Without that floor, clearing slots and settled would actually WIDEN the hole — both of fill’s other guards read those maps, so an old-dataset answer would land unopposed.

Source

pub fn is_loading(&self) -> bool

Source

pub fn ready_results(&self) -> impl Iterator<Item = &NeighborResult>

Every result received so far. Used to grow the known graph (the traditional view starts at the seed and expands as neighborhoods land).

Trait Implementations§

Source§

impl Default for NeighborCache

Source§

fn default() -> NeighborCache

Returns the “default value” for a type. 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, 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.