pub struct SessionRecallTracker { /* private fields */ }Expand description
v0.7.0 (issue #518) — process-global tracker mapping session_id
to its FIFO ring buffer of recently-accessed memory ids.
The tracker is consulted by apply_session_recency_boost after
the rerank stage of handle_recall (MCP) and recall_response
(HTTP). Each call:
- Reads the per-session set BEFORE assembling the boost so the candidates already touched in this session lift in rank.
- Appends every recall hit’s id INTO the per-session ring (FIFO
eviction past
SESSION_RECENT_CAP) so subsequent recalls in the same session reuse the new context.
The tracker uses a single Mutex because contention is dominated
by the per-recall work itself (FTS + semantic + rerank), making
the lock-acquire/-release cost noise; the implementation can swap
to per-shard locking if a future profile shows otherwise.
Implementations§
Source§impl SessionRecallTracker
impl SessionRecallTracker
Sourcepub fn new() -> Self
pub fn new() -> Self
Construct an empty tracker. Test code uses this directly; the
production code path goes through the process-global
global_session_recall_tracker accessor below.
Sourcepub fn recent_ids(&self, session_id: &str) -> HashSet<String>
pub fn recent_ids(&self, session_id: &str) -> HashSet<String>
Return the set of recently-accessed memory ids for session_id,
or an empty set if the session is unknown. Used by the rerank
boost to decide which candidates to lift.
v0.7.0 #1091 — kept for the public API contract (test code +
callers outside the hot path use it). The boost site
apply_session_recency_boost now uses
SessionRecallTracker::with_recent_ids to avoid the
per-recall HashSet allocation.
Sourcepub fn with_recent_ids<R>(
&self,
session_id: &str,
f: impl FnOnce(&dyn Fn(&str) -> bool) -> R,
) -> R
pub fn with_recent_ids<R>( &self, session_id: &str, f: impl FnOnce(&dyn Fn(&str) -> bool) -> R, ) -> R
v0.7.0 #1091 — allocation-free per-id membership lookup against
the per-session ring. Used by apply_session_recency_boost
to apply the +0.05 boost without cloning the 50-deep ring into
a fresh HashSet<String> on every recall.
The callback is invoked once with a membership predicate that
owns the inner mutex guard for its lifetime. Returns the
closure’s result (typically a Vec<(Memory, f64)> of boosted
candidates). The membership predicate is O(N) per id over the
ring (capped at SESSION_RECENT_CAP = 50); the closure is
expected to call it K times for a K-result recall, giving
O(K*N) total — same complexity as the pre-#1091 path that
also did a HashSet build (O(N) construct) + K lookups
(O(1) each = O(K)).
Sourcepub fn record(&self, session_id: &str, ids: impl IntoIterator<Item = String>)
pub fn record(&self, session_id: &str, ids: impl IntoIterator<Item = String>)
Record the ids of memories returned by the just-completed
recall into the per-session ring. FIFO eviction past
SESSION_RECENT_CAP keeps the per-session set bounded.
Duplicate ids (a memory recalled twice in the same session) move to the front of the ring so the eviction rule keeps the most-recently-touched ids in the set.
Sourcepub fn session_count(&self) -> usize
pub fn session_count(&self) -> usize
Diagnostic: number of tracked sessions. Used by tests and the
/metrics surface (future).
Trait Implementations§
Source§impl Debug for SessionRecallTracker
impl Debug for SessionRecallTracker
Source§impl Default for SessionRecallTracker
impl Default for SessionRecallTracker
Source§fn default() -> SessionRecallTracker
fn default() -> SessionRecallTracker
Auto Trait Implementations§
impl !Freeze for SessionRecallTracker
impl RefUnwindSafe for SessionRecallTracker
impl Send for SessionRecallTracker
impl Sync for SessionRecallTracker
impl Unpin for SessionRecallTracker
impl UnsafeUnpin for SessionRecallTracker
impl UnwindSafe for SessionRecallTracker
Blanket Implementations§
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
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§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