MCPcopy Create free account
hub / github.com/ScriptedAlchemy/tracedecay / ingest

Function ingest

src/accounting/parser.rs:185–278  ·  view source on GitHub ↗

Ingest all Claude Code session files into the global DB. Uses offset tracking to only parse new lines since the last run.

(gdb: &GlobalDb)

Source from the content-addressed store, hash-verified

183/// Ingest all Claude Code session files into the global DB.
184/// Uses offset tracking to only parse new lines since the last run.
185pub async fn ingest(gdb: &GlobalDb) -> IngestStats {
186 let files = find_session_files();
187 let mut total_inserted = 0u64;
188 let mut total_cost = 0.0f64;
189 let mut total_tokens = 0u64;
190
191 for file_path in &files {
192 let path_str = file_path.to_string_lossy().to_string();
193
194 // Check file mtime
195 let Ok(meta) = fs::metadata(file_path) else {
196 continue;
197 };
198 let mtime = meta
199 .modified()
200 .ok()
201 .and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok())
202 .map_or(0, |d| d.as_secs());
203
204 // Check if we've already parsed this file up to this mtime
205 let prev = gdb.get_parse_offset(&path_str).await.unwrap_or_default();
206 let (prev_offset, prev_mtime) = (prev.byte_offset, prev.mtime);
207
208 if mtime == prev_mtime && prev_offset > 0 {
209 // File hasn't changed since last parse
210 continue;
211 }
212
213 let seek_to = if mtime == prev_mtime {
214 prev_offset
215 } else if prev_mtime > 0 && mtime > prev_mtime {
216 // File was appended to -- seek to previous offset
217 prev_offset
218 } else {
219 // File is new or was rewritten -- start from beginning
220 0
221 };
222
223 let (project_hash, session_id) = extract_path_parts(file_path);
224
225 let Ok(f) = fs::File::open(file_path) else {
226 continue;
227 };
228 let mut reader = BufReader::new(f);
229
230 // Seek to the saved offset
231 if seek_to > 0 && reader.seek(SeekFrom::Start(seek_to)).is_err() {
232 continue;
233 }
234
235 let mut line = String::new();
236 let mut current_offset = seek_to;
237
238 loop {
239 line.clear();
240 match reader.read_line(&mut line) {
241 Ok(0) | Err(_) => break,
242 Ok(n) => {

Callers 4

refresh_cost_cacheFunction · 0.85
handle_costFunction · 0.85
handle_status_commandFunction · 0.85
hook_stopFunction · 0.85

Calls 9

find_session_filesFunction · 0.85
extract_path_partsFunction · 0.85
parse_lineFunction · 0.85
get_parse_offsetMethod · 0.80
clearMethod · 0.80
insert_turnMethod · 0.80
set_parse_offsetMethod · 0.80
read_lineMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected