grafeo_core/graph/lpg/
edge.rs1use grafeo_common::types::{EdgeId, EpochId, NodeId, PropertyKey, Value};
4use std::collections::BTreeMap;
5use std::sync::Arc;
6
7#[derive(Debug, Clone)]
11pub struct Edge {
12 pub id: EdgeId,
14 pub src: NodeId,
16 pub dst: NodeId,
18 pub edge_type: Arc<str>,
20 pub properties: BTreeMap<PropertyKey, Value>,
22}
23
24impl Edge {
25 #[must_use]
27 pub fn new(id: EdgeId, src: NodeId, dst: NodeId, edge_type: impl Into<Arc<str>>) -> Self {
28 Self {
29 id,
30 src,
31 dst,
32 edge_type: edge_type.into(),
33 properties: BTreeMap::new(),
34 }
35 }
36
37 pub fn set_property(&mut self, key: impl Into<PropertyKey>, value: impl Into<Value>) {
39 self.properties.insert(key.into(), value.into());
40 }
41
42 #[must_use]
44 pub fn get_property(&self, key: &str) -> Option<&Value> {
45 self.properties.get(&PropertyKey::new(key))
46 }
47
48 pub fn remove_property(&mut self, key: &str) -> Option<Value> {
50 self.properties.remove(&PropertyKey::new(key))
51 }
52
53 #[must_use]
57 pub fn other_endpoint(&self, node: NodeId) -> Option<NodeId> {
58 if node == self.src {
59 Some(self.dst)
60 } else if node == self.dst {
61 Some(self.src)
62 } else {
63 None
64 }
65 }
66}
67
68#[repr(C)]
72#[derive(Debug, Clone, Copy)]
73pub struct EdgeRecord {
74 pub id: EdgeId,
76 pub src: NodeId,
78 pub dst: NodeId,
80 pub type_id: u32,
82 pub props_offset: u32,
84 pub props_count: u16,
86 pub flags: EdgeFlags,
88 pub epoch: EpochId,
90}
91
92impl EdgeRecord {
93 pub const FLAG_DELETED: u16 = 1 << 0;
95 pub const FLAG_HAS_VERSION: u16 = 1 << 1;
97
98 #[must_use]
100 pub const fn new(id: EdgeId, src: NodeId, dst: NodeId, type_id: u32, epoch: EpochId) -> Self {
101 Self {
102 id,
103 src,
104 dst,
105 type_id,
106 props_offset: 0,
107 props_count: 0,
108 flags: EdgeFlags(0),
109 epoch,
110 }
111 }
112
113 #[must_use]
115 pub const fn is_deleted(&self) -> bool {
116 self.flags.contains(Self::FLAG_DELETED)
117 }
118
119 pub fn set_deleted(&mut self, deleted: bool) {
121 if deleted {
122 self.flags.set(Self::FLAG_DELETED);
123 } else {
124 self.flags.clear(Self::FLAG_DELETED);
125 }
126 }
127}
128
129#[repr(transparent)]
131#[derive(Debug, Clone, Copy, Default)]
132pub struct EdgeFlags(pub u16);
133
134impl EdgeFlags {
135 #[must_use]
137 pub const fn contains(&self, flag: u16) -> bool {
138 (self.0 & flag) != 0
139 }
140
141 pub fn set(&mut self, flag: u16) {
143 self.0 |= flag;
144 }
145
146 pub fn clear(&mut self, flag: u16) {
148 self.0 &= !flag;
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155
156 #[test]
157 fn test_edge_creation() {
158 let edge = Edge::new(EdgeId::new(1), NodeId::new(10), NodeId::new(20), "KNOWS");
159
160 assert_eq!(edge.id, EdgeId::new(1));
161 assert_eq!(edge.src, NodeId::new(10));
162 assert_eq!(edge.dst, NodeId::new(20));
163 assert_eq!(edge.edge_type.as_ref(), "KNOWS");
164 }
165
166 #[test]
167 fn test_edge_properties() {
168 let mut edge = Edge::new(EdgeId::new(1), NodeId::new(10), NodeId::new(20), "KNOWS");
169
170 edge.set_property("since", 2020i64);
171 edge.set_property("weight", 1.5f64);
172
173 assert_eq!(
174 edge.get_property("since").and_then(|v| v.as_int64()),
175 Some(2020)
176 );
177 assert_eq!(
178 edge.get_property("weight").and_then(|v| v.as_float64()),
179 Some(1.5)
180 );
181 }
182
183 #[test]
184 fn test_edge_other_endpoint() {
185 let edge = Edge::new(EdgeId::new(1), NodeId::new(10), NodeId::new(20), "KNOWS");
186
187 assert_eq!(edge.other_endpoint(NodeId::new(10)), Some(NodeId::new(20)));
188 assert_eq!(edge.other_endpoint(NodeId::new(20)), Some(NodeId::new(10)));
189 assert_eq!(edge.other_endpoint(NodeId::new(30)), None);
190 }
191
192 #[test]
193 fn test_edge_record_flags() {
194 let mut record = EdgeRecord::new(
195 EdgeId::new(1),
196 NodeId::new(10),
197 NodeId::new(20),
198 0,
199 EpochId::INITIAL,
200 );
201
202 assert!(!record.is_deleted());
203 record.set_deleted(true);
204 assert!(record.is_deleted());
205 }
206
207 #[test]
208 fn test_edge_record_size() {
209 let size = std::mem::size_of::<EdgeRecord>();
211 assert!(size <= 64, "EdgeRecord is {} bytes", size);
213 }
214}