raphtory_storage/graph/graph.rs
1use super::{
2 edges::{edge_entry::EdgeStorageEntry, unlocked::UnlockedEdges},
3 nodes::node_entry::NodeStorageEntry,
4};
5use crate::graph::{
6 edges::edges::{EdgesStorage, EdgesStorageRef},
7 locked::LockedGraph,
8 nodes::{nodes::NodesStorage, nodes_ref::NodesStorageEntry},
9};
10use raphtory_api::core::entities::{properties::meta::Meta, LayerIds, LayerVariants, EID, VID};
11use raphtory_core::entities::{
12 graph::tgraph::TemporalGraph, nodes::node_ref::NodeRef, properties::graph_meta::GraphMeta,
13};
14use serde::{Deserialize, Serialize};
15use std::{fmt::Debug, iter, sync::Arc};
16use thiserror::Error;
17
18#[cfg(feature = "storage")]
19use crate::disk::{
20 storage_interface::{
21 edges::DiskEdges, edges_ref::DiskEdgesRef, node::DiskNode, nodes::DiskNodesOwned,
22 nodes_ref::DiskNodesRef,
23 },
24 DiskGraphStorage,
25};
26use crate::mutation::MutationError;
27
28#[derive(Clone, Debug, Serialize, Deserialize)]
29pub enum GraphStorage {
30 Mem(LockedGraph),
31 Unlocked(Arc<TemporalGraph>),
32 #[cfg(feature = "storage")]
33 Disk(Arc<DiskGraphStorage>),
34}
35
36#[derive(Error, Debug)]
37pub enum Immutable {
38 #[error("The graph is locked and cannot be mutated")]
39 ReadLockedImmutable,
40 #[cfg(feature = "storage")]
41 #[error("DiskGraph cannot be mutated")]
42 DiskGraphImmutable,
43}
44
45impl From<TemporalGraph> for GraphStorage {
46 fn from(value: TemporalGraph) -> Self {
47 Self::Unlocked(Arc::new(value))
48 }
49}
50
51#[cfg(feature = "storage")]
52impl From<DiskGraphStorage> for GraphStorage {
53 fn from(value: DiskGraphStorage) -> Self {
54 Self::Disk(Arc::new(value))
55 }
56}
57
58impl Default for GraphStorage {
59 fn default() -> Self {
60 GraphStorage::Unlocked(Arc::new(TemporalGraph::default()))
61 }
62}
63
64impl std::fmt::Display for GraphStorage {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 write!(
67 f,
68 "Graph(num_nodes={}, num_edges={})",
69 self.unfiltered_num_nodes(),
70 self.unfiltered_num_edges(),
71 )
72 }
73}
74
75impl GraphStorage {
76 /// Check if two storage instances point at the same underlying storage
77 pub fn ptr_eq(&self, other: &Self) -> bool {
78 match self {
79 GraphStorage::Mem(LockedGraph {
80 graph: this_graph, ..
81 })
82 | GraphStorage::Unlocked(this_graph) => match other {
83 GraphStorage::Mem(LockedGraph {
84 graph: other_graph, ..
85 })
86 | GraphStorage::Unlocked(other_graph) => Arc::ptr_eq(this_graph, other_graph),
87 #[cfg(feature = "storage")]
88 _ => false,
89 },
90 #[cfg(feature = "storage")]
91 GraphStorage::Disk(this_graph) => match other {
92 GraphStorage::Disk(other_graph) => Arc::ptr_eq(this_graph, other_graph),
93 _ => false,
94 },
95 }
96 }
97
98 pub fn mutable(&self) -> Result<&Arc<TemporalGraph>, MutationError> {
99 match self {
100 GraphStorage::Mem(_) => Err(Immutable::ReadLockedImmutable)?,
101 GraphStorage::Unlocked(graph) => Ok(graph),
102 #[cfg(feature = "storage")]
103 GraphStorage::Disk(_) => Err(Immutable::DiskGraphImmutable)?,
104 }
105 }
106
107 #[inline(always)]
108 pub fn is_immutable(&self) -> bool {
109 match self {
110 GraphStorage::Mem(_) => true,
111 GraphStorage::Unlocked(_) => false,
112 #[cfg(feature = "storage")]
113 GraphStorage::Disk(_) => true,
114 }
115 }
116
117 #[inline(always)]
118 pub fn lock(&self) -> Self {
119 match self {
120 GraphStorage::Unlocked(storage) => {
121 let locked = LockedGraph::new(storage.clone());
122 GraphStorage::Mem(locked)
123 }
124 _ => self.clone(),
125 }
126 }
127
128 #[inline(always)]
129 pub fn nodes(&self) -> NodesStorageEntry<'_> {
130 match self {
131 GraphStorage::Mem(storage) => NodesStorageEntry::Mem(&storage.nodes),
132 GraphStorage::Unlocked(storage) => {
133 NodesStorageEntry::Unlocked(storage.storage.nodes.read_lock())
134 }
135 #[cfg(feature = "storage")]
136 GraphStorage::Disk(storage) => {
137 NodesStorageEntry::Disk(DiskNodesRef::new(&storage.inner))
138 }
139 }
140 }
141
142 #[inline(always)]
143 pub fn internalise_node(&self, v: NodeRef) -> Option<VID> {
144 match v {
145 NodeRef::Internal(vid) => Some(vid),
146 node_ref => match self {
147 GraphStorage::Mem(locked) => locked.graph.resolve_node_ref(node_ref),
148 GraphStorage::Unlocked(unlocked) => unlocked.resolve_node_ref(node_ref),
149 #[cfg(feature = "storage")]
150 GraphStorage::Disk(storage) => match v {
151 NodeRef::External(id) => storage.inner.find_node(id),
152 _ => unreachable!("VID is handled above!"),
153 },
154 },
155 }
156 }
157
158 #[inline(always)]
159 pub fn unfiltered_num_nodes(&self) -> usize {
160 match self {
161 GraphStorage::Mem(storage) => storage.nodes.len(),
162 GraphStorage::Unlocked(storage) => storage.internal_num_nodes(),
163 #[cfg(feature = "storage")]
164 GraphStorage::Disk(storage) => storage.inner.num_nodes(),
165 }
166 }
167
168 #[inline(always)]
169 pub fn unfiltered_num_edges(&self) -> usize {
170 match self {
171 GraphStorage::Mem(storage) => storage.edges.len(),
172 GraphStorage::Unlocked(storage) => storage.storage.edges_len(),
173 #[cfg(feature = "storage")]
174 GraphStorage::Disk(storage) => storage.inner.count_edges(),
175 }
176 }
177
178 #[inline(always)]
179 pub fn unfiltered_num_layers(&self) -> usize {
180 match self {
181 GraphStorage::Mem(storage) => storage.graph.num_layers(),
182 GraphStorage::Unlocked(storage) => storage.num_layers(),
183 #[cfg(feature = "storage")]
184 GraphStorage::Disk(storage) => storage.inner.layers().len(),
185 }
186 }
187
188 #[inline(always)]
189 pub fn core_nodes(&self) -> NodesStorage {
190 match self {
191 GraphStorage::Mem(storage) => NodesStorage::Mem(storage.nodes.clone()),
192 GraphStorage::Unlocked(storage) => {
193 NodesStorage::Mem(LockedGraph::new(storage.clone()).nodes.clone())
194 }
195 #[cfg(feature = "storage")]
196 GraphStorage::Disk(storage) => {
197 NodesStorage::Disk(DiskNodesOwned::new(storage.inner.clone()))
198 }
199 }
200 }
201
202 #[inline(always)]
203 pub fn core_node<'a>(&'a self, vid: VID) -> NodeStorageEntry<'a> {
204 match self {
205 GraphStorage::Mem(storage) => NodeStorageEntry::Mem(storage.nodes.get_entry(vid)),
206 GraphStorage::Unlocked(storage) => {
207 NodeStorageEntry::Unlocked(storage.storage.get_node(vid))
208 }
209 #[cfg(feature = "storage")]
210 GraphStorage::Disk(storage) => {
211 NodeStorageEntry::Disk(DiskNode::new(&storage.inner, vid))
212 }
213 }
214 }
215
216 /// Try to get a node that may not be initialised yet
217 pub fn try_core_node<'a>(&'a self, vid: VID) -> Option<NodeStorageEntry<'a>> {
218 match self {
219 GraphStorage::Mem(storage) => {
220 storage.nodes.try_get_entry(vid).map(NodeStorageEntry::Mem)
221 }
222 GraphStorage::Unlocked(storage) => storage
223 .storage
224 .nodes
225 .try_entry(vid)
226 .map(NodeStorageEntry::Unlocked),
227 #[cfg(feature = "storage")]
228 GraphStorage::Disk(storage) => {
229 if vid.index() < storage.inner().num_nodes() {
230 Some(NodeStorageEntry::Disk(DiskNode::new(storage.inner(), vid)))
231 } else {
232 None
233 }
234 }
235 }
236 }
237
238 #[inline(always)]
239 pub fn edges(&self) -> EdgesStorageRef<'_> {
240 match self {
241 GraphStorage::Mem(storage) => EdgesStorageRef::Mem(&storage.edges),
242 GraphStorage::Unlocked(storage) => {
243 EdgesStorageRef::Unlocked(UnlockedEdges(&storage.storage))
244 }
245 #[cfg(feature = "storage")]
246 GraphStorage::Disk(storage) => EdgesStorageRef::Disk(DiskEdgesRef::new(&storage.inner)),
247 }
248 }
249
250 #[inline(always)]
251 pub fn owned_edges(&self) -> EdgesStorage {
252 match self {
253 GraphStorage::Mem(storage) => EdgesStorage::Mem(storage.edges.clone()),
254 GraphStorage::Unlocked(storage) => {
255 GraphStorage::Mem(LockedGraph::new(storage.clone())).owned_edges()
256 }
257 #[cfg(feature = "storage")]
258 GraphStorage::Disk(storage) => EdgesStorage::Disk(DiskEdges::new(storage)),
259 }
260 }
261
262 #[inline(always)]
263 pub fn edge_entry(&self, eid: EID) -> EdgeStorageEntry<'_> {
264 match self {
265 GraphStorage::Mem(storage) => EdgeStorageEntry::Mem(storage.edges.get_mem(eid)),
266 GraphStorage::Unlocked(storage) => {
267 EdgeStorageEntry::Unlocked(storage.storage.edge_entry(eid))
268 }
269 #[cfg(feature = "storage")]
270 GraphStorage::Disk(storage) => EdgeStorageEntry::Disk(storage.inner.edge(eid)),
271 }
272 }
273
274 pub fn layer_ids_iter(&self, layer_ids: &LayerIds) -> impl Iterator<Item = usize> {
275 match layer_ids {
276 LayerIds::None => LayerVariants::None(iter::empty()),
277 LayerIds::All => LayerVariants::All(0..self.unfiltered_num_layers()),
278 LayerIds::One(id) => LayerVariants::One(iter::once(*id)),
279 LayerIds::Multiple(ids) => LayerVariants::Multiple(ids.into_iter()),
280 }
281 }
282 //
283 // pub fn into_nodes_iter<'graph, G: GraphViewOps<'graph>>(
284 // self,
285 // view: G,
286 // node_list: NodeList,
287 // type_filter: Option<Arc<[bool]>>,
288 // ) -> BoxedLIter<'graph, VID> {
289 // node_list
290 // .into_iter()
291 // .filter(move |&vid| {
292 // let node = self.node_entry(vid);
293 // type_filter
294 // .as_ref()
295 // .map_or(true, |type_filter| type_filter[node.node_type_id()])
296 // && view.filter_node(node.as_ref())
297 // })
298 // .into_dyn_boxed()
299 // }
300 //
301 // pub fn nodes_par<'a, 'graph: 'a, G: GraphViewOps<'graph>>(
302 // &'a self,
303 // view: &'a G,
304 // type_filter: Option<&'a Arc<[bool]>>,
305 // ) -> impl ParallelIterator<Item = VID> + 'a {
306 // let nodes = self.nodes();
307 // view.node_list().into_par_iter().filter(move |&vid| {
308 // let node = nodes.node(vid);
309 // type_filter.map_or(true, |type_filter| type_filter[node.node_type_id()])
310 // && view.filter_node(node)
311 // })
312 // }
313 //
314 // pub fn into_nodes_par<'graph, G: GraphViewOps<'graph>>(
315 // self,
316 // view: G,
317 // node_list: NodeList,
318 // type_filter: Option<Arc<[bool]>>,
319 // ) -> impl ParallelIterator<Item = VID> + 'graph {
320 // node_list.into_par_iter().filter(move |&vid| {
321 // let node = self.node_entry(vid);
322 // type_filter
323 // .as_ref()
324 // .map_or(true, |type_filter| type_filter[node.node_type_id()])
325 // && view.filter_node(node.as_ref())
326 // })
327 // }
328 //
329 // pub fn edges_iter<'graph, G: GraphViewOps<'graph>>(
330 // &'graph self,
331 // view: &'graph G,
332 // ) -> impl Iterator<Item = EdgeRef> + Send + 'graph {
333 // let iter = self.edges().iter(view.layer_ids());
334 //
335 // let filtered = match view.filter_state() {
336 // FilterState::Neither => FilterVariants::Neither(iter),
337 // FilterState::Both => {
338 // let nodes = self.nodes();
339 // FilterVariants::Both(iter.filter(move |e| {
340 // view.filter_edge(e.as_ref(), view.layer_ids())
341 // && view.filter_node(nodes.node(e.src()))
342 // && view.filter_node(nodes.node(e.dst()))
343 // }))
344 // }
345 // FilterState::Nodes => {
346 // let nodes = self.nodes();
347 // FilterVariants::Nodes(iter.filter(move |e| {
348 // view.filter_node(nodes.node(e.src())) && view.filter_node(nodes.node(e.dst()))
349 // }))
350 // }
351 // FilterState::Edges | FilterState::BothIndependent => FilterVariants::Edges(
352 // iter.filter(|e| view.filter_edge(e.as_ref(), view.layer_ids())),
353 // ),
354 // };
355 // filtered.map(|e| e.out_ref())
356 // }
357 //
358 // pub fn into_edges_iter<'graph, G: GraphViewOps<'graph>>(
359 // self,
360 // view: G,
361 // ) -> impl Iterator<Item = EdgeRef> + Send + 'graph {
362 // match view.node_list() {
363 // NodeList::List { elems } => {
364 // return elems
365 // .into_iter()
366 // .flat_map(move |v| {
367 // self.clone()
368 // .into_node_edges_iter(v, Direction::OUT, view.clone())
369 // })
370 // .into_dyn_boxed()
371 // }
372 // _ => {}
373 // }
374 // let edges = self.owned_edges();
375 // let nodes = self.owned_nodes();
376 //
377 // match edges {
378 // EdgesStorage::Mem(edges) => {
379 // let iter = (0..edges.len()).map(EID);
380 // let filtered = match view.filter_state() {
381 // FilterState::Neither => {
382 // FilterVariants::Neither(iter.map(move |eid| edges.get_mem(eid).out_ref()))
383 // }
384 // FilterState::Both => FilterVariants::Both(iter.filter_map(move |e| {
385 // let e = EdgeStorageRef::Mem(edges.get_mem(e));
386 // (view.filter_edge(e, view.layer_ids())
387 // && view.filter_node(nodes.node_entry(e.src()))
388 // && view.filter_node(nodes.node_entry(e.dst())))
389 // .then(|| e.out_ref())
390 // })),
391 // FilterState::Nodes => FilterVariants::Nodes(iter.filter_map(move |e| {
392 // let e = EdgeStorageRef::Mem(edges.get_mem(e));
393 // (view.filter_node(nodes.node_entry(e.src()))
394 // && view.filter_node(nodes.node_entry(e.dst())))
395 // .then(|| e.out_ref())
396 // })),
397 // FilterState::Edges | FilterState::BothIndependent => {
398 // FilterVariants::Edges(iter.filter_map(move |e| {
399 // let e = EdgeStorageRef::Mem(edges.get_mem(e));
400 // view.filter_edge(e, view.layer_ids()).then(|| e.out_ref())
401 // }))
402 // }
403 // };
404 // filtered.into_dyn_boxed()
405 // }
406 // #[cfg(feature = "storage")]
407 // EdgesStorage::Disk(edges) => {
408 // let edges_clone = edges.clone();
409 // let iter = edges_clone.into_iter_refs(view.layer_ids().clone());
410 // let filtered = match view.filter_state() {
411 // FilterState::Neither => FilterVariants::Neither(iter),
412 // FilterState::Both => FilterVariants::Both(iter.filter_map(move |e| {
413 // let edge = EdgeStorageRef::Disk(edges.get(e.pid()));
414 // if !view.filter_edge(edge, view.layer_ids()) {
415 // return None;
416 // }
417 // let src = nodes.node_entry(e.src());
418 // if !view.filter_node(src) {
419 // return None;
420 // }
421 // let dst = nodes.node_entry(e.dst());
422 // if !view.filter_node(dst) {
423 // return None;
424 // }
425 // Some(e)
426 // })),
427 // FilterState::Nodes => FilterVariants::Nodes(iter.filter_map(move |e| {
428 // let src = nodes.node_entry(e.src());
429 // if !view.filter_node(src) {
430 // return None;
431 // }
432 // let dst = nodes.node_entry(e.dst());
433 // if !view.filter_node(dst) {
434 // return None;
435 // }
436 // Some(e)
437 // })),
438 // FilterState::Edges | FilterState::BothIndependent => {
439 // FilterVariants::Edges(iter.filter_map(move |e| {
440 // let edge = EdgeStorageRef::Disk(edges.get(e.pid()));
441 // if !view.filter_edge(edge, view.layer_ids()) {
442 // return None;
443 // }
444 // Some(e)
445 // }))
446 // }
447 // };
448 // filtered.into_dyn_boxed()
449 // }
450 // }
451 // }
452 //
453 // pub fn edges_par<'graph, G: GraphViewOps<'graph>>(
454 // &'graph self,
455 // view: &'graph G,
456 // ) -> impl ParallelIterator<Item = EdgeRef> + 'graph {
457 // self.edges()
458 // .par_iter(view.layer_ids())
459 // .filter(|edge| match view.filter_state() {
460 // FilterState::Neither => true,
461 // FilterState::Both => {
462 // let src = self.node_entry(edge.src());
463 // let dst = self.node_entry(edge.dst());
464 // view.filter_edge(edge.as_ref(), view.layer_ids())
465 // && view.filter_node(src.as_ref())
466 // && view.filter_node(dst.as_ref())
467 // }
468 // FilterState::Nodes => {
469 // let src = self.node_entry(edge.src());
470 // let dst = self.node_entry(edge.dst());
471 // view.filter_node(src.as_ref()) && view.filter_node(dst.as_ref())
472 // }
473 // FilterState::Edges | FilterState::BothIndependent => {
474 // view.filter_edge(edge.as_ref(), view.layer_ids())
475 // }
476 // })
477 // .map(|e| e.out_ref())
478 // }
479 //
480 // pub fn into_edges_par<'graph, G: GraphViewOps<'graph>>(
481 // self,
482 // view: G,
483 // ) -> impl ParallelIterator<Item = EdgeRef> + 'graph {
484 // let edges = self.owned_edges();
485 // let nodes = self.owned_nodes();
486 //
487 // match edges {
488 // EdgesStorage::Mem(edges) => {
489 // let iter = (0..edges.len()).into_par_iter().map(EID);
490 // let filtered = match view.filter_state() {
491 // FilterState::Neither => FilterVariants::Neither(
492 // iter.map(move |eid| edges.get_mem(eid).as_edge_ref()),
493 // ),
494 // FilterState::Both => FilterVariants::Both(iter.filter_map(move |e| {
495 // let e = EdgeStorageRef::Mem(edges.get_mem(e));
496 // (view.filter_edge(e, view.layer_ids())
497 // && view.filter_node(nodes.node_entry(e.src()))
498 // && view.filter_node(nodes.node_entry(e.dst())))
499 // .then(|| e.out_ref())
500 // })),
501 // FilterState::Nodes => FilterVariants::Nodes(iter.filter_map(move |e| {
502 // let e = EdgeStorageRef::Mem(edges.get_mem(e));
503 // (view.filter_node(nodes.node_entry(e.src()))
504 // && view.filter_node(nodes.node_entry(e.dst())))
505 // .then(|| e.out_ref())
506 // })),
507 // FilterState::Edges | FilterState::BothIndependent => {
508 // FilterVariants::Edges(iter.filter_map(move |e| {
509 // let e = EdgeStorageRef::Mem(edges.get_mem(e));
510 // view.filter_edge(e, view.layer_ids()).then(|| e.out_ref())
511 // }))
512 // }
513 // };
514 // #[cfg(feature = "storage")]
515 // {
516 // StorageVariants::Mem(filtered)
517 // }
518 // #[cfg(not(feature = "storage"))]
519 // {
520 // filtered
521 // }
522 // }
523 // #[cfg(feature = "storage")]
524 // EdgesStorage::Disk(edges) => {
525 // let edges_clone = edges.clone();
526 // let iter = edges_clone.into_par_iter_refs(view.layer_ids().clone());
527 // let filtered = match view.filter_state() {
528 // FilterState::Neither => FilterVariants::Neither(
529 // iter.map(move |eid| EdgeStorageRef::Disk(edges.get(eid)).out_ref()),
530 // ),
531 // FilterState::Both => FilterVariants::Both(iter.filter_map(move |eid| {
532 // let e = EdgeStorageRef::Disk(edges.get(eid));
533 // if !view.filter_edge(e, view.layer_ids()) {
534 // return None;
535 // }
536 // let src = nodes.node_entry(e.src());
537 // if !view.filter_node(src) {
538 // return None;
539 // }
540 // let dst = nodes.node_entry(e.dst());
541 // if !view.filter_node(dst) {
542 // return None;
543 // }
544 // Some(e.out_ref())
545 // })),
546 // FilterState::Nodes => FilterVariants::Nodes(iter.filter_map(move |eid| {
547 // let e = EdgeStorageRef::Disk(edges.get(eid));
548 // let src = nodes.node_entry(e.src());
549 // if !view.filter_node(src) {
550 // return None;
551 // }
552 // let dst = nodes.node_entry(e.dst());
553 // if !view.filter_node(dst) {
554 // return None;
555 // }
556 // Some(e.out_ref())
557 // })),
558 // FilterState::Edges | FilterState::BothIndependent => {
559 // FilterVariants::Edges(iter.filter_map(move |eid| {
560 // let e = EdgeStorageRef::Disk(edges.get(eid));
561 // if !view.filter_edge(e, view.layer_ids()) {
562 // return None;
563 // }
564 // Some(e.out_ref())
565 // }))
566 // }
567 // };
568 // StorageVariants::Disk(filtered)
569 // }
570 // }
571 // }
572 //
573 // pub fn node_neighbours_iter<'a, 'graph: 'a, G: GraphViewOps<'graph>>(
574 // &'a self,
575 // node: VID,
576 // dir: Direction,
577 // view: &'a G,
578 // ) -> impl Iterator<Item = VID> + Send + 'a {
579 // self.node_edges_iter(node, dir, view)
580 // .map(|e| e.remote())
581 // .dedup()
582 // }
583 //
584 // pub fn into_node_neighbours_iter<'graph, G: GraphViewOps<'graph>>(
585 // self,
586 // node: VID,
587 // dir: Direction,
588 // view: G,
589 // ) -> impl Iterator<Item = VID> + 'graph {
590 // self.into_node_edges_iter(node, dir, view)
591 // .map(|e| e.remote())
592 // .dedup()
593 // }
594 //
595 // #[inline]
596 // pub fn node_degree<'graph, G: GraphViewOps<'graph>>(
597 // &self,
598 // node: VID,
599 // dir: Direction,
600 // view: &G,
601 // ) -> usize {
602 // if matches!(view.filter_state(), FilterState::Neither) {
603 // self.node_entry(node).degree(view.layer_ids(), dir)
604 // } else {
605 // self.node_neighbours_iter(node, dir, view).count()
606 // }
607 // }
608 //
609 // pub fn node_edges_iter<'a, 'graph: 'a, G: GraphViewOps<'graph>>(
610 // &'a self,
611 // node: VID,
612 // dir: Direction,
613 // view: &'a G,
614 // ) -> impl Iterator<Item = EdgeRef> + 'a {
615 // let source = self.node_entry(node);
616 // let layers = view.layer_ids();
617 // let iter = source.into_edges_iter(layers, dir);
618 // match view.filter_state() {
619 // FilterState::Neither => FilterVariants::Neither(iter),
620 // FilterState::Both => FilterVariants::Both(iter.filter(|&e| {
621 // view.filter_edge(self.edge_entry(e.pid()).as_ref(), view.layer_ids())
622 // && view.filter_node(self.node_entry(e.remote()).as_ref())
623 // })),
624 // FilterState::Nodes => FilterVariants::Nodes(
625 // iter.filter(|e| view.filter_node(self.node_entry(e.remote()).as_ref())),
626 // ),
627 // FilterState::Edges | FilterState::BothIndependent => {
628 // FilterVariants::Edges(iter.filter(|&e| {
629 // view.filter_edge(self.edge_entry(e.pid()).as_ref(), view.layer_ids())
630 // }))
631 // }
632 // }
633 // }
634 //
635 // pub fn into_node_edges_iter<'graph, G: GraphViewOps<'graph>>(
636 // self,
637 // node: VID,
638 // dir: Direction,
639 // view: G,
640 // ) -> impl Iterator<Item = EdgeRef> + 'graph {
641 // let layers = view.layer_ids().clone();
642 // let local = self.owned_node(node);
643 // let iter = local.into_edges_iter(layers, dir);
644 //
645 // match view.filter_state() {
646 // FilterState::Neither => FilterVariants::Neither(iter),
647 // FilterState::Both => FilterVariants::Both(iter.filter(move |&e| {
648 // view.filter_edge(self.edge_entry(e.pid()).as_ref(), view.layer_ids())
649 // && view.filter_node(self.node_entry(e.remote()).as_ref())
650 // })),
651 // FilterState::Nodes => FilterVariants::Nodes(
652 // iter.filter(move |e| view.filter_node(self.node_entry(e.remote()).as_ref())),
653 // ),
654 // FilterState::Edges | FilterState::BothIndependent => {
655 // FilterVariants::Edges(iter.filter(move |&e| {
656 // view.filter_edge(self.edge_entry(e.pid()).as_ref(), view.layer_ids())
657 // }))
658 // }
659 // }
660 // }
661
662 pub fn node_meta(&self) -> &Meta {
663 match self {
664 GraphStorage::Mem(storage) => &storage.graph.node_meta,
665 GraphStorage::Unlocked(storage) => &storage.node_meta,
666 #[cfg(feature = "storage")]
667 GraphStorage::Disk(storage) => storage.node_meta(),
668 }
669 }
670
671 pub fn edge_meta(&self) -> &Meta {
672 match self {
673 GraphStorage::Mem(storage) => &storage.graph.edge_meta,
674 GraphStorage::Unlocked(storage) => &storage.edge_meta,
675 #[cfg(feature = "storage")]
676 GraphStorage::Disk(storage) => storage.edge_meta(),
677 }
678 }
679
680 pub fn graph_meta(&self) -> &GraphMeta {
681 match self {
682 GraphStorage::Mem(storage) => &storage.graph.graph_meta,
683 GraphStorage::Unlocked(storage) => &storage.graph_meta,
684 #[cfg(feature = "storage")]
685 GraphStorage::Disk(storage) => storage.graph_meta(),
686 }
687 }
688}