Skip to main content

raphtory_storage/graph/nodes/
node_ref.rs

1use super::row::Row;
2use crate::graph::{
3    nodes::{node_additions::NodeAdditions, node_storage_ops::NodeStorageOps},
4    variants::storage_variants2::StorageVariants2,
5};
6use raphtory_api::{
7    core::{
8        entities::{
9            edges::edge_ref::EdgeRef,
10            properties::{prop::Prop, tprop::TPropOps},
11            GidRef, LayerIds, VID,
12        },
13        storage::timeindex::EventTime,
14        Direction,
15    },
16    iter::IntoDynBoxed,
17};
18use raphtory_core::storage::node_entry::NodePtr;
19use std::{borrow::Cow, ops::Range};
20
21#[cfg(feature = "storage")]
22use crate::disk::storage_interface::node::DiskNode;
23
24#[derive(Copy, Clone, Debug)]
25pub enum NodeStorageRef<'a> {
26    Mem(NodePtr<'a>),
27    #[cfg(feature = "storage")]
28    Disk(DiskNode<'a>),
29}
30
31impl<'a> NodeStorageRef<'a> {
32    pub fn temp_prop_rows(self) -> impl Iterator<Item = (EventTime, Row<'a>)> + 'a {
33        match self {
34            NodeStorageRef::Mem(node_entry) => node_entry
35                .into_rows()
36                .map(|(t, row)| (t, Row::Mem(row)))
37                .into_dyn_boxed(),
38            #[cfg(feature = "storage")]
39            NodeStorageRef::Disk(disk_node) => disk_node.into_rows().into_dyn_boxed(),
40        }
41    }
42
43    pub fn temp_prop_rows_window(
44        self,
45        window: Range<EventTime>,
46    ) -> impl Iterator<Item = (EventTime, Row<'a>)> + 'a {
47        match self {
48            NodeStorageRef::Mem(node_entry) => node_entry
49                .into_rows_window(window)
50                .map(|(t, row)| (t, Row::Mem(row)))
51                .into_dyn_boxed(),
52            #[cfg(feature = "storage")]
53            NodeStorageRef::Disk(disk_node) => disk_node.into_rows_window(window).into_dyn_boxed(),
54        }
55    }
56
57    pub fn last_before_row(self, t: EventTime) -> Vec<(usize, Prop)> {
58        match self {
59            NodeStorageRef::Mem(node_entry) => node_entry.last_before_row(t),
60            #[cfg(feature = "storage")]
61            NodeStorageRef::Disk(disk_node) => disk_node.last_before_row(t),
62        }
63    }
64}
65
66impl<'a> From<NodePtr<'a>> for NodeStorageRef<'a> {
67    fn from(value: NodePtr<'a>) -> Self {
68        NodeStorageRef::Mem(value)
69    }
70}
71
72#[cfg(feature = "storage")]
73impl<'a> From<DiskNode<'a>> for NodeStorageRef<'a> {
74    fn from(value: DiskNode<'a>) -> Self {
75        NodeStorageRef::Disk(value)
76    }
77}
78
79macro_rules! for_all {
80    ($value:expr, $pattern:pat => $result:expr) => {
81        match $value {
82            NodeStorageRef::Mem($pattern) => $result,
83            #[cfg(feature = "storage")]
84            NodeStorageRef::Disk($pattern) => $result,
85        }
86    };
87}
88
89#[cfg(feature = "storage")]
90macro_rules! for_all_iter {
91    ($value:expr, $pattern:pat => $result:expr) => {{
92        match $value {
93            NodeStorageRef::Mem($pattern) => StorageVariants2::Mem($result),
94            NodeStorageRef::Disk($pattern) => StorageVariants2::Disk($result),
95        }
96    }};
97}
98
99#[cfg(not(feature = "storage"))]
100macro_rules! for_all_iter {
101    ($value:expr, $pattern:pat => $result:expr) => {{
102        match $value {
103            NodeStorageRef::Mem($pattern) => $result,
104        }
105    }};
106}
107
108impl<'a> NodeStorageOps<'a> for NodeStorageRef<'a> {
109    fn degree(self, layers: &LayerIds, dir: Direction) -> usize {
110        for_all!(self, node => node.degree(layers, dir))
111    }
112
113    fn additions(self) -> NodeAdditions<'a> {
114        for_all!(self, node => node.additions())
115    }
116
117    fn tprop(self, prop_id: usize) -> impl TPropOps<'a> {
118        for_all_iter!(self, node => node.tprop(prop_id))
119    }
120
121    fn edges_iter(self, layers: &LayerIds, dir: Direction) -> impl Iterator<Item = EdgeRef> + 'a {
122        for_all_iter!(self, node => node.edges_iter(layers, dir))
123    }
124
125    fn node_type_id(self) -> usize {
126        for_all!(self, node => node.node_type_id())
127    }
128
129    fn vid(self) -> VID {
130        for_all!(self, node => node.vid())
131    }
132
133    fn id(self) -> GidRef<'a> {
134        for_all!(self, node => node.id())
135    }
136
137    fn name(self) -> Option<Cow<'a, str>> {
138        for_all!(self, node => node.name())
139    }
140
141    fn find_edge(self, dst: VID, layer_ids: &LayerIds) -> Option<EdgeRef> {
142        for_all!(self, node => NodeStorageOps::find_edge(node, dst, layer_ids))
143    }
144
145    fn prop(self, prop_id: usize) -> Option<Prop> {
146        for_all!(self, node => node.prop(prop_id))
147    }
148
149    fn tprops(self) -> impl Iterator<Item = (usize, impl TPropOps<'a>)> {
150        match self {
151            NodeStorageRef::Mem(node) => {
152                StorageVariants2::Mem(node.tprops().map(|(k, v)| (k, StorageVariants2::Mem(v))))
153            }
154            #[cfg(feature = "storage")]
155            NodeStorageRef::Disk(node) => {
156                StorageVariants2::Disk(node.tprops().map(|(k, v)| (k, StorageVariants2::Disk(v))))
157            }
158        }
159    }
160}