Skip to content

Instantly share code, notes, and snippets.

@divi255
Last active February 11, 2024 03:56
Show Gist options
  • Save divi255/ab9e54dc40261187dbcb7805a34b8253 to your computer and use it in GitHub Desktop.
Save divi255/ab9e54dc40261187dbcb7805a34b8253 to your computer and use it in GitHub Desktop.
tags to tree Rust
use std::collections::BTreeMap;
#[macro_use]
extern crate bma_benchmark;
// here Arc<String> is wanted to be used but for small depth Arc provides additional overhead and
// results are lower
#[derive(Default)]
struct Tree(BTreeMap<String, Tree>);
impl Tree {
fn to_vec(&self) -> Vec<String> {
fn combine_tags_recursive(tree: &Tree, prefix: &[String], tags: &mut Vec<String>) {
for (key, members) in &tree.0 {
if members.0.is_empty() {
let mut tag = prefix.join(".");
if !tag.is_empty() {
tag.push('.');
}
tag.push_str(key);
tags.push(tag);
} else {
let mut pfx = prefix.to_owned();
pfx.push(key.clone());
combine_tags_recursive(members, &pfx, tags);
}
}
}
let mut tags = vec![];
combine_tags_recursive(self, &[], &mut tags);
tags
}
}
impl<S> From<&[S]> for Tree
where
S: AsRef<str>,
{
fn from(tags: &[S]) -> Self {
fn fill_tree_recursive(tag: &str, tree: &mut Tree) {
let mut sp = tag.splitn(2, '.');
let parent = sp.next().unwrap();
if let Some(child) = sp.next() {
fill_tree_recursive(
child,
tree.0.entry(parent.to_owned()).or_insert(Tree::default()),
);
} else {
tree.0.insert(parent.to_owned(), Tree::default());
}
}
let mut tree = Tree::default();
for tag in tags {
fill_tree_recursive(tag.as_ref(), &mut tree);
}
tree
}
}
fn main() {
let n = 10;
let mut tags = Vec::with_capacity(100_000);
for a in 0..10 {
for b in 0..10 {
for c in 0..10 {
for d in 0..10 {
for e in 0..10 {
tags.push(format!(
"tagname_a{}.tagname_b{}.tagname_c{}.tagname_d{}.tagname_e{}",
a, b, c, d, e
));
}
}
}
}
}
dbg!(tags.len());
benchmark_start!();
for _ in 0..n {
let tree: Tree = tags.as_slice().into();
let result = tree.to_vec();
assert_eq!(result.len(), tags.len());
}
benchmark_print!(n);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment