use hashbrown::HashMap;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ConnectionEquivalenceClass {
pub representative: String,
pub schemas: Vec<String>,
pub connection_count: usize,
}
pub fn group_by_hash(
schemas: &[(String, usize, u64)],
) -> (Vec<ConnectionEquivalenceClass>, Vec<usize>) {
let mut key_to_class: HashMap<(usize, u64), usize> = HashMap::new();
let mut classes: Vec<ConnectionEquivalenceClass> = Vec::new();
for (display, support, hash) in schemas {
match key_to_class.get(&(*support, *hash)) {
Some(&ci) => {
let class = &mut classes[ci];
if display.len() < class.representative.len() {
class.representative = display.clone();
}
class.schemas.push(display.clone());
}
None => {
key_to_class.insert((*support, *hash), classes.len());
classes.push(ConnectionEquivalenceClass {
representative: display.clone(),
schemas: vec![display.clone()],
connection_count: *support,
});
}
}
}
let mut order: Vec<usize> = (0..classes.len()).collect();
order.sort_by(|&a, &b| classes[a].representative.cmp(&classes[b].representative));
let mut remap = vec![0usize; classes.len()];
for (new_idx, &old_idx) in order.iter().enumerate() {
remap[old_idx] = new_idx;
}
let sorted: Vec<ConnectionEquivalenceClass> =
order.into_iter().map(|old| classes[old].clone()).collect();
let class_of: Vec<usize> = schemas
.iter()
.map(|(_, support, hash)| remap[key_to_class[&(*support, *hash)]])
.collect();
(sorted, class_of)
}