icentral_graph/
graph.rs

1crate::ix!();
2
3//-------------------------------------------[icentral/src/graph_t.cc]
4//-------------------------------------------[icentral/src/bcc_scratch.cc]
5
6/// TODO: remove this
7pub fn print_edgelist_and_mucs<GH>(graph: &Graph<GH>)  
8where Graph<GH>
9: GetEdgeListDebugger 
10+ Debug
11+ GetMucDebuggerWithoutNodes
12+ SetPrintNodes
13+ GetEdges
14+ SetMucDebug
15+ GetMucs<GH>,
16GH
17: ExtendWith<GH,Error=BetweennessCentralityError>
18+ Debug
19+ GetConnectedComponentSizes
20+ GetEdges
21+ GetNeighborsForNode
22+ GetNodeIdRange
23+ HasMapForNode
24+ InsertEdge
25+ InsertNode
26+ MappedNodes
27+ NumEdges
28+ NumNodes
29+ SetPrintNodes
30{
31    debug!("{:?}", graph.edgelist_debugger());
32    debug!("{:?}", graph.muc_debugger_without_nodes());
33}
34
35pub fn extract_graph_name(path: &str) -> String {
36    
37    let pos: usize = match path.rfind("/") { 
38        Some(x) => x + 1, 
39        None    => 0 
40    };
41
42    let length: usize = path.len() - pos + 1;
43
44    let name = path[pos .. pos + length - 1].to_string();
45
46    debug!("extracting graph_name {} from path {}", name, path);
47
48    name
49}
50
51/**
52  | Simple undirected unweighted graph
53  | data structure no checks whatsoever
54  | should call init_size(..) first then
55  | insert_edge(..) to populate
56  | 
57  | IMP: nodes have indexes from 0 to n-1
58  | 
59  | IMP: graph is assumed to be connected
60  |
61  */
62pub struct Graph<GH> {
63    pub(crate) nodes_map:       NeighborsMap,
64    pub(crate) nodes_to_mucs:   MucIdMap,
65    pub(crate) edges:           Edges,
66    pub(crate) mucs:            Vec<MinimumUnionCycle<GH>>,
67    pub(crate) mcb:             MinimumCycleBasis,
68    pub(crate) visit_markers:   VisitMarkers,
69    pub(crate) bc_computed:     bool,
70    pub(crate) scores:          BetweennessScores,
71    pub(crate) graph_name:      String,
72}
73
74impl<GH> NumNodes for Graph<GH> {
75
76    fn num_nodes(&self) -> usize {
77        self.nodes_map.len()
78    }
79}
80
81impl<GH> Graph<GH> 
82where GH: BccGraphHashInterface
83{
84    delegate_to_neighbors_map!{}
85    delegate_to_edges!{}
86
87    #[inline] pub fn debug_all(&self) -> bool {
88        true
89    }
90
91    pub fn adjacency_list_for_dachshund(&self) -> Vec<(usize,usize)> {
92        self.edges.adjacency_list_for_dachshund()
93    }
94}
95
96impl<GH> NodeIdToMucId for Graph<GH> 
97//where GH: BccGraphHashInterface
98{
99    fn nodeid_to_mucid(&self, idx: NodeId) -> MinimumUnionCycleId {
100        self.nodes_to_mucs.mucid_for_node(idx)
101    }
102}
103
104impl<GH> GetMuc<GH> for Graph<GH> {
105
106    fn muc(&self, idx: MinimumUnionCycleId) -> &MinimumUnionCycle<GH> {
107        &self.mucs[idx.val()]
108    }
109
110    fn muc_mut(&mut self, idx: MinimumUnionCycleId) -> &mut MinimumUnionCycle<GH> {
111        &mut self.mucs[idx.val()]
112    }
113}
114
115impl<GH> SetGraphName for Graph<GH> {
116
117    fn set_graph_name(&mut self, name: &str) {
118
119        debug!("setting graph_name to {}", name);
120
121        self.graph_name = name.to_string();
122    }
123}
124
125impl<GH> GetEdges for Graph<GH> {
126
127    fn edges(&self) -> &Edges {
128        &self.edges
129    }
130}
131
132impl<GH> HasEdge for Graph<GH> {
133
134    fn has_edge(&self, e: &Edge) -> bool {
135        self.edges.has_edge(e)
136    }
137}
138
139impl<GH> NumEdges for Graph<GH> {
140
141    fn num_edges(&self) -> usize {
142        self.edges.len()
143    }
144}
145
146impl<GH> Named for Graph<GH> {
147
148    fn name(&self) -> Cow<'_,str> {
149        Cow::Borrowed(&self.graph_name)
150    }
151}
152
153impl<GH> CreateNamedEmpty for Graph<GH> {
154
155    fn empty(name: &str) -> Self {
156
157        debug!("creating new empty graph named {}", name);
158
159        let nodes_map_name     = name![name, "nodes_map"];
160        let edges_name         = name![name, "edges"];
161        let visit_markers_name = name![name, "visit_markers"];
162        let scores_name        = name![name, "scores"];
163        let nodes_to_mucs_name = name![name, "nodes_to_mucs"];
164
165        Self {
166            nodes_map:       NeighborsMap::empty_mapped(nodes_map_name),
167            nodes_to_mucs:   MucIdMap::empty_mapped(nodes_to_mucs_name),
168            edges:           Edges::empty(edges_name),
169            mucs:            vec![],
170            mcb:             MinimumCycleBasis::empty(),
171            visit_markers:   VisitMarkers::empty_mapped(visit_markers_name),
172            bc_computed:     false,
173            scores:          BetweennessScores::empty_mapped(scores_name),
174            graph_name:      name.to_string(),
175        }
176    }
177}
178
179impl<GH> GetNodesToMucs for Graph<GH> {
180
181    fn get_nodes_to_mucs<'a>(&'a self) -> &'a MucIdMap {
182        &self.nodes_to_mucs
183    }
184}
185
186impl<GH> GetMucs<GH> for Graph<GH> {
187
188    fn get_mucs<'a>(&'a self) -> &Vec<MinimumUnionCycle<GH>> {
189        &self.mucs
190    }
191}
192
193impl<GH> fmt::Debug for Graph<GH> 
194where GH: BccGraphHashInterface 
195{
196    //TODO: how should we handle the unwrapping
197    //done here?
198    //
199    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200
201        let binding = f.debug_struct("Graph");
202
203        let mut builder = binding;
204
205        builder.field("graph_name",          &self.graph_name);
206        builder.field("nodes_map_len",       &self.nodes_map.len());
207        builder.field("nodes_to_mucs_len",   &self.nodes_to_mucs.len());
208        builder.field("edges_len",           &self.edges.len());
209        builder.field("visit_markers_len",   &self.visit_markers.len());
210
211        if self.debug_all() {
212            builder.field("nodes_map",       &self.nodes_map);
213            builder.field("nodes_to_mucs",   &self.nodes_to_mucs);
214            builder.field("edges",           &self.edges);
215            builder.field("visit_markers",   &self.visit_markers);
216        }
217
218        builder.field("mucs",                &self.mucs.len());
219        builder.field("mcb",                 &self.mcb);
220        builder.field("bc_computed",         &self.bc_computed);
221        builder.field("scores",              &self.scores.len());
222        builder.field("scores",              &self.scores.len());;
223
224        builder.finish_non_exhaustive()
225    }
226}
227
228impl<GH> From<GraphMock> for Graph<GH> {
229
230    fn from(mock: GraphMock) -> Self {
231
232        debug!("creating Graph from mock: {:?}", mock);
233
234        let name = mock.name();
235
236        let mut g = Graph::empty(&name);
237
238        mock.fill(&mut g);
239
240        g
241    }
242}
243
244impl<GH> VisitMarkersHandle for Graph<GH> {
245
246    fn visit_markers_handle(&mut self) -> &mut VisitMarkers {
247        &mut self.visit_markers
248    }
249}