Skip to main content

PositiveProbeCache

Struct PositiveProbeCache 

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

Bounded LRU cache of hash → Vec<(NodeId, rate_per_mb, rtt)>.

Implementations§

Source§

impl PositiveProbeCache

Source

pub fn new() -> Self

Build a cache with the ADR 001 §Probe cache defaults (1024 hashes, 15s TTL, ≤10 providers per hash).

Source

pub fn with_capacity_and_ttl(cap: usize, ttl: Duration) -> Self

Build a cache with an explicit capacity and TTL.

Production code uses Self::new; this is the test / tuning seam, for the same reason super::negative_cache::NegativeProbeCache::with_capacity_and_ttl is: the TTL is anchored on Instant, so tokio::time pause / advance has no effect on it, and 15s of wall clock per assertion is not a test suite. cap is clamped to ≥ 1.

A ttl of Duration::ZERO disables the cache behaviourally: every entry is already expired the instant it is read, so Self::get always misses. That is the supported way to opt out of positive caching — there is deliberately no disabled() constructor, because a constructor that turns off an ADR-mandated behaviour is a thing production code will eventually call.

Source

pub fn get(&self, hash: &Hash) -> Option<Vec<ProbedProvider>>

The cached providers for hash, best-first, iff an entry exists and its TTL hasn’t elapsed.

A live hit bumps the entry to the front of the LRU ordering (index 0) without refreshing its expiry — TTL is anchored at insertion per ADR 001 §Probe cache. An expired entry is evicted before returning None.

Returns a clone rather than a guard-scoped borrow on purpose: the caller rebuilds Candidates from this, which means an await on region_of(..) per provider, and holding a std::sync::Mutex guard across an await is exactly the hazard clippy::await_holding_lock exists for. At ≤10 small providers — each a triple plus a coverage bitmap sized to the blob’s block count — the clone is not worth arguing about.

Source

pub fn insert(&self, hash: Hash, providers: Vec<ProbedProvider>)

Insert / replace the entry for hash with now + TTL expiry, moving it to the front of the LRU ordering. Evicts the least-recently-used hash on cap overflow.

providers MUST already be in selection order, best-first: this keeps the first MAX_PROVIDERS_PER_HASH, which is ADR 001’s “top 10 by selection score” only if the caller ranked first. The cache cannot rank them itself — the selection score needs reputation, which is precisely the field this cache refuses to store.

An empty providers is a no-op. An empty entry is strictly worse than no entry: it would occupy an LRU slot, hit on every read, and yield nothing — a cache of “we found nobody”, which is the negative cache’s job and not on the negative cache’s terms.

Source

pub fn invalidate(&self, hash: &Hash)

Drop the entry for hash, if any.

ADR 001 §Probe cache: “if all fail, run a fresh DHT lookup + probe.” A hit whose every BUDGETED provider failed to deliver has been disproved by the only evidence that outranks a probe — actual pulls — so it is removed rather than left to keep hitting for the rest of its TTL. The caller may not have tried the entry’s whole list (the attempt budget can be smaller than the list); the top-ranked members failing is disproof enough.

Source

pub fn len(&self) -> usize

Current hash count. Includes expired entries that haven’t been swept yet — call Self::get first if a precise live count is needed.

Source

pub fn is_empty(&self) -> bool

Whether the cache holds zero entries (including stale).

Trait Implementations§

Source§

impl Debug for PositiveProbeCache

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for PositiveProbeCache

Source§

fn default() -> Self

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> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self> ⓘ

Attaches the current Context to this type, returning a WithContext wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> MaybeSend for T
where T: Send,

Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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