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}