Skip to main content

raphtory_storage/
core_ops.rs

1use crate::graph::{
2    edges::{edge_entry::EdgeStorageEntry, edges::EdgesStorage},
3    graph::GraphStorage,
4    locked::LockedGraph,
5    nodes::{node_entry::NodeStorageEntry, node_storage_ops::NodeStorageOps, nodes::NodesStorage},
6};
7use raphtory_api::{
8    core::{
9        entities::{
10            properties::{meta::Meta, prop::Prop},
11            GidType, LayerIds, EID, GID, VID,
12        },
13        storage::arc_str::ArcStr,
14    },
15    inherit::Base,
16    iter::{BoxedIter, BoxedLIter},
17};
18use raphtory_core::entities::{nodes::node_ref::NodeRef, properties::graph_meta::GraphMeta};
19use std::{
20    iter,
21    sync::{atomic::Ordering, Arc},
22};
23
24/// Check if two Graph views point at the same underlying storage
25pub fn is_view_compatible(g1: &impl CoreGraphOps, g2: &impl CoreGraphOps) -> bool {
26    g1.core_graph().ptr_eq(g2.core_graph())
27}
28
29/// Core functions that should (almost-)always be implemented by pointing at the underlying graph.
30pub trait CoreGraphOps: Send + Sync {
31    fn id_type(&self) -> Option<GidType> {
32        match self.core_graph() {
33            GraphStorage::Mem(LockedGraph { graph, .. }) | GraphStorage::Unlocked(graph) => {
34                graph.logical_to_physical.dtype()
35            }
36            #[cfg(feature = "storage")]
37            GraphStorage::Disk(storage) => Some(storage.inner().id_type()),
38        }
39    }
40
41    fn num_shards(&self) -> usize {
42        match self.core_graph() {
43            GraphStorage::Mem(LockedGraph { graph, .. }) | GraphStorage::Unlocked(graph) => {
44                graph.storage.num_shards()
45            }
46            #[cfg(feature = "storage")]
47            GraphStorage::Disk(_) => 1,
48        }
49    }
50
51    /// get the current sequence id without incrementing the counter
52    fn read_event_id(&self) -> usize {
53        match self.core_graph() {
54            GraphStorage::Unlocked(graph) | GraphStorage::Mem(LockedGraph { graph, .. }) => {
55                graph.event_counter.load(Ordering::Relaxed)
56            }
57            #[cfg(feature = "storage")]
58            GraphStorage::Disk(storage) => storage.inner.count_temporal_edges(),
59        }
60    }
61
62    /// get the number of nodes in the main graph
63    #[inline]
64    fn unfiltered_num_nodes(&self) -> usize {
65        self.core_graph().unfiltered_num_nodes()
66    }
67
68    /// get the number of edges in the main graph
69    #[inline]
70    fn unfiltered_num_edges(&self) -> usize {
71        self.core_graph().unfiltered_num_edges()
72    }
73
74    /// get the number of layers in the main graph
75    #[inline]
76    fn unfiltered_num_layers(&self) -> usize {
77        self.core_graph().unfiltered_num_layers()
78    }
79
80    /// Return the id of the single layer if `layer_ids` reduces to a graph with a single layer, else None
81    fn single_layer(&self, layer_ids: &LayerIds) -> Option<usize> {
82        match layer_ids {
83            LayerIds::None => None,
84            LayerIds::All => {
85                if self.unfiltered_num_layers() == 1 {
86                    Some(0)
87                } else {
88                    None
89                }
90            }
91            LayerIds::One(id) => Some(*id),
92            LayerIds::Multiple(ids) => {
93                if ids.len() == 1 {
94                    Some(ids.0[0])
95                } else {
96                    None
97                }
98            }
99        }
100    }
101
102    fn core_graph(&self) -> &GraphStorage;
103
104    #[inline]
105    fn core_edges(&self) -> EdgesStorage {
106        self.core_graph().owned_edges()
107    }
108    #[inline]
109    fn core_edge(&self, eid: EID) -> EdgeStorageEntry<'_> {
110        self.core_graph().edge_entry(eid)
111    }
112
113    #[inline]
114    fn core_nodes(&self) -> NodesStorage {
115        self.core_graph().core_nodes()
116    }
117
118    #[inline]
119    fn core_node(&self, vid: VID) -> NodeStorageEntry<'_> {
120        self.core_graph().core_node(vid)
121    }
122
123    #[inline]
124    fn node_meta(&self) -> &Meta {
125        self.core_graph().node_meta()
126    }
127
128    #[inline]
129    fn edge_meta(&self) -> &Meta {
130        self.core_graph().edge_meta()
131    }
132
133    #[inline]
134    fn graph_meta(&self) -> &GraphMeta {
135        self.core_graph().graph_meta()
136    }
137
138    #[inline]
139    fn get_layer_name(&self, layer_id: usize) -> ArcStr {
140        self.edge_meta().layer_meta().get_name(layer_id).clone()
141    }
142
143    #[inline]
144    fn get_layer_id(&self, name: &str) -> Option<usize> {
145        self.edge_meta().get_layer_id(name)
146    }
147
148    #[inline]
149    fn get_default_layer_id(&self) -> Option<usize> {
150        self.edge_meta().get_default_layer_id()
151    }
152
153    /// Get the layer name for a given id
154    #[inline]
155    fn get_layer_names_from_ids(&self, layer_ids: &LayerIds) -> BoxedIter<ArcStr> {
156        let layer_ids = layer_ids.clone();
157        match layer_ids {
158            LayerIds::None => Box::new(iter::empty()),
159            LayerIds::All => Box::new(self.edge_meta().layer_meta().get_keys().into_iter()),
160            LayerIds::One(id) => {
161                let name = self.edge_meta().layer_meta().get_name(id).clone();
162                Box::new(iter::once(name))
163            }
164            LayerIds::Multiple(ids) => {
165                let keys = self.edge_meta().layer_meta().get_keys();
166                Box::new(ids.into_iter().map(move |id| keys[id].clone()))
167            }
168        }
169    }
170
171    /// Get all node types
172    #[inline]
173    fn get_all_node_types(&self) -> Vec<ArcStr> {
174        self.node_meta().get_all_node_types()
175    }
176
177    /// Returns the external ID for a node
178    #[inline]
179    fn node_id(&self, v: VID) -> GID {
180        self.core_graph().core_node(v).id().into()
181    }
182
183    /// Returns the string name for a node
184    #[inline]
185    fn node_name(&self, v: VID) -> String {
186        let node = self.core_node(v);
187        node.name()
188            .map(|name| name.to_string())
189            .unwrap_or_else(|| node.id().to_str().to_string())
190    }
191
192    /// Returns the type of node
193    #[inline]
194    fn node_type(&self, v: VID) -> Option<ArcStr> {
195        let type_id = self.node_type_id(v);
196        self.node_meta().get_node_type_name_by_id(type_id)
197    }
198
199    /// Returns the type id of a node
200    #[inline]
201    fn node_type_id(&self, v: VID) -> usize {
202        let node = self.core_node(v);
203        node.node_type_id()
204    }
205
206    /// Gets the internal reference for an external node reference and keeps internal references unchanged.
207    #[inline]
208    fn internalise_node(&self, v: NodeRef) -> Option<VID> {
209        self.core_graph().internalise_node(v)
210    }
211
212    /// Gets the internal reference for an external node reference and keeps internal references unchanged. Assumes node exists!
213    #[inline]
214    fn internalise_node_unchecked(&self, v: NodeRef) -> VID {
215        self.core_graph().internalise_node(v).unwrap()
216    }
217
218    /// Gets a static property of a given node given the name and node reference.
219    ///
220    /// # Arguments
221    ///
222    /// * `v` - A reference to the node for which the property is being queried.
223    /// * `name` - The name of the property.
224    ///
225    /// # Returns
226    /// The property value if it exists.
227    fn node_metadata(&self, v: VID, id: usize) -> Option<Prop> {
228        let core_node_entry = self.core_node(v);
229        core_node_entry.prop(id)
230    }
231
232    /// Gets the keys of metadata of a given node
233    ///
234    /// # Arguments
235    ///
236    /// * `v` - A reference to the node for which the property is being queried.
237    ///
238    /// # Returns
239    /// The keys of the metadata.
240    fn node_metadata_ids(&self, v: VID) -> BoxedLIter<'_, usize> {
241        let core_node_entry = self.core_node(v);
242        core_node_entry.metadata_ids()
243    }
244
245    /// Returns a vector of all ids of temporal properties within the given node
246    ///
247    /// # Arguments
248    ///
249    /// * `v` - A reference to the node for which to retrieve the names.
250    ///
251    /// # Returns
252    /// The ids of the temporal properties
253    fn temporal_node_prop_ids(&self, v: VID) -> Box<dyn Iterator<Item = usize> + '_> {
254        let core_node_entry = self.core_node(v);
255        core_node_entry.temporal_prop_ids()
256    }
257}
258
259impl CoreGraphOps for GraphStorage {
260    #[inline]
261    fn core_graph(&self) -> &GraphStorage {
262        self
263    }
264}
265
266pub trait InheritCoreGraphOps: Base {}
267
268impl<G: InheritCoreGraphOps + Send + Sync> CoreGraphOps for G
269where
270    G::Base: CoreGraphOps,
271{
272    #[inline]
273    fn core_graph(&self) -> &GraphStorage {
274        self.base().core_graph()
275    }
276}
277
278impl<T: ?Sized> InheritCoreGraphOps for Arc<T> {}
279impl<T: ?Sized> InheritCoreGraphOps for &T {}