raphtory_storage/mutation/
property_addition_ops.rs

1use crate::{
2    graph::{graph::GraphStorage, nodes::node_storage_ops::NodeStorageOps},
3    mutation::MutationError,
4};
5use parking_lot::RwLockWriteGuard;
6use raphtory_api::{
7    core::{
8        entities::{
9            properties::prop::{validate_prop, Prop},
10            EID, VID,
11        },
12        storage::timeindex::TimeIndexEntry,
13    },
14    inherit::Base,
15};
16use raphtory_core::{
17    entities::graph::tgraph::TemporalGraph,
18    storage::{raw_edges::EdgeWGuard, EntryMut, NodeSlot},
19};
20
21pub trait InternalPropertyAdditionOps {
22    type Error: From<MutationError>;
23    fn internal_add_properties(
24        &self,
25        t: TimeIndexEntry,
26        props: &[(usize, Prop)],
27    ) -> Result<(), Self::Error>;
28    fn internal_add_metadata(&self, props: &[(usize, Prop)]) -> Result<(), Self::Error>;
29    fn internal_update_metadata(&self, props: &[(usize, Prop)]) -> Result<(), Self::Error>;
30    fn internal_add_node_metadata(
31        &self,
32        vid: VID,
33        props: &[(usize, Prop)],
34    ) -> Result<EntryMut<'_, RwLockWriteGuard<'_, NodeSlot>>, Self::Error>;
35    fn internal_update_node_metadata(
36        &self,
37        vid: VID,
38        props: &[(usize, Prop)],
39    ) -> Result<EntryMut<'_, RwLockWriteGuard<'_, NodeSlot>>, Self::Error>;
40    fn internal_add_edge_metadata(
41        &self,
42        eid: EID,
43        layer: usize,
44        props: &[(usize, Prop)],
45    ) -> Result<EdgeWGuard<'_>, Self::Error>;
46    fn internal_update_edge_metadata(
47        &self,
48        eid: EID,
49        layer: usize,
50        props: &[(usize, Prop)],
51    ) -> Result<EdgeWGuard<'_>, Self::Error>;
52}
53
54impl InternalPropertyAdditionOps for TemporalGraph {
55    type Error = MutationError;
56    fn internal_add_properties(
57        &self,
58        t: TimeIndexEntry,
59        props: &[(usize, Prop)],
60    ) -> Result<(), Self::Error> {
61        if !props.is_empty() {
62            for (prop_id, prop) in props {
63                let prop = self.process_prop_value(prop);
64                let prop = validate_prop(prop).map_err(MutationError::from)?;
65                self.graph_meta
66                    .add_prop(t, *prop_id, prop)
67                    .map_err(MutationError::from)?;
68            }
69            self.update_time(t);
70        }
71        Ok(())
72    }
73
74    fn internal_add_metadata(&self, props: &[(usize, Prop)]) -> Result<(), Self::Error> {
75        for (id, prop) in props {
76            let prop = self.process_prop_value(prop);
77            let prop = validate_prop(prop).map_err(MutationError::from)?;
78            self.graph_meta
79                .add_metadata(*id, prop)
80                .map_err(MutationError::from)?;
81        }
82        Ok(())
83    }
84
85    fn internal_update_metadata(&self, props: &[(usize, Prop)]) -> Result<(), Self::Error> {
86        for (id, prop) in props {
87            let prop = self.process_prop_value(prop);
88            let prop = validate_prop(prop).map_err(MutationError::from)?;
89            self.graph_meta.update_metadata(*id, prop);
90        }
91        Ok(())
92    }
93
94    fn internal_add_node_metadata(
95        &self,
96        vid: VID,
97        props: &[(usize, Prop)],
98    ) -> Result<EntryMut<'_, RwLockWriteGuard<'_, NodeSlot>>, Self::Error> {
99        let mut node = self.storage.get_node_mut(vid);
100        for (prop_id, prop) in props {
101            let prop = self.process_prop_value(prop);
102            let prop = validate_prop(prop).map_err(MutationError::from)?;
103            node.as_mut()
104                .add_metadata(*prop_id, prop)
105                .map_err(MutationError::from)?;
106        }
107        Ok(node)
108    }
109
110    fn internal_update_node_metadata(
111        &self,
112        vid: VID,
113        props: &[(usize, Prop)],
114    ) -> Result<EntryMut<'_, RwLockWriteGuard<'_, NodeSlot>>, Self::Error> {
115        let mut node = self.storage.get_node_mut(vid);
116        for (prop_id, prop) in props {
117            let prop = self.process_prop_value(prop);
118            let prop = validate_prop(prop).map_err(MutationError::from)?;
119            node.as_mut()
120                .update_metadata(*prop_id, prop)
121                .map_err(MutationError::from)?;
122        }
123        Ok(node)
124    }
125
126    fn internal_add_edge_metadata(
127        &self,
128        eid: EID,
129        layer: usize,
130        props: &[(usize, Prop)],
131    ) -> Result<EdgeWGuard<'_>, Self::Error> {
132        let mut edge = self.storage.get_edge_mut(eid);
133        let mut edge_mut = edge.as_mut();
134        if let Some(edge_layer) = edge_mut.get_layer_mut(layer) {
135            for (prop_id, prop) in props {
136                let prop = self.process_prop_value(prop);
137                let prop = validate_prop(prop).map_err(MutationError::from)?;
138                edge_layer
139                    .add_metadata(*prop_id, prop)
140                    .map_err(MutationError::from)?;
141            }
142            Ok(edge)
143        } else {
144            let layer = self.get_layer_name(layer).to_string();
145            let src = self.node(edge.as_ref().src()).as_ref().id().to_string();
146            let dst = self.node(edge.as_ref().dst()).as_ref().id().to_string();
147            Err(MutationError::InvalidEdgeLayer { layer, src, dst })
148        }
149    }
150
151    fn internal_update_edge_metadata(
152        &self,
153        eid: EID,
154        layer: usize,
155        props: &[(usize, Prop)],
156    ) -> Result<EdgeWGuard<'_>, Self::Error> {
157        let mut edge = self.storage.get_edge_mut(eid);
158        let mut edge_mut = edge.as_mut();
159        if let Some(edge_layer) = edge_mut.get_layer_mut(layer) {
160            for (prop_id, prop) in props {
161                let prop = self.process_prop_value(prop);
162                let prop = validate_prop(prop).map_err(MutationError::from)?;
163                edge_layer
164                    .update_metadata(*prop_id, prop)
165                    .map_err(MutationError::from)?;
166            }
167            Ok(edge)
168        } else {
169            let layer = self.get_layer_name(layer).to_string();
170            let src = self.node(edge.as_ref().src()).as_ref().id().to_string();
171            let dst = self.node(edge.as_ref().dst()).as_ref().id().to_string();
172            Err(MutationError::InvalidEdgeLayer { layer, src, dst })
173        }
174    }
175}
176
177impl InternalPropertyAdditionOps for GraphStorage {
178    type Error = MutationError;
179
180    fn internal_add_properties(
181        &self,
182        t: TimeIndexEntry,
183        props: &[(usize, Prop)],
184    ) -> Result<(), Self::Error> {
185        self.mutable()?.internal_add_properties(t, props)
186    }
187
188    fn internal_add_metadata(&self, props: &[(usize, Prop)]) -> Result<(), Self::Error> {
189        self.mutable()?.internal_add_metadata(props)
190    }
191
192    fn internal_update_metadata(&self, props: &[(usize, Prop)]) -> Result<(), Self::Error> {
193        self.mutable()?.internal_update_metadata(props)
194    }
195
196    fn internal_add_node_metadata(
197        &self,
198        vid: VID,
199        props: &[(usize, Prop)],
200    ) -> Result<EntryMut<'_, RwLockWriteGuard<'_, NodeSlot>>, Self::Error> {
201        self.mutable()?.internal_add_node_metadata(vid, props)
202    }
203
204    fn internal_update_node_metadata(
205        &self,
206        vid: VID,
207        props: &[(usize, Prop)],
208    ) -> Result<EntryMut<'_, RwLockWriteGuard<'_, NodeSlot>>, Self::Error> {
209        self.mutable()?.internal_update_node_metadata(vid, props)
210    }
211
212    fn internal_add_edge_metadata(
213        &self,
214        eid: EID,
215        layer: usize,
216        props: &[(usize, Prop)],
217    ) -> Result<EdgeWGuard<'_>, Self::Error> {
218        self.mutable()?
219            .internal_add_edge_metadata(eid, layer, props)
220    }
221
222    fn internal_update_edge_metadata(
223        &self,
224        eid: EID,
225        layer: usize,
226        props: &[(usize, Prop)],
227    ) -> Result<EdgeWGuard<'_>, Self::Error> {
228        self.mutable()?
229            .internal_update_edge_metadata(eid, layer, props)
230    }
231}
232
233pub trait InheritPropertyAdditionOps: Base {}
234
235impl<G: InheritPropertyAdditionOps> InternalPropertyAdditionOps for G
236where
237    G::Base: InternalPropertyAdditionOps,
238{
239    type Error = <G::Base as InternalPropertyAdditionOps>::Error;
240
241    #[inline]
242    fn internal_add_properties(
243        &self,
244        t: TimeIndexEntry,
245        props: &[(usize, Prop)],
246    ) -> Result<(), Self::Error> {
247        self.base().internal_add_properties(t, props)
248    }
249
250    #[inline]
251    fn internal_add_metadata(&self, props: &[(usize, Prop)]) -> Result<(), Self::Error> {
252        self.base().internal_add_metadata(props)
253    }
254
255    #[inline]
256    fn internal_update_metadata(&self, props: &[(usize, Prop)]) -> Result<(), Self::Error> {
257        self.base().internal_update_metadata(props)
258    }
259
260    #[inline]
261    fn internal_add_node_metadata(
262        &self,
263        vid: VID,
264        props: &[(usize, Prop)],
265    ) -> Result<EntryMut<'_, RwLockWriteGuard<'_, NodeSlot>>, Self::Error> {
266        self.base().internal_add_node_metadata(vid, props)
267    }
268
269    #[inline]
270    fn internal_update_node_metadata(
271        &self,
272        vid: VID,
273        props: &[(usize, Prop)],
274    ) -> Result<EntryMut<'_, RwLockWriteGuard<'_, NodeSlot>>, Self::Error> {
275        self.base().internal_update_node_metadata(vid, props)
276    }
277
278    #[inline]
279    fn internal_add_edge_metadata(
280        &self,
281        eid: EID,
282        layer: usize,
283        props: &[(usize, Prop)],
284    ) -> Result<EdgeWGuard<'_>, Self::Error> {
285        self.base().internal_add_edge_metadata(eid, layer, props)
286    }
287
288    #[inline]
289    fn internal_update_edge_metadata(
290        &self,
291        eid: EID,
292        layer: usize,
293        props: &[(usize, Prop)],
294    ) -> Result<EdgeWGuard<'_>, Self::Error> {
295        self.base().internal_update_edge_metadata(eid, layer, props)
296    }
297}