1use crate::{
2 core::{
3 entities::{edges::edge_ref::EdgeRef, VID},
4 storage::timeindex::AsTime,
5 },
6 db::api::{
7 properties::internal::InternalPropertiesOps,
8 state::{ops, NodeOp},
9 view::{internal::OneHopFilter, node_edges, reset_filter::ResetFilter, TimeOps},
10 },
11 prelude::{EdgeViewOps, GraphViewOps, LayerOps},
12};
13use chrono::{DateTime, Utc};
14use itertools::Itertools;
15use raphtory_api::core::Direction;
16use raphtory_storage::graph::graph::GraphStorage;
17
18pub trait BaseNodeViewOps<'graph>: Clone + TimeOps<'graph> + LayerOps<'graph> {
19 type BaseGraph: GraphViewOps<'graph>;
20 type Graph: GraphViewOps<'graph>;
21 type ValueType<Op>: 'graph
22 where
23 Op: NodeOp + 'graph,
24 Op::Output: 'graph;
25
26 type PropType: InternalPropertiesOps + Clone + 'graph;
27 type PathType: NodeViewOps<'graph, BaseGraph = Self::BaseGraph, Graph = Self::BaseGraph>
28 + 'graph;
29 type Edges: EdgeViewOps<'graph, Graph = Self::Graph, BaseGraph = Self::BaseGraph> + 'graph;
30
31 fn graph(&self) -> &Self::Graph;
32
33 fn map<F: NodeOp + Clone + 'graph>(&self, op: F) -> Self::ValueType<F>;
34 fn map_edges<
35 I: Iterator<Item = EdgeRef> + Send + Sync + 'graph,
36 F: Fn(&GraphStorage, &Self::Graph, VID) -> I + Send + Sync + Clone + 'graph,
37 >(
38 &self,
39 op: F,
40 ) -> Self::Edges;
41
42 fn hop<
43 I: Iterator<Item = VID> + Send + Sync + 'graph,
44 F: for<'a> Fn(&GraphStorage, &'a Self::Graph, VID) -> I + Send + Sync + Clone + 'graph,
45 >(
46 &self,
47 op: F,
48 ) -> Self::PathType;
49}
50
51pub trait NodeViewOps<'graph>: Clone + TimeOps<'graph> + LayerOps<'graph> {
53 type BaseGraph: GraphViewOps<'graph>;
54 type Graph: GraphViewOps<'graph>;
55 type ValueType<T: NodeOp>: 'graph
56 where
57 T: 'graph,
58 T::Output: 'graph;
59 type PathType: NodeViewOps<'graph, BaseGraph = Self::BaseGraph, Graph = Self::BaseGraph>
60 + 'graph;
61 type Edges: EdgeViewOps<'graph, Graph = Self::Graph, BaseGraph = Self::BaseGraph> + 'graph;
62
63 fn id(&self) -> Self::ValueType<ops::Id>;
65
66 fn name(&self) -> Self::ValueType<ops::Name>;
72
73 fn node_type(&self) -> Self::ValueType<ops::Type>;
75 fn node_type_id(&self) -> Self::ValueType<ops::TypeId>;
76 fn earliest_time(&self) -> Self::ValueType<ops::EarliestTime<Self::Graph>>;
78
79 fn earliest_date_time(
80 &self,
81 ) -> Self::ValueType<ops::Map<ops::EarliestTime<Self::Graph>, Option<DateTime<Utc>>>>;
82
83 fn latest_time(&self) -> Self::ValueType<ops::LatestTime<Self::Graph>>;
85
86 fn latest_date_time(
87 &self,
88 ) -> Self::ValueType<ops::Map<ops::LatestTime<Self::Graph>, Option<DateTime<Utc>>>>;
89
90 fn history(&self) -> Self::ValueType<ops::History<Self::Graph>>;
92
93 fn edge_history_count(&self) -> Self::ValueType<ops::EdgeHistoryCount<Self::Graph>>;
95
96 fn history_date_time(
98 &self,
99 ) -> Self::ValueType<ops::Map<ops::History<Self::Graph>, Option<Vec<DateTime<Utc>>>>>;
100
101 fn is_active(&self) -> Self::ValueType<ops::Map<ops::History<Self::Graph>, bool>>;
103
104 fn properties(&self) -> Self::ValueType<ops::GetProperties<'graph, Self::Graph>>;
109
110 fn metadata(&self) -> Self::ValueType<ops::GetMetadata<'graph, Self::Graph>>;
112
113 fn degree(&self) -> Self::ValueType<ops::Degree<Self::Graph>>;
119
120 fn in_degree(&self) -> Self::ValueType<ops::Degree<Self::Graph>>;
126
127 fn out_degree(&self) -> Self::ValueType<ops::Degree<Self::Graph>>;
133
134 fn edges(&self) -> Self::Edges;
140
141 fn in_edges(&self) -> Self::Edges;
147
148 fn out_edges(&self) -> Self::Edges;
154
155 fn neighbours(&self) -> Self::PathType;
161
162 fn in_neighbours(&self) -> Self::PathType;
168
169 fn out_neighbours(&self) -> Self::PathType;
175}
176
177impl<'graph, V: BaseNodeViewOps<'graph> + 'graph> NodeViewOps<'graph> for V {
178 type BaseGraph = V::BaseGraph;
179 type Graph = V::Graph;
180 type ValueType<T: NodeOp + 'graph>
181 = V::ValueType<T>
182 where
183 T::Output: 'graph;
184 type PathType = V::PathType;
185 type Edges = V::Edges;
186
187 #[inline]
188 fn id(&self) -> Self::ValueType<ops::Id> {
189 self.map(ops::Id)
190 }
191
192 #[inline]
193 fn name(&self) -> Self::ValueType<ops::Name> {
194 self.map(ops::Name)
195 }
196 #[inline]
197 fn node_type(&self) -> Self::ValueType<ops::Type> {
198 self.map(ops::Type)
199 }
200 #[inline]
201 fn node_type_id(&self) -> Self::ValueType<ops::TypeId> {
202 self.map(ops::TypeId)
203 }
204 #[inline]
205 fn earliest_time(&self) -> Self::ValueType<ops::EarliestTime<Self::Graph>> {
206 let op = ops::EarliestTime {
207 graph: self.graph().clone(),
208 };
209 self.map(op)
210 }
211 #[inline]
212 fn earliest_date_time(
213 &self,
214 ) -> Self::ValueType<ops::Map<ops::EarliestTime<Self::Graph>, Option<DateTime<Utc>>>> {
215 let op = ops::EarliestTime {
216 graph: self.graph().clone(),
217 }
218 .map(|t| t.and_then(|t| t.dt()));
219 self.map(op)
220 }
221
222 #[inline]
223 fn latest_time(&self) -> Self::ValueType<ops::LatestTime<Self::Graph>> {
224 let op = ops::LatestTime {
225 graph: self.graph().clone(),
226 };
227 self.map(op)
228 }
229
230 #[inline]
231 fn latest_date_time(
232 &self,
233 ) -> Self::ValueType<ops::Map<ops::LatestTime<Self::Graph>, Option<DateTime<Utc>>>> {
234 let op = ops::LatestTime {
235 graph: self.graph().clone(),
236 }
237 .map(|t| t.and_then(|t| t.dt()));
238 self.map(op)
239 }
240
241 #[inline]
242 fn history(&self) -> Self::ValueType<ops::History<Self::Graph>> {
243 let op = ops::History {
244 graph: self.graph().clone(),
245 };
246 self.map(op)
247 }
248
249 #[inline]
250 fn edge_history_count(&self) -> Self::ValueType<ops::EdgeHistoryCount<Self::Graph>> {
251 let op = ops::EdgeHistoryCount {
252 graph: self.graph().clone(),
253 };
254 self.map(op)
255 }
256 #[inline]
257 fn history_date_time(
258 &self,
259 ) -> Self::ValueType<ops::Map<ops::History<Self::Graph>, Option<Vec<DateTime<Utc>>>>> {
260 let op = ops::History {
261 graph: self.graph().clone(),
262 }
263 .map(|h| h.into_iter().map(|t| t.dt()).collect());
264 self.map(op)
265 }
266
267 fn is_active(&self) -> Self::ValueType<ops::Map<ops::History<Self::Graph>, bool>> {
269 let op = ops::History {
270 graph: self.graph().clone(),
271 }
272 .map(|h| !h.is_empty());
273 self.map(op)
274 }
275
276 #[inline]
277 fn properties(&self) -> Self::ValueType<ops::GetProperties<'graph, Self::Graph>> {
278 let op = ops::GetProperties::new(self.graph().clone());
279 self.map(op)
280 }
281
282 #[inline]
283 fn metadata(&self) -> Self::ValueType<ops::GetMetadata<'graph, Self::Graph>> {
284 let op = ops::GetMetadata::new(self.graph().clone());
285 self.map(op)
286 }
287
288 #[inline]
289 fn degree(&self) -> Self::ValueType<ops::Degree<Self::Graph>> {
290 let op = ops::Degree {
291 graph: self.graph().clone(),
292 dir: Direction::BOTH,
293 };
294 self.map(op)
295 }
296 #[inline]
297 fn in_degree(&self) -> Self::ValueType<ops::Degree<Self::Graph>> {
298 let op = ops::Degree {
299 graph: self.graph().clone(),
300 dir: Direction::IN,
301 };
302 self.map(op)
303 }
304 #[inline]
305 fn out_degree(&self) -> Self::ValueType<ops::Degree<Self::Graph>> {
306 let op = ops::Degree {
307 graph: self.graph().clone(),
308 dir: Direction::OUT,
309 };
310 self.map(op)
311 }
312 #[inline]
313 fn edges(&self) -> Self::Edges {
314 self.map_edges(|cg, g, v| {
315 let cg = cg.clone();
316 let g = g.clone();
317 node_edges(cg, g, v, Direction::BOTH)
318 })
319 }
320 #[inline]
321 fn in_edges(&self) -> Self::Edges {
322 self.map_edges(|cg, g, v| {
323 let cg = cg.clone();
324 let g = g.clone();
325 node_edges(cg, g, v, Direction::IN)
326 })
327 }
328 #[inline]
329 fn out_edges(&self) -> Self::Edges {
330 self.map_edges(|cg, g, v| {
331 let cg = cg.clone();
332 let g = g.clone();
333 node_edges(cg, g, v, Direction::OUT)
334 })
335 }
336 #[inline]
337 fn neighbours(&self) -> Self::PathType {
338 self.hop(|cg, g, v| {
339 let cg = cg.clone();
340 let g = g.clone();
341 node_edges(cg, g, v, Direction::BOTH)
342 .map(|e| e.remote())
343 .dedup()
344 })
345 }
346 #[inline]
347 fn in_neighbours(&self) -> Self::PathType {
348 self.hop(|cg, g, v| {
349 let cg = cg.clone();
350 let g = g.clone();
351 node_edges(cg, g, v, Direction::IN)
352 .map(|e| e.remote())
353 .dedup()
354 })
355 }
356 #[inline]
357 fn out_neighbours(&self) -> Self::PathType {
358 self.hop(|cg, g, v| {
359 let cg = cg.clone();
360 let g = g.clone();
361 node_edges(cg, g, v, Direction::OUT)
362 .map(|e| e.remote())
363 .dedup()
364 })
365 }
366}
367
368impl<'graph, V: BaseNodeViewOps<'graph> + OneHopFilter<'graph>> ResetFilter<'graph> for V {}