Skip to content

Commit eb9c9d1

Browse files
committed
Added some features
1 parent 8f49a55 commit eb9c9d1

4 files changed

Lines changed: 59 additions & 11 deletions

File tree

src/core/state_machine.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ impl StateMachine {
5555
let id = entry.id;
5656
let timestamp = entry.created_at;
5757

58+
// If this ID already exists, remove its previous temporal index entry first.
59+
if let Some(previous) = self.memories.get(&id) {
60+
let old_ts = previous.created_at;
61+
let mut remove_old_bucket = false;
62+
if let Some(ids) = self.temporal_index.get_mut(&old_ts) {
63+
ids.retain(|&mid| mid != id);
64+
remove_old_bucket = ids.is_empty();
65+
}
66+
if remove_old_bucket {
67+
self.temporal_index.remove(&old_ts);
68+
}
69+
}
70+
5871
self.memories.insert(id, entry);
5972

6073
// Add to temporal index
@@ -170,6 +183,13 @@ impl StateMachine {
170183
self.memories.len()
171184
}
172185

186+
/// Get all memories in deterministic ID order.
187+
pub fn all_memories(&self) -> Vec<&MemoryEntry> {
188+
let mut entries: Vec<&MemoryEntry> = self.memories.values().collect();
189+
entries.sort_by_key(|e| e.id);
190+
entries
191+
}
192+
173193
pub fn is_empty(&self) -> bool {
174194
self.memories.is_empty()
175195
}
@@ -262,6 +282,38 @@ mod tests {
262282
assert_eq!(range[1].id, MemoryId(3));
263283
}
264284

285+
#[test]
286+
fn test_insert_update_replaces_old_temporal_timestamp() {
287+
let mut sm = StateMachine::new();
288+
sm.insert_memory(create_test_entry(1, "default", 1000))
289+
.unwrap();
290+
sm.insert_memory(create_test_entry(1, "default", 3000))
291+
.unwrap();
292+
293+
assert_eq!(sm.len(), 1);
294+
assert!(sm.get_memories_in_time_range(1000, 1000).is_empty());
295+
let new_range = sm.get_memories_in_time_range(3000, 3000);
296+
assert_eq!(new_range.len(), 1);
297+
assert_eq!(new_range[0].id, MemoryId(1));
298+
}
299+
300+
#[test]
301+
fn test_all_memories_deterministic_order() {
302+
let mut sm = StateMachine::new();
303+
sm.insert_memory(create_test_entry(3, "default", 1000))
304+
.unwrap();
305+
sm.insert_memory(create_test_entry(1, "default", 1000))
306+
.unwrap();
307+
sm.insert_memory(create_test_entry(2, "default", 1000))
308+
.unwrap();
309+
310+
let all = sm.all_memories();
311+
assert_eq!(all.len(), 3);
312+
assert_eq!(all[0].id, MemoryId(1));
313+
assert_eq!(all[1].id, MemoryId(2));
314+
assert_eq!(all[2].id, MemoryId(3));
315+
}
316+
265317
#[test]
266318
fn test_namespace_filtering() {
267319
let mut sm = StateMachine::new();

src/engine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl Engine {
204204
let mut unique_ids = std::collections::HashSet::new();
205205
let mut candidates: Vec<(MemoryId, u64, f32)> = self
206206
.state_machine
207-
.get_memories_in_time_range(0, u64::MAX)
207+
.all_memories()
208208
.into_iter()
209209
.filter(|entry| unique_ids.insert(entry.id))
210210
.map(|entry| (entry.id, entry.created_at, entry.importance))
@@ -240,7 +240,7 @@ impl Engine {
240240
let entries = self.state_machine.len();
241241
let bytes = self
242242
.state_machine
243-
.get_memories_in_time_range(0, u64::MAX)
243+
.all_memories()
244244
.into_iter()
245245
.map(Self::estimate_memory_bytes)
246246
.sum();

src/index/temporal.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl TemporalIndex {
7777
pub fn get_earliest_timestamp(state_machine: &StateMachine) -> Option<u64> {
7878
// Find first memory in the system (brute force for now)
7979
let mut earliest = u64::MAX;
80-
for entry in state_machine.get_memories_in_time_range(0, u64::MAX) {
80+
for entry in state_machine.all_memories() {
8181
if entry.created_at < earliest {
8282
earliest = entry.created_at;
8383
}
@@ -94,7 +94,7 @@ impl TemporalIndex {
9494
pub fn get_latest_timestamp(state_machine: &StateMachine) -> Option<u64> {
9595
// Find last memory in the system
9696
let mut latest: Option<u64> = None;
97-
for entry in state_machine.get_memories_in_time_range(0, u64::MAX) {
97+
for entry in state_machine.all_memories() {
9898
latest = Some(match latest {
9999
Some(current) => current.max(entry.created_at),
100100
None => entry.created_at,
@@ -144,7 +144,7 @@ impl TemporalIndex {
144144
pub fn get_oldest(state_machine: &StateMachine, count: usize) -> Result<Vec<MemoryId>> {
145145
// Get all memories and sort by timestamp
146146
let mut all = Vec::new();
147-
for entry in state_machine.get_memories_in_time_range(0, u64::MAX) {
147+
for entry in state_machine.all_memories() {
148148
all.push((entry.id, entry.created_at));
149149
}
150150

@@ -165,7 +165,7 @@ impl TemporalIndex {
165165
pub fn get_newest(state_machine: &StateMachine, count: usize) -> Result<Vec<MemoryId>> {
166166
// Get all memories and sort by timestamp
167167
let mut all = Vec::new();
168-
for entry in state_machine.get_memories_in_time_range(0, u64::MAX) {
168+
for entry in state_machine.all_memories() {
169169
all.push((entry.id, entry.created_at));
170170
}
171171

src/store.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,7 @@ impl MnemosStore {
110110
pub fn rebuild_vector_index(&mut self) -> Result<usize> {
111111
self.indexes = IndexLayer::new(self.indexes.vector.dimension());
112112
let mut indexed = 0usize;
113-
for entry in self
114-
.engine
115-
.get_state_machine()
116-
.get_memories_in_time_range(0, u64::MAX)
117-
{
113+
for entry in self.engine.get_state_machine().all_memories() {
118114
if let Some(embedding) = entry.embedding.clone() {
119115
self.indexes.vector_index_mut().index(entry.id, embedding)?;
120116
indexed += 1;

0 commit comments

Comments
 (0)