28 std::size_t directed_edges,
29 double latency_ratio = 1.25) noexcept {
30 constexpr std::size_t kLargeGraphDirectedArcs = 100'000'000;
31 return {directed_edges >= kLargeGraphDirectedArcs ? 1.50 : 1.25,
44 std::size_t current_storage_bytes,
45 std::size_t canonical_storage_bytes,
46 double current_neighbor_latency,
47 double canonical_neighbor_latency,
49 const auto storage_ratio = canonical_storage_bytes == 0
51 :
static_cast<double>(current_storage_bytes) /
52 static_cast<double>(canonical_storage_bytes);
53 const auto latency_ratio = canonical_neighbor_latency <= 0.0
55 : current_neighbor_latency / canonical_neighbor_latency;
56 const bool storage_exceeded = storage_ratio >= policy.max_storage_growth_ratio;
57 const bool latency_exceeded = latency_ratio >= policy.max_neighbor_latency_ratio;
58 return {storage_ratio, latency_ratio, storage_exceeded, latency_exceeded,
59 storage_exceeded || latency_exceeded};
79 if (signal.storage_limit_exceeded) {
80 latency_breach_streak_ = 0;
84 const bool cooldown_complete = last_consolidation_epoch_ == 0 ||
86 if (!cooldown_complete) {
91 latency_breach_streak_ = 0;
95 const bool meaningful_patch_growth =
97 if (signal.latency_limit_exceeded && meaningful_patch_growth) {
98 ++latency_breach_streak_;
100 latency_breach_streak_ = 0;
103 return signal.latency_limit_exceeded && meaningful_patch_growth &&
108 last_consolidation_epoch_ = epoch;
109 latency_breach_streak_ = 0;
117 std::size_t latency_breach_streak_{0};
118 std::size_t last_consolidation_epoch_{0};
133 std::vector<std::pair<VertexId, VertexId>> edges;
137 const bool compact_source = source.
is_compact();
138 for (std::size_t u = 0; u < source.
vertex_count(); ++u) {
139 const auto vertex =
static_cast<VertexId>(u);
140 if (compact_source) {
142 for (
const auto v : row) {
143 if (source.
directed() || u < static_cast<std::size_t>(v)) {
144 edges.emplace_back(vertex, v);
148 const auto row = source.
neighbors(vertex);
149 for (
const auto v : row) {
150 if (source.
directed() || u < static_cast<std::size_t>(v)) {
151 edges.emplace_back(vertex, v);
160 const auto consolidated_bytes = consolidated.
storage_bytes();
162 return {std::move(consolidated), source_bytes, consolidated_bytes, directed_edges};
void mark_consolidated(std::size_t epoch) noexcept
std::size_t latency_breach_streak() const noexcept
ConsolidationController(ConsolidationControllerConfig config={})
bool observe(const ConsolidationSignal &signal, std::size_t epoch) noexcept
std::size_t last_consolidation_epoch() const noexcept
bool directed() const noexcept
std::size_t storage_bytes() const noexcept
bool is_compact() const noexcept
std::size_t edge_count_directed() const noexcept
std::span< const VertexId > compact_neighbors(VertexId u) const noexcept
std::vector< VertexId > neighbors(VertexId u) const
void bulk_load_edges(const std::vector< std::pair< VertexId, VertexId > > &edges)
std::size_t vertex_count() const noexcept
ConsolidationSnapshot consolidate_to_csr_snapshot(const DynamicGraph &source)
ConsolidationSignal evaluate_consolidation(std::size_t current_storage_bytes, std::size_t canonical_storage_bytes, double current_neighbor_latency, double canonical_neighbor_latency, ConsolidationPolicy policy={}) noexcept
ConsolidationPolicy scale_aware_consolidation_policy(std::size_t directed_edges, double latency_ratio=1.25) noexcept
std::size_t min_epochs_between_consolidations
double min_storage_growth_for_latency_trigger
std::size_t latency_breach_samples
double max_neighbor_latency_ratio
double max_storage_growth_ratio
double neighbor_latency_ratio
double storage_growth_ratio
bool storage_limit_exceeded
bool latency_limit_exceeded
std::size_t consolidated_storage_bytes
std::size_t directed_edges
std::size_t source_storage_bytes