perf(server): eliminate implicit full-collection clones by removing Store::read() in favor of read_with()

This commit is contained in:
Riz Ashraf committed 2026-09-21 16:25:57 +01:00
1 parent 84ad64156c
commit 1d5e4bd00d
8 files changed
+80 -23

No files matched your search

+4 -4
View File
@@ -307,8 +307,8 @@ async fn run_server(state: Arc<MemoryState>) -> Result<(), Box<dyn std::error::E
get({
let state_clone = app_state.handler.state.clone();
move || async move {
let tasks = state_clone.tasks.read();
axum::Json(tasks.clone())
let tasks = state_clone.tasks.read_with(|t| t.clone());
axum::Json(tasks)
}
}),
)
@@ -317,8 +317,8 @@ async fn run_server(state: Arc<MemoryState>) -> Result<(), Box<dyn std::error::E
get({
let state_clone = app_state.handler.state.clone();
move || async move {
let sticky = state_clone.sticky.read();
axum::Json(sticky.clone())
let sticky = state_clone.sticky.read_with(|s| s.clone());
axum::Json(sticky)
}
}),
)
+8 -4
View File
@@ -215,14 +215,18 @@ impl MemoryIndex {
pub fn index_batch(
&self,
entities: Vec<Entity>,
tasks: Vec<Task>,
snippets: Vec<Snippet>,
adrs: Vec<Adr>,
entities: &[Entity],
tasks: &[Task],
snippets: &[Snippet],
adrs: &[Adr],
) -> tokio::task::JoinHandle<tantivy::Result<()>> {
let writer = Arc::clone(&self.writer);
let id_field = self.id_field;
let entities = entities.to_vec();
let tasks = tasks.to_vec();
let snippets = snippets.to_vec();
let title_field = self.title_field;
let adrs = adrs.to_vec();
let body_field = self.body_field;
let type_field = self.type_field;
let namespace_field = self.namespace_field;
+6 -6
View File
@@ -46,7 +46,7 @@ impl MemoryState {
}
pub fn get_full_graph(&self) -> KnowledgeGraph {
self.graph.read()
self.graph.read_with(|g| g.clone())
}
pub fn read_graph<F, R>(&self, f: F) -> R
@@ -62,12 +62,12 @@ impl MemoryState {
pub async fn rebuild_index(&self) {
if let Ok(new_idx) = MemoryIndex::new(&self.base_dir) {
let entities = self.graph.read().entities.into_values().collect();
let tasks = self.tasks.read();
let snippets = self.snippets.read();
let adrs = self.adrs.read();
let entities: Vec<Entity> = self.graph.read_with(|g| g.entities.values().cloned().collect());
let tasks = self.tasks.read_with(|t| t.clone());
let snippets = self.snippets.read_with(|s| s.clone());
let adrs = self.adrs.read_with(|a| a.clone());
let handle = new_idx.index_batch(entities, tasks, snippets, adrs);
let handle = new_idx.index_batch(&entities, &tasks, &snippets, &adrs);
let _ = handle.await;
let _ = new_idx.commit().await;
+4 -9
View File
@@ -59,11 +59,6 @@ impl<T: DeserializeOwned + Default + Serialize + Clone + Send + Sync + 'static>
T::default()
}
pub fn read(&self) -> T {
let lock = self.cache.read().unwrap_or_else(|e| e.into_inner());
lock.clone()
}
pub fn read_with<F, R>(&self, f: F) -> R
where
F: FnOnce(&T) -> R,
@@ -106,7 +101,7 @@ mod tests {
let db = Arc::new(db);
let store = Store::<TestData>::new("test_key", db.clone());
assert_eq!(store.read(), TestData::default());
assert_eq!(store.read_with(|s| s.clone()), TestData::default());
store.modify(|data| {
data.name = "Hello".to_string();
@@ -117,7 +112,7 @@ mod tests {
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
assert_eq!(
store.read(),
store.read_with(|s| s.clone()),
TestData {
name: "Hello".to_string(),
value: 42
@@ -127,7 +122,7 @@ mod tests {
// Load again to verify persistence
let store2 = Store::<TestData>::new("test_key", db.clone());
assert_eq!(
store2.read(),
store2.read_with(|s| s.clone()),
TestData {
name: "Hello".to_string(),
value: 42
@@ -166,6 +161,6 @@ mod tests {
// Wait for all blocking writes to flush
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
assert_eq!(store.read().value, 50);
assert_eq!(store.read_with(|s| s.value), 50);
}
}