perf: replace inefficient memory cloning vectors with fast zero-allocation read iterators

This commit is contained in:
Riz Ashraf committed 2026-09-21 12:51:26 +01:00
1 parent 5da422d23a
commit 3c31aeec1f
6 files changed
+108 -69

No files matched your search

+29 -21
View File
@@ -65,16 +65,19 @@ impl McpTool for QueryDecisionsHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
let req: QueryDecisionsTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let mut adrs = state.adrs.read();
if let Some(q) = req.query {
let q = q.to_lowercase();
adrs.retain(|a| {
contains_ignore_ascii_case(&a.title, &q)
|| contains_ignore_ascii_case(&a.context, &q)
|| contains_ignore_ascii_case(&a.decision, &q)
});
}
let data = serde_json::to_string(&adrs).unwrap_or_default();
let data = state.adrs.read_with(|adrs| {
let filtered: Vec<_> = adrs.iter().filter(|a| {
if let Some(q) = &req.query {
let q = q.to_lowercase();
contains_ignore_ascii_case(&a.title, &q)
|| contains_ignore_ascii_case(&a.context, &q)
|| contains_ignore_ascii_case(&a.decision, &q)
} else {
true
}
}).collect();
serde_json::to_string(&filtered).unwrap_or_default()
});
Ok(data.to_string())
}
}
@@ -127,12 +130,13 @@ impl McpTool for SearchErrorFixesHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
let req: SearchErrorFixesTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let q = req.query.to_lowercase();
let mut fixes = state.error_fixes.read();
fixes.retain(|f| {
contains_ignore_ascii_case(&f.signature, &q)
|| contains_ignore_ascii_case(&f.solution, &q)
let data = state.error_fixes.read_with(|fixes| {
let filtered: Vec<_> = fixes.iter().filter(|f| {
contains_ignore_ascii_case(&f.signature, &q)
|| contains_ignore_ascii_case(&f.solution, &q)
}).collect();
serde_json::to_string(&filtered).unwrap_or_default()
});
let data = serde_json::to_string(&fixes).unwrap_or_default();
Ok(data.to_string())
}
}
@@ -183,7 +187,7 @@ impl McpTool for QueryRecentChangesHandler {
}
async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> Result<String, String> {
let data = serde_json::to_string(&state.ledger.read()).unwrap_or_else(|_| "[]".to_string());
let data = state.ledger.read_with(|l| serde_json::to_string(l).unwrap_or_else(|_| "[]".to_string()));
Ok(data.to_string())
}
}
@@ -232,8 +236,7 @@ impl McpTool for ReadPreferencesHandler {
}
async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> Result<String, String> {
let prefs = state.prefs.read();
let data = serde_json::to_string(&prefs).unwrap_or_default();
let data = state.prefs.read_with(|prefs| serde_json::to_string(prefs).unwrap_or_default());
Ok(data.to_string())
}
}
@@ -320,9 +323,12 @@ impl McpTool for ListTechDebtHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
let req: ListTechDebtTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let mut debts = state.tech_debts.read();
debts.retain(|d| d.namespace == req.namespace && (req.include_resolved || !d.is_resolved));
let data = serde_json::to_string(&debts).unwrap_or_default();
let data = state.tech_debts.read_with(|debts| {
let filtered: Vec<_> = debts.iter().filter(|d| {
d.namespace == req.namespace && (req.include_resolved || !d.is_resolved)
}).collect();
serde_json::to_string(&filtered).unwrap_or_default()
});
Ok(data.to_string())
}
}
@@ -490,3 +496,5 @@ impl McpTool for GetProjectHealthHandler {
}
use crate::handlers_v2::utils::*;