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