acl: use BTreeMap and BTreeSet to avoid sort()
This commit is contained in:
parent
0815ec7e65
commit
a83eab3c4d
@ -1,5 +1,5 @@
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet, BTreeMap, BTreeSet};
|
||||||
use std::path::{PathBuf, Path};
|
use std::path::{PathBuf, Path};
|
||||||
|
|
||||||
use failure::*;
|
use failure::*;
|
||||||
@ -70,7 +70,7 @@ pub struct AclTree {
|
|||||||
struct AclTreeNode {
|
struct AclTreeNode {
|
||||||
users: HashMap<String, HashMap<String, bool>>,
|
users: HashMap<String, HashMap<String, bool>>,
|
||||||
groups: HashMap<String, HashMap<String, bool>>,
|
groups: HashMap<String, HashMap<String, bool>>,
|
||||||
children: HashMap<String, AclTreeNode>,
|
children: BTreeMap<String, AclTreeNode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AclTreeNode {
|
impl AclTreeNode {
|
||||||
@ -79,7 +79,7 @@ impl AclTreeNode {
|
|||||||
Self {
|
Self {
|
||||||
users: HashMap::new(),
|
users: HashMap::new(),
|
||||||
groups: HashMap::new(),
|
groups: HashMap::new(),
|
||||||
children: HashMap::new(),
|
children: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,10 +197,10 @@ impl AclTree {
|
|||||||
let role = role.as_str();
|
let role = role.as_str();
|
||||||
let user = user.to_string();
|
let user = user.to_string();
|
||||||
if *propagate {
|
if *propagate {
|
||||||
role_ug_map1.entry(role).or_insert_with(|| HashSet::new())
|
role_ug_map1.entry(role).or_insert_with(|| BTreeSet::new())
|
||||||
.insert(user);
|
.insert(user);
|
||||||
} else {
|
} else {
|
||||||
role_ug_map0.entry(role).or_insert_with(|| HashSet::new())
|
role_ug_map0.entry(role).or_insert_with(|| BTreeSet::new())
|
||||||
.insert(user);
|
.insert(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,60 +210,53 @@ impl AclTree {
|
|||||||
for (role, propagate) in roles {
|
for (role, propagate) in roles {
|
||||||
let group = format!("@{}", group);
|
let group = format!("@{}", group);
|
||||||
if *propagate {
|
if *propagate {
|
||||||
role_ug_map1.entry(role).or_insert_with(|| HashSet::new())
|
role_ug_map1.entry(role).or_insert_with(|| BTreeSet::new())
|
||||||
.insert(group);
|
.insert(group);
|
||||||
} else {
|
} else {
|
||||||
role_ug_map0.entry(role).or_insert_with(|| HashSet::new())
|
role_ug_map0.entry(role).or_insert_with(|| BTreeSet::new())
|
||||||
.insert(group);
|
.insert(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn group_by_property_list(
|
fn group_by_property_list(
|
||||||
item_property_map: &HashMap<&str, HashSet<String>>,
|
item_property_map: &HashMap<&str, BTreeSet<String>>,
|
||||||
) -> HashMap<String, HashSet<String>> {
|
) -> BTreeMap<String, BTreeSet<String>> {
|
||||||
let mut result_map = HashMap::new();
|
let mut result_map = BTreeMap::new();
|
||||||
for (item, property_map) in item_property_map {
|
for (item, property_map) in item_property_map {
|
||||||
let mut item_list = property_map.iter().map(|v| v.as_str())
|
let item_list = property_map.iter().fold(String::new(), |mut acc, v| {
|
||||||
.collect::<Vec<&str>>();
|
if !acc.is_empty() { acc.push(','); }
|
||||||
item_list.sort();
|
acc.push_str(v);
|
||||||
let item_list = item_list.join(",");
|
acc
|
||||||
result_map.entry(item_list).or_insert_with(|| HashSet::new())
|
});
|
||||||
|
result_map.entry(item_list).or_insert_with(|| BTreeSet::new())
|
||||||
.insert(item.to_string());
|
.insert(item.to_string());
|
||||||
}
|
}
|
||||||
result_map
|
result_map
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut uglist_role_map0 = group_by_property_list(&role_ug_map0)
|
let uglist_role_map0 = group_by_property_list(&role_ug_map0);
|
||||||
.into_iter()
|
let uglist_role_map1 = group_by_property_list(&role_ug_map1);
|
||||||
.collect::<Vec<(String, HashSet<String>)>>();
|
|
||||||
uglist_role_map0.sort_unstable_by(|a,b| a.0.cmp(&b.0));
|
|
||||||
|
|
||||||
let mut uglist_role_map1 = group_by_property_list(&role_ug_map1)
|
|
||||||
.into_iter()
|
|
||||||
.collect::<Vec<(String, HashSet<String>)>>();
|
|
||||||
uglist_role_map1.sort_unstable_by(|a,b| a.0.cmp(&b.0));
|
|
||||||
|
|
||||||
|
|
||||||
for (uglist, roles) in uglist_role_map0 {
|
for (uglist, roles) in uglist_role_map0 {
|
||||||
let mut role_list = roles.iter().map(|v| v.as_str())
|
let role_list = roles.iter().fold(String::new(), |mut acc, v| {
|
||||||
.collect::<Vec<&str>>();
|
if !acc.is_empty() { acc.push(','); }
|
||||||
role_list.sort();
|
acc.push_str(v);
|
||||||
writeln!(w, "acl:0:{}:{}:{}", path, uglist, role_list.join(","))?;
|
acc
|
||||||
|
});
|
||||||
|
writeln!(w, "acl:0:{}:{}:{}", path, uglist, role_list)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uglist, roles) in uglist_role_map1 {
|
for (uglist, roles) in uglist_role_map1 {
|
||||||
let mut role_list = roles.iter().map(|v| v.as_str())
|
let role_list = roles.iter().fold(String::new(), |mut acc, v| {
|
||||||
.collect::<Vec<&str>>();
|
if !acc.is_empty() { acc.push(','); }
|
||||||
role_list.sort();
|
acc.push_str(v);
|
||||||
writeln!(w, "acl:1:{}:{}:{}", path, uglist, role_list.join(","))?;
|
acc
|
||||||
|
});
|
||||||
|
writeln!(w, "acl:1:{}:{}:{}", path, uglist, role_list)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut child_names = node.children.keys().map(|v| v.as_str()).collect::<Vec<&str>>();
|
for (name, child) in node.children.iter() {
|
||||||
child_names.sort();
|
|
||||||
|
|
||||||
for name in child_names {
|
|
||||||
let child = node.children.get(name).unwrap();
|
|
||||||
let child_path = format!("{}/{}", path, name);
|
let child_path = format!("{}/{}", path, name);
|
||||||
Self::write_node_config(child, &child_path, w)?;
|
Self::write_node_config(child, &child_path, w)?;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user