graphmind_graph_algorithms/
common.rs1use std::collections::HashMap;
6
7pub type NodeId = u64;
9
10pub struct GraphView {
12 pub node_count: usize,
14 pub index_to_node: Vec<NodeId>,
16 pub node_to_index: HashMap<NodeId, usize>,
18
19 pub out_offsets: Vec<usize>,
22 pub out_targets: Vec<usize>,
24
25 pub in_offsets: Vec<usize>,
28 pub in_sources: Vec<usize>,
30
31 pub weights: Option<Vec<f64>>,
33}
34
35impl GraphView {
36 pub fn out_degree(&self, idx: usize) -> usize {
38 self.out_offsets[idx + 1] - self.out_offsets[idx]
39 }
40
41 pub fn in_degree(&self, idx: usize) -> usize {
43 self.in_offsets[idx + 1] - self.in_offsets[idx]
44 }
45
46 pub fn successors(&self, idx: usize) -> &[usize] {
48 let start = self.out_offsets[idx];
49 let end = self.out_offsets[idx + 1];
50 &self.out_targets[start..end]
51 }
52
53 pub fn predecessors(&self, idx: usize) -> &[usize] {
55 let start = self.in_offsets[idx];
56 let end = self.in_offsets[idx + 1];
57 &self.in_sources[start..end]
58 }
59
60 pub fn weights(&self, idx: usize) -> Option<&[f64]> {
62 self.weights.as_ref().map(|w| {
63 let start = self.out_offsets[idx];
64 let end = self.out_offsets[idx + 1];
65 &w[start..end]
66 })
67 }
68
69 pub fn from_adjacency_list(
71 node_count: usize,
72 index_to_node: Vec<NodeId>,
73 node_to_index: HashMap<NodeId, usize>,
74 outgoing: Vec<Vec<usize>>,
75 incoming: Vec<Vec<usize>>,
76 weights: Option<Vec<Vec<f64>>>,
77 ) -> Self {
78 let mut out_offsets = Vec::with_capacity(node_count + 1);
79 let mut out_targets = Vec::new();
80 let mut in_offsets = Vec::with_capacity(node_count + 1);
81 let mut in_sources = Vec::new();
82 let mut flat_weights = if weights.is_some() {
83 Some(Vec::new())
84 } else {
85 None
86 };
87
88 out_offsets.push(0);
89 for (i, neighbors) in outgoing.into_iter().enumerate() {
90 out_targets.extend(neighbors);
91 out_offsets.push(out_targets.len());
92
93 if let Some(ref mut w_flat) = flat_weights {
94 if let Some(w_row) = weights.as_ref().map(|w| &w[i]) {
95 w_flat.extend(w_row.iter());
96 }
97 }
98 }
99
100 in_offsets.push(0);
101 for sources in incoming {
102 in_sources.extend(sources);
103 in_offsets.push(in_sources.len());
104 }
105
106 GraphView {
107 node_count,
108 index_to_node,
109 node_to_index,
110 out_offsets,
111 out_targets,
112 in_offsets,
113 in_sources,
114 weights: flat_weights,
115 }
116 }
117}