MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / compute_statistics

Method compute_statistics

nodedb-graph/src/csr/statistics.rs:68–157  ·  view source on GitHub ↗

Compute full graph statistics from the current CSR state. O(V + E) — iterates all nodes and edges once. Intended for query planning, not hot-path execution. # Errors Returns [`GraphError::MemoryBudget`] if a memory governor is installed and the degree-array working set would exceed the `Graph` engine budget.

(&self)

Source from the content-addressed store, hash-verified

66 /// Returns [`GraphError::MemoryBudget`] if a memory governor is installed
67 /// and the degree-array working set would exceed the `Graph` engine budget.
68 pub fn compute_statistics(&self) -> Result<GraphStatistics, GraphError> {
69 let n = self.node_count();
70 if n == 0 {
71 return Ok(GraphStatistics {
72 node_count: 0,
73 edge_count: 0,
74 label_count: 0,
75 label_stats: HashMap::new(),
76 out_degree_histogram: DegreeHistogram {
77 min: 0,
78 max: 0,
79 avg: 0.0,
80 p50: 0,
81 p95: 0,
82 p99: 0,
83 },
84 in_degree_histogram: DegreeHistogram {
85 min: 0,
86 max: 0,
87 avg: 0.0,
88 p50: 0,
89 p95: 0,
90 p99: 0,
91 },
92 });
93 }
94
95 // Reserve memory for the two degree-distribution scratch arrays.
96 let degree_bytes = 2 * n * size_of::<usize>();
97 let _degree_guard = self
98 .governor
99 .as_ref()
100 .map(|g| g.reserve(EngineId::Graph, degree_bytes))
101 .transpose()?;
102
103 // Per-label counters.
104 let mut label_edge_count: HashMap<u32, usize> = HashMap::new();
105 let mut label_sources: HashMap<u32, std::collections::HashSet<u32>> = HashMap::new();
106 let mut label_targets: HashMap<u32, std::collections::HashSet<u32>> = HashMap::new();
107
108 // Degree arrays.
109 let mut out_degrees: Vec<usize> = Vec::with_capacity(n);
110 let mut in_degrees: Vec<usize> = Vec::with_capacity(n);
111
112 let mut total_edges = 0usize;
113
114 for node in 0..n {
115 let node_id = node as u32;
116 let mut out_deg = 0usize;
117 let mut in_deg = 0usize;
118
119 for (lid, dst) in self.dense_iter_out(node_id) {
120 out_deg += 1;
121 total_edges += 1;
122 *label_edge_count.entry(lid).or_insert(0) += 1;
123 label_sources.entry(lid).or_default().insert(node_id);
124 label_targets.entry(lid).or_default().insert(dst);
125 }

Callers 5

statistics_empty_graphFunction · 0.80
statistics_basicFunction · 0.80
degree_histogram_valuesFunction · 0.80

Calls 13

compute_histogramFunction · 0.85
dense_iter_outMethod · 0.80
entryMethod · 0.80
dense_iter_inMethod · 0.80
to_stringMethod · 0.80
node_countMethod · 0.45
as_refMethod · 0.45
reserveMethod · 0.45
insertMethod · 0.45
pushMethod · 0.45
label_nameMethod · 0.45
getMethod · 0.45

Tested by 5

statistics_empty_graphFunction · 0.64
statistics_basicFunction · 0.64
degree_histogram_valuesFunction · 0.64