use crate::db::api::view::internal::{
time_semantics::{
filtered_edge::FilteredEdgeStorageOps, filtered_node::FilteredNodeStorageOps,
time_semantics_ops::NodeTimeSemanticsOps,
},
EdgeTimeSemanticsOps, FilterOps, GraphView, InnerFilterOps,
};
use either::Either;
use itertools::Itertools;
use raphtory_api::core::{
entities::{
properties::{prop::Prop, tprop::TPropOps},
LayerIds, ELID,
},
storage::timeindex::{EventTime, TimeIndexOps},
};
use raphtory_storage::graph::{
edges::{edge_ref::EdgeStorageRef, edge_storage_ops::EdgeStorageOps},
nodes::{node_ref::NodeStorageRef, node_storage_ops::NodeStorageOps},
};
use std::ops::Range;
#[derive(Debug, Copy, Clone)]
pub struct EventSemantics;
impl NodeTimeSemanticsOps for EventSemantics {
fn node_earliest_time<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
view: G,
) -> Option<EventTime> {
node.history(view).first()
}
fn node_latest_time<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
view: G,
) -> Option<EventTime> {
node.history(view).last()
}
fn node_earliest_time_window<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> Option<EventTime> {
node.history(view).range(w).first()
}
fn node_latest_time_window<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> Option<EventTime> {
node.history(view).range(w).last()
}
fn node_history<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
) -> impl Iterator<Item = EventTime> + Send + Sync + 'graph {
node.history(view).iter()
}
fn node_history_rev<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
) -> impl Iterator<Item = EventTime> + Send + Sync + 'graph {
node.history(view).iter_rev()
}
fn node_history_window<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> impl Iterator<Item = EventTime> + Send + Sync + 'graph {
node.history(view).range(w).iter()
}
fn node_history_window_rev<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> impl Iterator<Item = EventTime> + Send + Sync + 'graph {
node.history(view).range(w).iter_rev()
}
fn node_edge_history_count<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
) -> usize {
node.history(view).edge_history().len()
}
fn node_edge_history_count_window<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> usize {
node.history(view).range(w).edge_history().len()
}
fn node_edge_history<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
) -> impl Iterator<Item = (EventTime, ELID)> + Send + Sync + 'graph {
node.edge_history(view).history()
}
fn node_edge_history_window<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, ELID)> + Send + Sync + 'graph {
node.edge_history(view).range(w).history()
}
fn node_edge_history_rev<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
) -> impl Iterator<Item = (EventTime, ELID)> + Send + Sync + 'graph {
node.edge_history(view).history_rev()
}
fn node_edge_history_rev_window<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, ELID)> + Send + Sync + 'graph {
node.edge_history(view).range(w).history_rev()
}
fn node_updates<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
_view: G,
) -> impl Iterator<Item = (EventTime, Vec<(usize, Prop)>)> + Send + Sync + 'graph {
node.temp_prop_rows().map(|(t, row)| {
(
t,
row.into_iter()
.filter_map(|(id, prop)| Some((id, prop?)))
.collect(),
)
})
}
fn node_updates_window<'graph, G: GraphView + 'graph>(
self,
node: NodeStorageRef<'graph>,
_view: G,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, Vec<(usize, Prop)>)> + Send + Sync + 'graph {
node.temp_prop_rows_window(w).map(|(t, row)| {
(
t,
row.into_iter()
.filter_map(|(id, prop)| Some((id, prop?)))
.collect(),
)
})
}
fn node_valid<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
view: G,
) -> bool {
!node.history(view).is_empty()
}
fn node_valid_window<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> bool {
node.history(view).active(w)
}
fn node_tprop_iter<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
_view: G,
prop_id: usize,
) -> impl DoubleEndedIterator<Item = (EventTime, Prop)> + Send + Sync + 'graph {
node.tprop(prop_id).iter()
}
fn node_tprop_iter_window<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
_view: G,
prop_id: usize,
w: Range<EventTime>,
) -> impl DoubleEndedIterator<Item = (EventTime, Prop)> + Send + Sync + 'graph {
node.tprop(prop_id).iter_window(w)
}
fn node_tprop_last_at<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
_view: G,
prop_id: usize,
t: EventTime,
) -> Option<(EventTime, Prop)> {
let prop = node.tprop(prop_id);
prop.last_before(t.next())
}
fn node_tprop_last_at_window<'graph, G: GraphView + 'graph>(
&self,
node: NodeStorageRef<'graph>,
_view: G,
prop_id: usize,
t: EventTime,
w: Range<EventTime>,
) -> Option<(EventTime, Prop)> {
if w.contains(&t) {
let prop = node.tprop(prop_id);
prop.last_before(t.next()).filter(|(t, _)| w.contains(t))
} else {
None
}
}
}
impl EdgeTimeSemanticsOps for EventSemantics {
fn handle_edge_update_filter<G: GraphView>(
&self,
t: EventTime,
eid: ELID,
view: G,
) -> Option<(EventTime, ELID)> {
view.filter_exploded_edge_inner(eid, t).then_some((t, eid))
}
fn include_edge<G: GraphView>(&self, edge: EdgeStorageRef, view: G, layer_id: usize) -> bool {
!edge.filtered_additions(layer_id, &view).is_empty()
|| !edge.filtered_deletions(layer_id, &view).is_empty()
}
fn include_edge_window<G: GraphView>(
&self,
edge: EdgeStorageRef,
view: G,
layer_id: usize,
w: Range<EventTime>,
) -> bool {
edge.filtered_additions(layer_id, &view).active(w.clone())
|| edge.filtered_deletions(layer_id, &view).active(w)
}
fn include_exploded_edge<G: GraphView>(&self, eid: ELID, t: EventTime, view: G) -> bool {
view.layer_ids().contains(&eid.layer())
&& view.internal_filter_exploded_edge(eid, t, view.layer_ids())
&& (view.exploded_filter_independent() || {
let edge = view.core_edge(eid.edge);
(view.exploded_edge_filter_includes_edge_layer_filter()
|| view.internal_filter_edge_layer(edge.as_ref(), eid.layer()))
&& (view.exploded_edge_filter_includes_edge_filter()
|| view.edge_layer_filter_includes_edge_filter()
|| view.internal_filter_edge(edge.as_ref(), view.layer_ids()))
&& view.filter_edge_from_nodes(edge.as_ref())
})
}
fn include_exploded_edge_window<G: GraphView>(
&self,
elid: ELID,
t: EventTime,
view: G,
w: Range<EventTime>,
) -> bool {
w.contains(&t) && self.include_exploded_edge(elid, t, view)
}
fn edge_history<'graph, G: GraphView + 'graph>(
self,
edge: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
edge.filtered_additions_iter(view, layer_ids)
.map(|(layer_id, additions)| additions.iter().map(move |t| (t, layer_id)))
.kmerge()
}
fn edge_history_rev<'graph, G: GraphView + 'graph>(
self,
edge: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
edge.filtered_additions_iter(view, layer_ids)
.map(|(layer_id, additions)| additions.iter_rev().map(move |t| (t, layer_id)))
.kmerge_by(|a, b| a >= b)
}
fn edge_history_window<'graph, G: GraphView + 'graph>(
self,
edge: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
edge.filtered_additions_iter(view, layer_ids)
.map(move |(layer_id, additions)| {
additions
.range(w.clone())
.iter()
.map(move |t| (t, layer_id))
})
.kmerge()
}
fn edge_history_window_rev<'graph, G: GraphView + 'graph>(
self,
edge: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
edge.filtered_additions_iter(view, layer_ids)
.map(move |(layer_id, additions)| {
additions
.range(w.clone())
.iter_rev()
.map(move |t| (t, layer_id))
})
.kmerge_by(|a, b| a >= b)
}
fn edge_exploded_count<'graph, G: GraphView + 'graph>(
&self,
edge: EdgeStorageRef,
view: G,
) -> usize {
edge.filtered_additions_iter(&view, view.layer_ids())
.map(|(_, additions)| additions.len())
.sum()
}
fn edge_exploded_count_window<'graph, G: GraphView + 'graph>(
&self,
edge: EdgeStorageRef,
view: G,
w: Range<EventTime>,
) -> usize {
edge.filtered_additions_iter(&view, view.layer_ids())
.map(|(_, additions)| additions.range(w.clone()).len())
.sum()
}
fn edge_exploded<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
self.edge_history(e, view, layer_ids)
}
fn edge_layers<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
) -> impl Iterator<Item = usize> + Send + Sync + 'graph {
if view.filtered() {
Either::Left(e.filtered_updates_iter(view, layer_ids).filter_map(
move |(layer_id, additions, deletions)| {
if additions.is_empty() && deletions.is_empty() {
None
} else {
Some(layer_id)
}
},
))
} else {
Either::Right(e.layer_ids_iter(layer_ids))
}
}
fn edge_window_exploded<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
self.edge_history_window(e, view, layer_ids, w)
}
fn edge_window_layers<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
w: Range<EventTime>,
) -> impl Iterator<Item = usize> + Send + Sync + 'graph {
e.filtered_updates_iter(view, layer_ids).filter_map(
move |(layer_id, additions, deletions)| {
(additions.active(w.clone()) || deletions.active(w.clone())).then_some(layer_id)
},
)
}
fn edge_earliest_time<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
) -> Option<EventTime> {
e.filtered_additions_iter(&view, view.layer_ids())
.filter_map(|(_, additions)| additions.first())
.chain(
e.filtered_deletions_iter(&view, view.layer_ids())
.filter_map(|(_, deletions)| deletions.first()),
)
.min()
}
fn edge_earliest_time_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
w: Range<EventTime>,
) -> Option<EventTime> {
e.filtered_additions_iter(&view, view.layer_ids())
.filter_map(|(_, additions)| additions.range(w.clone()).first())
.chain(
e.filtered_deletions_iter(&view, view.layer_ids())
.filter_map(|(_, deletions)| deletions.range(w.clone()).first()),
)
.min()
}
fn edge_exploded_earliest_time<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
t: EventTime,
layer: usize,
) -> Option<EventTime> {
view.internal_filter_exploded_edge(e.eid().with_layer(layer), t, view.layer_ids())
.then_some(t)
}
fn edge_exploded_earliest_time_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
t: EventTime,
layer: usize,
w: Range<EventTime>,
) -> Option<EventTime> {
if !w.contains(&t) {
return None;
}
self.edge_exploded_earliest_time(e, view, t, layer)
}
fn edge_latest_time<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
) -> Option<EventTime> {
e.filtered_additions_iter(&view, view.layer_ids())
.filter_map(|(_, additions)| additions.last())
.chain(
e.filtered_deletions_iter(&view, view.layer_ids())
.filter_map(|(_, deletions)| deletions.last()),
)
.max()
}
fn edge_latest_time_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
w: Range<EventTime>,
) -> Option<EventTime> {
e.filtered_additions_iter(&view, view.layer_ids())
.filter_map(|(_, additions)| additions.range(w.clone()).last())
.chain(
e.filtered_deletions_iter(&view, view.layer_ids())
.filter_map(|(_, deletions)| deletions.range(w.clone()).last()),
)
.max()
}
fn edge_exploded_latest_time<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
t: EventTime,
layer: usize,
) -> Option<EventTime> {
self.edge_exploded_earliest_time(e, view, t, layer)
}
fn edge_exploded_latest_time_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
t: EventTime,
layer: usize,
w: Range<EventTime>,
) -> Option<EventTime> {
self.edge_exploded_earliest_time_window(e, view, t, layer, w)
}
fn edge_deletion_history<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
e.filtered_deletions_iter(view, layer_ids)
.map(|(layer_id, t)| t.iter().map(move |t| (t, layer_id)))
.kmerge()
}
fn edge_deletion_history_rev<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
e.filtered_deletions_iter(view, layer_ids)
.map(|(layer_id, t)| t.iter_rev().map(move |t| (t, layer_id)))
.kmerge_by(|(t1, _), (t2, _)| t1 >= t2)
}
fn edge_deletion_history_window<'graph, G: GraphView + 'graph>(
self,
edge: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
edge.filtered_deletions_iter(view, layer_ids)
.map(move |(layer_id, additions)| {
additions
.range(w.clone())
.iter()
.map(move |t| (t, layer_id))
})
.kmerge()
}
fn edge_deletion_history_window_rev<'graph, G: GraphView + 'graph>(
self,
edge: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, usize)> + Send + Sync + 'graph {
edge.filtered_deletions_iter(view, layer_ids)
.map(move |(layer_id, additions)| {
additions
.range(w.clone())
.iter_rev()
.map(move |t| (t, layer_id))
})
.kmerge_by(|(t1, _), (t2, _)| t1 >= t2)
}
fn edge_is_valid<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
) -> bool {
e.filtered_additions_iter(&view, view.layer_ids())
.any(|(_, additions)| !additions.is_empty())
}
fn edge_is_valid_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> bool {
e.filtered_additions_iter(&view, view.layer_ids())
.any(|(_, additions)| !additions.range(w.clone()).is_empty())
}
fn edge_is_deleted<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
) -> bool {
e.filtered_deletions_iter(&view, view.layer_ids())
.any(|(_, deletions)| !deletions.is_empty())
}
fn edge_is_deleted_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> bool {
e.filtered_deletions_iter(&view, view.layer_ids())
.any(|(_, deletions)| !deletions.range(w.clone()).is_empty())
}
fn edge_is_active<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
) -> bool {
self.edge_is_valid(e, &view) || self.edge_is_deleted(e, &view)
}
fn edge_is_active_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
w: Range<EventTime>,
) -> bool {
self.edge_is_valid_window(e, &view, w.clone()) || self.edge_is_deleted_window(e, &view, w)
}
fn edge_is_active_exploded<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
t: EventTime,
layer: usize,
) -> bool {
view.internal_filter_exploded_edge(e.eid().with_layer(layer), t, view.layer_ids())
}
fn edge_is_active_exploded_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
t: EventTime,
layer: usize,
w: Range<EventTime>,
) -> bool {
w.contains(&t)
&& view.internal_filter_exploded_edge(e.eid().with_layer(layer), t, view.layer_ids())
}
fn edge_is_valid_exploded<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
t: EventTime,
layer: usize,
) -> bool {
self.edge_is_active_exploded(e, view, t, layer)
}
fn edge_is_valid_exploded_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
t: EventTime,
layer: usize,
w: Range<EventTime>,
) -> bool {
self.edge_is_active_exploded_window(e, view, t, layer, w)
}
fn edge_exploded_deletion<'graph, G: GraphView + 'graph>(
&self,
_e: EdgeStorageRef<'graph>,
_view: G,
_t: EventTime,
_layer: usize,
) -> Option<EventTime> {
None
}
fn edge_exploded_deletion_window<'graph, G: GraphView + 'graph>(
&self,
_e: EdgeStorageRef<'graph>,
_view: G,
_t: EventTime,
_layer: usize,
_w: Range<EventTime>,
) -> Option<EventTime> {
None
}
fn temporal_edge_prop_exploded<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
prop_id: usize,
t: EventTime,
layer_id: usize,
) -> Option<Prop> {
let eid = e.eid();
if view.internal_filter_exploded_edge(eid.with_layer(layer_id), t, view.layer_ids()) {
e.temporal_prop_layer(layer_id, prop_id).at(&t)
} else {
None
}
}
fn temporal_edge_prop_exploded_last_at<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
edge_time: EventTime,
layer_id: usize,
prop_id: usize,
at: EventTime,
) -> Option<Prop> {
if at == edge_time {
self.temporal_edge_prop_exploded(e, view, prop_id, edge_time, layer_id)
} else {
None
}
}
fn temporal_edge_prop_exploded_last_at_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
edge_time: EventTime,
layer_id: usize,
prop_id: usize,
at: EventTime,
w: Range<EventTime>,
) -> Option<Prop> {
if edge_time == at && w.contains(&edge_time) {
self.temporal_edge_prop_exploded(e, view, prop_id, edge_time, layer_id)
} else {
None
}
}
fn temporal_edge_prop_last_at<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
prop_id: usize,
t: EventTime,
) -> Option<Prop> {
e.filtered_temporal_prop_iter(prop_id, &view, view.layer_ids())
.filter_map(|(_, prop)| prop.last_before(t.next()))
.max_by(|(t1, _), (t2, _)| t1.cmp(t2))
.map(|(_, v)| v)
}
fn temporal_edge_prop_last_at_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
prop_id: usize,
t: EventTime,
w: Range<EventTime>,
) -> Option<Prop> {
if w.contains(&t) {
e.filtered_temporal_prop_iter(prop_id, &view, view.layer_ids())
.filter_map(|(_, prop)| prop.last_before(t.next()).filter(|(t, _)| w.contains(&t)))
.max_by(|(t1, _), (t2, _)| t1.cmp(t2))
.map(|(_, v)| v)
} else {
None
}
}
fn temporal_edge_prop_hist<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
prop_id: usize,
) -> impl Iterator<Item = (EventTime, usize, Prop)> + Send + Sync + 'graph {
e.filtered_temporal_prop_iter(prop_id, view, layer_ids)
.map(|(layer_id, prop)| prop.iter().map(move |(t, v)| (t, layer_id, v)))
.kmerge_by(|(t1, _, _), (t2, _, _)| t1 <= t2)
}
fn temporal_edge_prop_hist_rev<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
prop_id: usize,
) -> impl Iterator<Item = (EventTime, usize, Prop)> + Send + Sync + 'graph {
e.filtered_temporal_prop_iter(prop_id, view, layer_ids)
.map(|(layer_id, prop)| prop.iter().rev().map(move |(t, v)| (t, layer_id, v)))
.kmerge_by(|(t1, _, _), (t2, _, _)| t1 >= t2)
}
fn temporal_edge_prop_hist_window<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
prop_id: usize,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, usize, Prop)> + Send + Sync + 'graph {
e.filtered_temporal_prop_iter(prop_id, view, layer_ids)
.map(move |(layer_id, prop)| {
prop.iter_window(w.clone())
.map(move |(t, v)| (t, layer_id, v))
})
.kmerge_by(|(t1, _, _), (t2, _, _)| t1 <= t2)
}
fn temporal_edge_prop_hist_window_rev<'graph, G: GraphView + 'graph>(
self,
e: EdgeStorageRef<'graph>,
view: G,
layer_ids: &'graph LayerIds,
prop_id: usize,
w: Range<EventTime>,
) -> impl Iterator<Item = (EventTime, usize, Prop)> + Send + Sync + 'graph {
e.filtered_temporal_prop_iter(prop_id, view, layer_ids)
.map(move |(layer_id, prop)| {
prop.iter_window(w.clone())
.rev()
.map(move |(t, v)| (t, layer_id, v))
})
.kmerge_by(|(t1, _, _), (t2, _, _)| t1 >= t2)
}
fn edge_metadata<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef,
view: G,
prop_id: usize,
) -> Option<Prop> {
let layer_filter = |layer| {
view.internal_filter_edge_layer(e, layer)
&& !e.filtered_additions(layer, &view).is_empty()
};
e.filtered_edge_metadata(&view, prop_id, layer_filter)
}
fn edge_metadata_window<'graph, G: GraphView + 'graph>(
&self,
e: EdgeStorageRef<'graph>,
view: G,
prop_id: usize,
w: Range<EventTime>,
) -> Option<Prop> {
let layer_filter = |layer| {
!e.filtered_additions(layer, &view)
.range(w.clone())
.is_empty()
};
e.filtered_edge_metadata(&view, prop_id, layer_filter)
}
}