Skip to main content

contextdb_graph/
store.rs

1use contextdb_core::{AdjEntry, EdgeType, NodeId, TxId};
2use parking_lot::RwLock;
3use std::collections::HashMap;
4
5pub struct GraphStore {
6    pub forward_adj: RwLock<HashMap<NodeId, Vec<AdjEntry>>>,
7    pub reverse_adj: RwLock<HashMap<NodeId, Vec<AdjEntry>>>,
8}
9
10impl Default for GraphStore {
11    fn default() -> Self {
12        Self::new()
13    }
14}
15
16impl GraphStore {
17    pub fn new() -> Self {
18        Self {
19            forward_adj: RwLock::new(HashMap::new()),
20            reverse_adj: RwLock::new(HashMap::new()),
21        }
22    }
23
24    pub fn apply_inserts(&self, inserts: Vec<AdjEntry>) {
25        let mut fwd = self.forward_adj.write();
26        let mut rev = self.reverse_adj.write();
27
28        for entry in inserts {
29            rev.entry(entry.target).or_default().push(entry.clone());
30            fwd.entry(entry.source).or_default().push(entry);
31        }
32    }
33
34    pub fn apply_deletes(&self, deletes: Vec<(NodeId, EdgeType, NodeId, TxId)>) {
35        let mut fwd = self.forward_adj.write();
36        let mut rev = self.reverse_adj.write();
37
38        for (source, edge_type, target, deleted_tx) in deletes {
39            if let Some(entries) = fwd.get_mut(&source) {
40                for e in entries.iter_mut() {
41                    if e.target == target && e.edge_type == edge_type && e.deleted_tx.is_none() {
42                        e.deleted_tx = Some(deleted_tx);
43                    }
44                }
45            }
46
47            if let Some(entries) = rev.get_mut(&target) {
48                for e in entries.iter_mut() {
49                    if e.source == source && e.edge_type == edge_type && e.deleted_tx.is_none() {
50                        e.deleted_tx = Some(deleted_tx);
51                    }
52                }
53            }
54        }
55    }
56
57    pub fn insert_loaded_edge(&self, entry: AdjEntry) {
58        let mut fwd = self.forward_adj.write();
59        let mut rev = self.reverse_adj.write();
60        rev.entry(entry.target).or_default().push(entry.clone());
61        fwd.entry(entry.source).or_default().push(entry);
62    }
63}