What
Move the graph-related methods of GraphTimeSemanticsOps — earliest_time_global,
latest_time_global, their _window variants, has_temporal_prop(_window),
temporal_prop_iter(_window, _window_rev), temporal_prop_last_at(_window) — onto a new
trait implemented for TimeSemantics, the way NodeTimeSemanticsOps and EdgeTimeSemanticsOps
already are. A view then exposes graph_time_semantics() and delegates, instead of every view
type implementing the eleven methods against its own notion of a window. view_start,
view_end and window_filtered come along for free: they are the range set's start(),
end() and "is not everything".
With that in place, AndFilteredGraph, OrFilteredGraph and NotFilteredGraph hold the
TimeSemantics their expression resolved to, and implement GraphTimeSemanticsOps from it.
Why
Three view types — WindowedGraph, MultiWindowedGraph, and the combinator graphs — each
answer the same questions by consulting a window they hold. That is the same code three times
with three chances to diverge, and it is the reason the combinators had to return
DynGraphArc: filter(V1 & V2) produces the composed view when the expression is views only
and an AndFilteredGraph otherwise, and the view arm picks between a WindowedGraph, a
MultiWindowedGraph and a LayeredGraph from the number of ranges. No single associated type
covers that, so the combinators type-erase. A graph that carries the resolved TimeSemantics
needs no dyn to pick between the graphs that value could have become — it is all of them.
Doing this also lets the _window methods skip ranges that cannot contain the input time
(binary search over the sorted range set, rather than clipping the whole set), which is the
optimisation asked for alongside.
Also here: per-layer time semantics
A union or complement that restricts time on one axis and layers on the other has no single
(time, layers) pair and is refused today with an error naming the workaround. The
representation that would make it total is a list of rectangles, Vec<(TimeRanges, LayerIds)>
— closed under all three operators. It needs per-layer time semantics, which is blocked on one
semantic decision: node property updates live on the reserved static layer, so under
window(0,4) | layer("work") a node property update at t=6 would be dropped, while
layer("work") on its own keeps node property history. Whether a layer view restricts
layer-less events has to be decided before this can be built.
Sites that reference this issue
AndFilter, OrFilter, NotFilter — EntityFiltered = DynGraphArc
MultiWindowedGraph — the per-range graph-level methods (temporal_value_at,
temporal_prop_iter, earliest_time_global, …) that graph_time_semantics() would replace
ResolvedView::or / ResolvedView::not — the refusal
Refs #2774 (review threads on multi_window_graph.rs:232, or_filter.rs:65,
resolved_view.rs:80), #2718, #2728.
What
Move the graph-related methods of
GraphTimeSemanticsOps—earliest_time_global,latest_time_global, their_windowvariants,has_temporal_prop(_window),temporal_prop_iter(_window, _window_rev),temporal_prop_last_at(_window)— onto a newtrait implemented for
TimeSemantics, the wayNodeTimeSemanticsOpsandEdgeTimeSemanticsOpsalready are. A view then exposes
graph_time_semantics()and delegates, instead of every viewtype implementing the eleven methods against its own notion of a window.
view_start,view_endandwindow_filteredcome along for free: they are the range set'sstart(),end()and "is not everything".With that in place,
AndFilteredGraph,OrFilteredGraphandNotFilteredGraphhold theTimeSemanticstheir expression resolved to, and implementGraphTimeSemanticsOpsfrom it.Why
Three view types —
WindowedGraph,MultiWindowedGraph, and the combinator graphs — eachanswer the same questions by consulting a window they hold. That is the same code three times
with three chances to diverge, and it is the reason the combinators had to return
DynGraphArc:filter(V1 & V2)produces the composed view when the expression is views onlyand an
AndFilteredGraphotherwise, and the view arm picks between aWindowedGraph, aMultiWindowedGraphand aLayeredGraphfrom the number of ranges. No single associated typecovers that, so the combinators type-erase. A graph that carries the resolved
TimeSemanticsneeds no
dynto pick between the graphs that value could have become — it is all of them.Doing this also lets the
_windowmethods skip ranges that cannot contain the input time(binary search over the sorted range set, rather than clipping the whole set), which is the
optimisation asked for alongside.
Also here: per-layer time semantics
A union or complement that restricts time on one axis and layers on the other has no single
(time, layers)pair and is refused today with an error naming the workaround. Therepresentation that would make it total is a list of rectangles,
Vec<(TimeRanges, LayerIds)>— closed under all three operators. It needs per-layer time semantics, which is blocked on one
semantic decision: node property updates live on the reserved static layer, so under
window(0,4) | layer("work")a node property update att=6would be dropped, whilelayer("work")on its own keeps node property history. Whether a layer view restrictslayer-less events has to be decided before this can be built.
Sites that reference this issue
AndFilter,OrFilter,NotFilter—EntityFiltered = DynGraphArcMultiWindowedGraph— the per-range graph-level methods (temporal_value_at,temporal_prop_iter,earliest_time_global, …) thatgraph_time_semantics()would replaceResolvedView::or/ResolvedView::not— the refusalRefs #2774 (review threads on
multi_window_graph.rs:232,or_filter.rs:65,resolved_view.rs:80), #2718, #2728.