Skip to content

Commit f3d0323

Browse files
committed
apend
1 parent 36478e5 commit f3d0323

3 files changed

Lines changed: 68 additions & 2 deletions

File tree

src/client/builder.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,17 @@ impl EngineBuilder {
507507
retriever.with_content_config(retrieval_config.content.to_aggregator_config());
508508
}
509509

510+
// Add memo store if provided or create default
511+
if let Some(memo_store) = self.memo_store {
512+
retriever = retriever.with_memo_store(memo_store);
513+
} else {
514+
// Create default memo store with model from config
515+
let memo_store = MemoStore::new()
516+
.with_model(&retrieval_config.model)
517+
.with_version(1);
518+
retriever = retriever.with_memo_store(memo_store);
519+
}
520+
510521
// Build engine
511522
Engine::with_components(config, workspace, retriever, executor)
512523
.await

src/memo/store.rs

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,44 @@ struct MemoStoreData {
4242
stats: MemoStats,
4343
}
4444

45+
/// Atomic statistics for lock-free access.
46+
#[derive(Debug, Default)]
47+
struct AtomicStats {
48+
hits: AtomicU64,
49+
misses: AtomicU64,
50+
tokens_saved: AtomicU64,
51+
}
52+
53+
impl AtomicStats {
54+
fn new() -> Self {
55+
Self {
56+
hits: AtomicU64::new(0),
57+
misses: AtomicU64::new(0),
58+
tokens_saved: AtomicU64::new(0),
59+
}
60+
}
61+
62+
fn record_hit(&self) {
63+
self.hits.fetch_add(1, Ordering::Relaxed);
64+
}
65+
66+
fn record_miss(&self) {
67+
self.misses.fetch_add(1, Ordering::Relaxed);
68+
}
69+
70+
fn add_tokens_saved(&self, tokens: u64) {
71+
self.tokens_saved.fetch_add(tokens, Ordering::Relaxed);
72+
}
73+
74+
fn snapshot(&self) -> (u64, u64, u64) {
75+
(
76+
self.hits.load(Ordering::Relaxed),
77+
self.misses.load(Ordering::Relaxed),
78+
self.tokens_saved.load(Ordering::Relaxed),
79+
)
80+
}
81+
}
82+
4583
/// LLM Memoization store.
4684
///
4785
/// Provides caching for expensive LLM operations with:
@@ -79,6 +117,17 @@ pub struct MemoStore {
79117
version: u32,
80118
}
81119

120+
impl std::fmt::Debug for MemoStore {
121+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122+
f.debug_struct("MemoStore")
123+
.field("ttl", &self.ttl)
124+
.field("model_id", &self.model_id)
125+
.field("version", &self.version)
126+
.field("cache_len", &self.cache.read().len())
127+
.finish()
128+
}
129+
}
130+
82131
impl Clone for MemoStore {
83132
fn clone(&self) -> Self {
84133
Self {
@@ -639,8 +688,13 @@ mod tests {
639688
.await
640689
.unwrap();
641690

642-
// Hit
643-
store.get(&key);
691+
// Hit via get_or_compute (this updates global stats)
692+
store
693+
.get_or_compute(key.clone(), || async {
694+
Ok((MemoValue::Summary("Should not be called".to_string()), 0))
695+
})
696+
.await
697+
.unwrap();
644698

645699
let stats = store.stats().await;
646700
assert_eq!(stats.misses, 1);

src/retrieval/pipeline_retriever.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ impl Clone for PipelineRetriever {
200200
max_backtracks: self.max_backtracks,
201201
max_iterations: self.max_iterations,
202202
content_config: self.content_config.clone(),
203+
memo_store: self.memo_store.clone(),
203204
}
204205
}
205206
}

0 commit comments

Comments
 (0)