1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use phf::phf_map;

use crate::{serialize::CompactGraph, Graph};

/// Datasets as raw JSON encoded CompactGraphs.
const DATASETS_JSON: phf::Map<&'static str, &'static str> = phf_map! {
    "aircraft_engine" => include_str!("./aircraft_engine.json"),
    "architecture_integral" => include_str!("./architecture_integral.json"),
    "architecture_mix" => include_str!("./architecture_mix.json"),
    "architecture_modular" => include_str!("./architecture_modular.json"),
    "climate_control_mg" => include_str!("./climate_control_mg.json"),
    "climate_control" => include_str!("./climate_control.json"),
    "compatibility" => include_str!("./compatibility.json"),
    "design" => include_str!("./design.json"),
    "eefde_lock" => include_str!("./eefde_lock.json"),
    "elevator45" => include_str!("./elevator45.json"),
    "elevator175" => include_str!("./elevator175.json"),
    "ford_hood" => include_str!("./ford_hood.json"),
    "kodak3d" => include_str!("./kodak3d.json"),
    "ledsip" => include_str!("./ledsip.json"),
    "localbus" => include_str!("./localbus.json"),
    "overlap" => include_str!("./overlap.json"),
    "pathfinder" => include_str!("./pathfinder.json"),
    "shaja8" => include_str!("./shaja8.json"),
    "similarity" => include_str!("./similarity.json"),
    "tarjans8" => include_str!("./tarjans8.json"),
    "ucav" => include_str!("./ucav.json"),
};

/// Enumerate all available datasets.
pub fn enumerate_datasets() -> Vec<&'static str> {
    let mut keys: Vec<&'static str> = DATASETS_JSON.keys().copied().collect();
    keys.sort();
    keys
}

/// Get a dataset as the CompactGraph it is encoded as.
fn get_compact(key: &str) -> Option<CompactGraph> {
    DATASETS_JSON
        .get(key)
        .map(|&contents| serde_json::from_str(contents).expect("a correctly encoded dataset"))
}

/// Get a dataset as a Graph instance.
pub fn get_dataset(key: &str) -> Option<Graph> {
    get_compact(key).and_then(|c| c.try_into().ok())
}

/// Get the info regarding a dataset.
pub fn get_dataset_info(key: &str) -> Option<String> {
    get_compact(key).map(|c| {
        serde_json::to_string_pretty(
            &c.metadata
                .annotations
                .get(&"info".to_string())
                .expect("any dataset info"),
        )
        .expect("valid dataset info")
    })
}

#[cfg(test)]
mod tests {
    use std::collections::{HashMap, HashSet};

    use crate::{EdgeStore, HasNodeStore, NodeStore};

    #[allow(unused_imports)]
    use super::*;
    use anyhow::Result;
    #[allow(unused_imports)]
    use pretty_assertions::{assert_eq, assert_ne, assert_str_eq};

    #[test]
    fn test_dataset_keys() {
        assert!(
            DATASETS_JSON.contains_key("aircraft_engine"),
            "definitely should have this"
        );
        assert_eq!(DATASETS_JSON.len(), 21);
    }

    #[test]
    fn test_dataset_graphs() {
        for key in enumerate_datasets() {
            assert!(get_compact(key).is_some());
            assert!(get_dataset_info(key).is_some());
            let graph = get_dataset(key).unwrap_or_else(|| panic!("a valid graph for {}", key));
            for &node in graph.all_nodes().iter() {
                graph.check_node(node).expect("valid node");
            }
            for &edge in graph.all_edges().iter() {
                graph
                    .check_edge(edge, graph.node_store())
                    .expect("valid edge");
            }
        }
    }

    #[test]
    fn test_ucav_contents() {
        let mut g = get_dataset("ucav").expect("valid graph");
        let node_agg = g.node_aggregate();
        assert_eq!(node_agg.kinds, HashMap::from([("node".to_string(), 14)]));
        assert_eq!(
            node_agg.labels,
            HashMap::from([("default".to_string(), 14)])
        );
        let weight_keys = node_agg
            .weights
            .keys()
            .map(|x| x.to_owned())
            .collect::<HashSet<String>>();
        let reference_keys = HashSet::from([
            "min_cost".to_string(),
            "max_cost".to_string(),
            "mean_cost".to_string(),
            "min_duration".to_string(),
            "mean_duration".to_string(),
            "max_duration".to_string(),
            "improvement_curve".to_string(),
        ]);
        assert_eq!(weight_keys, reference_keys);
        assert_eq!(g.max_node_depth(), 0);
    }

    #[test]
    fn test_climate_control_mg() {
        let compact: CompactGraph = DATASETS_JSON
            .get("climate_control_mg")
            .map(|&contents| serde_json::from_str(contents).expect("a correctly encoded dataset"))
            .expect("valid compact graph");

        let mut graph: Result<Graph> = compact.try_into();
        match graph.as_mut() {
            Ok(graph) => assert_eq!(graph.max_node_depth(), 3),
            Err(err) => panic!("{:?}", err),
        }
    }
}