raphtory/db/graph/views/filter/
edge_and_filtered_graph.rs

1use crate::{
2    db::{
3        api::{
4            properties::internal::InheritPropertiesOps,
5            view::internal::{
6                EdgeHistoryFilter, EdgeList, Immutable, InheritMaterialize, InheritNodeFilterOps,
7                InheritNodeHistoryFilter, InheritStorageOps, InheritTimeSemantics,
8                InternalEdgeFilterOps, InternalEdgeLayerFilterOps, InternalExplodedEdgeFilterOps,
9                InternalLayerOps, ListOps, NodeList, Static,
10            },
11        },
12        graph::views::filter::{
13            internal::{CreateEdgeFilter, CreateExplodedEdgeFilter},
14            model::AndFilter,
15        },
16    },
17    errors::GraphError,
18    prelude::GraphViewOps,
19};
20use raphtory_api::{
21    core::{
22        entities::{LayerIds, EID, ELID},
23        storage::timeindex::TimeIndexEntry,
24    },
25    inherit::Base,
26};
27use raphtory_storage::{core_ops::InheritCoreGraphOps, graph::edges::edge_ref::EdgeStorageRef};
28use std::ops::Range;
29
30#[derive(Debug, Clone)]
31pub struct EdgeAndFilteredGraph<G, L, R> {
32    graph: G,
33    left: L,
34    right: R,
35    layer_ids: LayerIds,
36}
37
38impl<L: CreateEdgeFilter, R: CreateEdgeFilter> CreateEdgeFilter for AndFilter<L, R> {
39    type EdgeFiltered<'graph, G: GraphViewOps<'graph>>
40        = EdgeAndFilteredGraph<G, L::EdgeFiltered<'graph, G>, R::EdgeFiltered<'graph, G>>
41    where
42        Self: 'graph;
43
44    fn create_edge_filter<'graph, G: GraphViewOps<'graph>>(
45        self,
46        graph: G,
47    ) -> Result<Self::EdgeFiltered<'graph, G>, GraphError> {
48        let left = self.left.create_edge_filter(graph.clone())?;
49        let right = self.right.create_edge_filter(graph.clone())?;
50        let layer_ids = left.layer_ids().intersect(right.layer_ids());
51        Ok(EdgeAndFilteredGraph {
52            graph,
53            left,
54            right,
55            layer_ids,
56        })
57    }
58}
59
60impl<L: CreateExplodedEdgeFilter, R: CreateExplodedEdgeFilter> CreateExplodedEdgeFilter
61    for AndFilter<L, R>
62{
63    type ExplodedEdgeFiltered<'graph, G: GraphViewOps<'graph>>
64        = EdgeAndFilteredGraph<
65        G,
66        L::ExplodedEdgeFiltered<'graph, G>,
67        R::ExplodedEdgeFiltered<'graph, G>,
68    >
69    where
70        Self: 'graph;
71
72    fn create_exploded_edge_filter<'graph, G: GraphViewOps<'graph>>(
73        self,
74        graph: G,
75    ) -> Result<Self::ExplodedEdgeFiltered<'graph, G>, GraphError> {
76        let left = self.left.create_exploded_edge_filter(graph.clone())?;
77        let right = self.right.create_exploded_edge_filter(graph.clone())?;
78        let layer_ids = left.layer_ids().intersect(right.layer_ids());
79        Ok(EdgeAndFilteredGraph {
80            graph,
81            left,
82            right,
83            layer_ids,
84        })
85    }
86}
87
88impl<G, L, R> Base for EdgeAndFilteredGraph<G, L, R> {
89    type Base = G;
90
91    fn base(&self) -> &Self::Base {
92        &self.graph
93    }
94}
95
96impl<G, L, R> Static for EdgeAndFilteredGraph<G, L, R> {}
97impl<G, L, R> Immutable for EdgeAndFilteredGraph<G, L, R> {}
98
99impl<G, L, R> InheritCoreGraphOps for EdgeAndFilteredGraph<G, L, R> {}
100impl<'graph, G: GraphViewOps<'graph>, L, R> InheritStorageOps for EdgeAndFilteredGraph<G, L, R> {}
101impl<'graph, G: GraphViewOps<'graph>, L, R> InheritMaterialize for EdgeAndFilteredGraph<G, L, R> {}
102impl<'graph, G: GraphViewOps<'graph>, L, R> InheritNodeFilterOps for EdgeAndFilteredGraph<G, L, R> {}
103impl<'graph, G: GraphViewOps<'graph>, L, R> InheritPropertiesOps for EdgeAndFilteredGraph<G, L, R> {}
104impl<'graph, G: GraphViewOps<'graph>, L, R> InheritTimeSemantics for EdgeAndFilteredGraph<G, L, R> {}
105impl<'graph, G: GraphViewOps<'graph>, L, R> InheritNodeHistoryFilter
106    for EdgeAndFilteredGraph<G, L, R>
107{
108}
109
110impl<G, L: Send + Sync, R: Send + Sync> InternalLayerOps for EdgeAndFilteredGraph<G, L, R>
111where
112    G: InternalLayerOps,
113{
114    fn layer_ids(&self) -> &LayerIds {
115        &self.layer_ids
116    }
117}
118
119impl<G, L, R> ListOps for EdgeAndFilteredGraph<G, L, R>
120where
121    L: ListOps,
122    R: ListOps,
123{
124    fn node_list(&self) -> NodeList {
125        let left = self.left.node_list();
126        let right = self.right.node_list();
127        left.intersection(&right)
128    }
129
130    fn edge_list(&self) -> EdgeList {
131        let left = self.left.edge_list();
132        let right = self.right.edge_list();
133        left.intersection(&right)
134    }
135}
136
137impl<G, L, R> EdgeHistoryFilter for EdgeAndFilteredGraph<G, L, R>
138where
139    L: EdgeHistoryFilter,
140    R: EdgeHistoryFilter,
141{
142    fn is_edge_prop_update_available(
143        &self,
144        layer_id: usize,
145        prop_id: usize,
146        edge_id: EID,
147        time: TimeIndexEntry,
148    ) -> bool {
149        self.left
150            .is_edge_prop_update_available(layer_id, prop_id, edge_id, time)
151            && self
152                .right
153                .is_edge_prop_update_available(layer_id, prop_id, edge_id, time)
154    }
155
156    fn is_edge_prop_update_available_window(
157        &self,
158        layer_id: usize,
159        prop_id: usize,
160        edge_id: EID,
161        time: TimeIndexEntry,
162        w: Range<i64>,
163    ) -> bool {
164        self.left
165            .is_edge_prop_update_available_window(layer_id, prop_id, edge_id, time, w.clone())
166            && self
167                .right
168                .is_edge_prop_update_available_window(layer_id, prop_id, edge_id, time, w)
169    }
170
171    fn is_edge_prop_update_latest(
172        &self,
173        layer_ids: &LayerIds,
174        layer_id: usize,
175        prop_id: usize,
176        edge_id: EID,
177        time: TimeIndexEntry,
178    ) -> bool {
179        self.left
180            .is_edge_prop_update_latest(layer_ids, layer_id, prop_id, edge_id, time)
181            && self
182                .right
183                .is_edge_prop_update_latest(layer_ids, layer_id, prop_id, edge_id, time)
184    }
185
186    fn is_edge_prop_update_latest_window(
187        &self,
188        layer_ids: &LayerIds,
189        layer_id: usize,
190        prop_id: usize,
191        edge_id: EID,
192        time: TimeIndexEntry,
193        w: Range<i64>,
194    ) -> bool {
195        self.left.is_edge_prop_update_latest_window(
196            layer_ids,
197            layer_id,
198            prop_id,
199            edge_id,
200            time,
201            w.clone(),
202        ) && self
203            .right
204            .is_edge_prop_update_latest_window(layer_ids, layer_id, prop_id, edge_id, time, w)
205    }
206}
207
208impl<G, L: InternalEdgeLayerFilterOps, R: InternalEdgeLayerFilterOps> InternalEdgeLayerFilterOps
209    for EdgeAndFilteredGraph<G, L, R>
210{
211    fn internal_edge_layer_filtered(&self) -> bool {
212        self.left.internal_edge_layer_filtered() || self.right.internal_edge_layer_filtered()
213    }
214
215    fn internal_layer_filter_edge_list_trusted(&self) -> bool {
216        self.left.internal_layer_filter_edge_list_trusted()
217            && self.right.internal_layer_filter_edge_list_trusted()
218    }
219
220    fn internal_filter_edge_layer(&self, edge: EdgeStorageRef, layer: usize) -> bool {
221        self.left.internal_filter_edge_layer(edge, layer)
222            && self.right.internal_filter_edge_layer(edge, layer)
223    }
224}
225
226impl<G, L: InternalExplodedEdgeFilterOps, R: InternalExplodedEdgeFilterOps>
227    InternalExplodedEdgeFilterOps for EdgeAndFilteredGraph<G, L, R>
228{
229    fn internal_exploded_edge_filtered(&self) -> bool {
230        self.left.internal_exploded_edge_filtered() || self.right.internal_exploded_edge_filtered()
231    }
232
233    fn internal_exploded_filter_edge_list_trusted(&self) -> bool {
234        self.left.internal_exploded_filter_edge_list_trusted()
235            && self.right.internal_exploded_filter_edge_list_trusted()
236    }
237
238    fn internal_filter_exploded_edge(
239        &self,
240        eid: ELID,
241        t: TimeIndexEntry,
242        layer_ids: &LayerIds,
243    ) -> bool {
244        self.left.internal_filter_exploded_edge(eid, t, layer_ids)
245            && self.right.internal_filter_exploded_edge(eid, t, layer_ids)
246    }
247}
248
249impl<G, L: InternalEdgeFilterOps, R: InternalEdgeFilterOps> InternalEdgeFilterOps
250    for EdgeAndFilteredGraph<G, L, R>
251{
252    #[inline]
253    fn internal_edge_filtered(&self) -> bool {
254        self.left.internal_edge_filtered() || self.right.internal_edge_filtered()
255    }
256
257    #[inline]
258    fn internal_edge_list_trusted(&self) -> bool {
259        self.left.internal_edge_list_trusted() && self.right.internal_edge_list_trusted()
260    }
261
262    #[inline]
263    fn internal_filter_edge(&self, edge: EdgeStorageRef, layer_ids: &LayerIds) -> bool {
264        self.left.internal_filter_edge(edge, layer_ids)
265            && self.right.internal_filter_edge(edge, layer_ids)
266    }
267}