agentic_memory/v3/indexes/
temporal.rs1use super::{Index, IndexResult};
4use crate::v3::block::{Block, BlockHash};
5use chrono::{DateTime, Utc};
6use std::collections::BTreeMap;
7
8pub struct TemporalIndex {
10 by_time: BTreeMap<i64, Vec<(u64, BlockHash)>>,
12
13 by_sequence: Vec<i64>,
15}
16
17impl TemporalIndex {
18 pub fn new() -> Self {
19 Self {
20 by_time: BTreeMap::new(),
21 by_sequence: Vec::new(),
22 }
23 }
24
25 pub fn query_range(&self, start: DateTime<Utc>, end: DateTime<Utc>) -> Vec<IndexResult> {
27 let start_ts = start.timestamp_millis();
28 let end_ts = end.timestamp_millis();
29
30 self.by_time
31 .range(start_ts..=end_ts)
32 .flat_map(|(_, blocks)| blocks.iter())
33 .map(|(seq, hash)| IndexResult {
34 block_sequence: *seq,
35 block_hash: *hash,
36 score: 1.0,
37 })
38 .collect()
39 }
40
41 pub fn query_recent(&self, seconds: i64) -> Vec<IndexResult> {
43 let now = Utc::now().timestamp_millis();
44 let start = now - (seconds * 1000);
45
46 self.by_time
47 .range(start..=now)
48 .flat_map(|(_, blocks)| blocks.iter())
49 .map(|(seq, hash)| IndexResult {
50 block_sequence: *seq,
51 block_hash: *hash,
52 score: 1.0,
53 })
54 .collect()
55 }
56
57 pub fn len(&self) -> usize {
59 self.by_sequence.len()
60 }
61
62 pub fn is_empty(&self) -> bool {
64 self.by_sequence.is_empty()
65 }
66}
67
68impl Default for TemporalIndex {
69 fn default() -> Self {
70 Self::new()
71 }
72}
73
74impl Index for TemporalIndex {
75 fn index(&mut self, block: &Block) {
76 let ts = block.timestamp.timestamp_millis();
77
78 self.by_time
79 .entry(ts)
80 .or_default()
81 .push((block.sequence, block.hash));
82
83 while self.by_sequence.len() <= block.sequence as usize {
85 self.by_sequence.push(0);
86 }
87 self.by_sequence[block.sequence as usize] = ts;
88 }
89
90 fn remove(&mut self, sequence: u64) {
91 if let Some(&ts) = self.by_sequence.get(sequence as usize) {
92 if let Some(blocks) = self.by_time.get_mut(&ts) {
93 blocks.retain(|(seq, _)| *seq != sequence);
94 }
95 }
96 }
97
98 fn rebuild(&mut self, blocks: impl Iterator<Item = Block>) {
99 self.by_time.clear();
100 self.by_sequence.clear();
101 for block in blocks {
102 self.index(&block);
103 }
104 }
105}