VeloGraphX
High-performance dynamic graph analytics in C++20
Loading...
Searching...
No Matches
temporal_graph.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <algorithm>
6#include <cstdint>
7#include <optional>
8#include <stdexcept>
9#include <utility>
10#include <vector>
11
12namespace velographx {
13
15 std::uint64_t version{};
16 std::uint64_t min_timestamp{};
17 std::uint64_t max_timestamp{};
19};
20
22 public:
23 explicit TemporalGraph(std::size_t vertices = 0, bool directed = false)
24 : initial_vertices_(vertices), directed_(directed), graph_(vertices, directed) {}
25
26 [[nodiscard]] const DynamicGraph& graph() const noexcept { return graph_; }
27 [[nodiscard]] std::uint64_t version() const noexcept { return graph_.version(); }
28 [[nodiscard]] const std::vector<VersionedUpdateBatch>& history() const noexcept { return history_; }
29
30 void apply(const UpdateBatch& batch) {
31 if (batch.empty()) return;
32 std::uint64_t min_ts = batch.updates.front().timestamp;
33 std::uint64_t max_ts = batch.updates.front().timestamp;
34 for (const auto& update : batch.updates) {
35 min_ts = std::min(min_ts, update.timestamp);
36 max_ts = std::max(max_ts, update.timestamp);
37 }
38 graph_.apply(batch);
39 history_.push_back({graph_.version(), min_ts, max_ts, batch});
40 }
41
42 [[nodiscard]] DynamicGraph snapshot_version(std::uint64_t version) const {
43 if (version > graph_.version()) throw std::out_of_range("requested version is in the future");
44 DynamicGraph snapshot(initial_vertices_, directed_);
45 for (const auto& entry : history_) {
46 if (entry.version > version) break;
47 snapshot.apply(entry.batch);
48 }
49 return snapshot;
50 }
51
52 [[nodiscard]] DynamicGraph snapshot_time(std::uint64_t timestamp) const {
53 DynamicGraph snapshot(initial_vertices_, directed_);
54 for (const auto& entry : history_) {
55 UpdateBatch filtered;
56 for (const auto& update : entry.batch.updates) {
57 if (update.timestamp <= timestamp) filtered.updates.push_back(update);
58 }
59 if (!filtered.empty()) snapshot.apply(filtered);
60 }
61 return snapshot;
62 }
63
64 [[nodiscard]] std::vector<EdgeUpdate> changes_between_versions(std::uint64_t from_exclusive,
65 std::uint64_t to_inclusive) const {
66 if (from_exclusive > to_inclusive || to_inclusive > graph_.version())
67 throw std::out_of_range("invalid version range");
68 std::vector<EdgeUpdate> out;
69 for (const auto& entry : history_) {
70 if (entry.version <= from_exclusive) continue;
71 if (entry.version > to_inclusive) break;
72 out.insert(out.end(), entry.batch.updates.begin(), entry.batch.updates.end());
73 }
74 return out;
75 }
76
77 [[nodiscard]] std::vector<EdgeUpdate> changes_between_times(std::uint64_t from_exclusive,
78 std::uint64_t to_inclusive) const {
79 if (from_exclusive > to_inclusive) throw std::out_of_range("invalid timestamp range");
80 std::vector<EdgeUpdate> out;
81 for (const auto& entry : history_) {
82 if (entry.max_timestamp <= from_exclusive || entry.min_timestamp > to_inclusive) continue;
83 for (const auto& update : entry.batch.updates) {
84 if (update.timestamp > from_exclusive && update.timestamp <= to_inclusive) out.push_back(update);
85 }
86 }
87 return out;
88 }
89
90 [[nodiscard]] DynamicGraph sliding_window(std::uint64_t end_timestamp,
91 std::uint64_t window_width) const {
92 const auto begin = end_timestamp > window_width ? end_timestamp - window_width : 0;
93 DynamicGraph window(initial_vertices_, directed_);
94 for (const auto& entry : history_) {
95 UpdateBatch filtered;
96 for (const auto& update : entry.batch.updates) {
97 if (update.timestamp > begin && update.timestamp <= end_timestamp) filtered.updates.push_back(update);
98 }
99 if (!filtered.empty()) window.apply(filtered);
100 }
101 return window;
102 }
103
104 private:
105 std::size_t initial_vertices_{0};
106 bool directed_{false};
107 DynamicGraph graph_;
108 std::vector<VersionedUpdateBatch> history_;
109};
110
111} // namespace velographx
std::uint64_t version() const noexcept
void apply(const UpdateBatch &batch)
const std::vector< VersionedUpdateBatch > & history() const noexcept
std::vector< EdgeUpdate > changes_between_versions(std::uint64_t from_exclusive, std::uint64_t to_inclusive) const
std::uint64_t version() const noexcept
DynamicGraph sliding_window(std::uint64_t end_timestamp, std::uint64_t window_width) const
DynamicGraph snapshot_time(std::uint64_t timestamp) const
TemporalGraph(std::size_t vertices=0, bool directed=false)
DynamicGraph snapshot_version(std::uint64_t version) const
std::vector< EdgeUpdate > changes_between_times(std::uint64_t from_exclusive, std::uint64_t to_inclusive) const
const DynamicGraph & graph() const noexcept
void apply(const UpdateBatch &batch)
bool empty() const noexcept
std::vector< EdgeUpdate > updates