use token_trie::Trie;
fn main() {
println!("=== Token Trie Demo ===\n");
println!("1. Basic Operations with Character Keys");
let mut char_trie = Trie::new();
char_trie.insert(&['h', 'e', 'l', 'l', 'o'], "greeting");
char_trie.insert(&['h', 'e', 'l', 'p'], "assistance");
char_trie.insert(&['h', 'i'], "informal_greeting");
char_trie.insert(&['w', 'o', 'r', 'l', 'd'], "earth");
println!("Inserted words: hello, help, hi, world");
println!(
"Looking up 'hello': {:?}",
char_trie.get(&['h', 'e', 'l', 'l', 'o'])
);
println!(
"Looking up 'help': {:?}",
char_trie.get(&['h', 'e', 'l', 'p'])
);
println!("Looking up 'hi': {:?}", char_trie.get(&['h', 'i']));
println!(
"Looking up 'foo' (not in trie): {:?}",
char_trie.get(&['f', 'o', 'o'])
);
println!(
"\nWords starting with 'he': {:?}",
char_trie.keys_with_prefix(&['h', 'e'])
);
println!(
"Words starting with 'h': {:?}",
char_trie.keys_with_prefix(&['h'])
);
println!("\nCommon prefix length tests:");
println!(
"'hello' vs trie: {}",
char_trie.common_prefix_length(&['h', 'e', 'l', 'l', 'o'])
);
println!(
"'helper' vs trie: {}",
char_trie.common_prefix_length(&['h', 'e', 'l', 'p', 'e', 'r'])
);
println!(
"'hex' vs trie: {}",
char_trie.common_prefix_length(&['h', 'e', 'x'])
);
println!(
"'xyz' vs trie: {}",
char_trie.common_prefix_length(&['x', 'y', 'z'])
);
println!("\n{}\n", "=".repeat(50));
println!("2. Integer Keys Demo (Token IDs)");
let mut token_trie = Trie::new();
token_trie.insert(&[1, 2, 3], "sequence_a");
token_trie.insert(&[1, 2, 4], "sequence_b");
token_trie.insert(&[1, 5], "sequence_c");
token_trie.insert(&[2, 3, 4, 5], "sequence_d");
println!("Inserted token sequences:");
println!(" [1,2,3] -> sequence_a");
println!(" [1,2,4] -> sequence_b");
println!(" [1,5] -> sequence_c");
println!(" [2,3,4,5] -> sequence_d");
println!("\nLookup results:");
println!(" [1,2,3]: {:?}", token_trie.get(&[1, 2, 3]));
println!(" [1,2]: {:?}", token_trie.get(&[1, 2]));
println!(" [1,2,4]: {:?}", token_trie.get(&[1, 2, 4]));
println!("\nSequences starting with [1]:");
let prefix_1 = token_trie.keys_with_prefix(&[1]);
for seq in &prefix_1 {
println!(" {:?}", seq);
}
println!("\nSequences starting with [1,2]:");
let prefix_12 = token_trie.keys_with_prefix(&[1, 2]);
for seq in &prefix_12 {
println!(" {:?}", seq);
}
println!("\n{}\n", "=".repeat(50));
println!("3. Radix Compression Demo");
let mut radix_trie = Trie::new();
radix_trie.insert(&['p', 'r', 'e', 'f', 'i', 'x', '_', '1'], "first");
radix_trie.insert(&['p', 'r', 'e', 'f', 'i', 'x', '_', '2'], "second");
radix_trie.insert(&['p', 'r', 'e', 'f', 'i', 'x', '_', '3'], "third");
radix_trie.insert(&['p', 'r', 'e', 'f'], "prefix_itself");
radix_trie.insert(&['p', 'r', 'e', 'p', 'a', 'r', 'e'], "prepare");
println!("Inserted keys with common prefixes:");
println!(" prefix_1, prefix_2, prefix_3, pref, prepare");
println!("\nAll keys in trie:");
let all_keys = radix_trie.keys();
for key in &all_keys {
let key_str: String = key.iter().collect();
println!(" '{}' -> {:?}", key_str, radix_trie.get(key));
}
println!("\nCommon prefix analysis:");
println!(
" 'prefix_4' common length: {}",
radix_trie.common_prefix_length(&['p', 'r', 'e', 'f', 'i', 'x', '_', '4'])
);
println!(
" 'preparation' common length: {}",
radix_trie.common_prefix_length(&['p', 'r', 'e', 'p', 'a', 'r', 'a', 't', 'i', 'o', 'n'])
);
println!("\n{}\n", "=".repeat(50));
println!("4. Performance Demo");
let mut perf_trie = Trie::new();
println!("Inserting 1000 keys...");
for i in 0..1000 {
let key = generate_key_pattern(i);
perf_trie.insert(&key, format!("value_{}", i));
}
println!("Total keys in trie: {}", perf_trie.len());
let test_key = generate_key_pattern(42);
println!("Looking up key pattern 42: {:?}", perf_trie.get(&test_key));
let test_key2 = generate_key_pattern(999);
println!(
"Looking up key pattern 999: {:?}",
perf_trie.get(&test_key2)
);
let prefix = vec![0, 1];
let prefix_results = perf_trie.keys_with_prefix(&prefix);
println!("Keys starting with [0,1]: {} found", prefix_results.len());
println!("\n{}\n", "=".repeat(50));
println!("5. Edge Cases Demo");
let mut edge_trie = Trie::new();
edge_trie.insert(&[], "empty_key_value");
println!("Inserted empty key");
println!("Empty key lookup: {:?}", edge_trie.get(&[]));
edge_trie.insert(&[42], "single_element");
println!("Single element [42]: {:?}", edge_trie.get(&[42]));
let long_key: Vec<i32> = (0..50).collect();
edge_trie.insert(&long_key, "very_long_sequence");
println!(
"Very long key (50 elements): {:?}",
edge_trie.get(&long_key)
);
edge_trie.insert(&[-1, -2, -3], "negative_sequence");
println!(
"Negative sequence [-1,-2,-3]: {:?}",
edge_trie.get(&[-1, -2, -3])
);
println!("\nFinal edge trie stats:");
println!(" Total keys: {}", edge_trie.len());
println!(" Is empty: {}", edge_trie.is_empty());
println!("\n=== Demo Complete ===");
}
fn generate_key_pattern(i: usize) -> Vec<i32> {
match i % 4 {
0 => vec![0, 1, (i % 10) as i32],
1 => vec![1, (i % 5) as i32, (i % 3) as i32],
2 => vec![(i % 7) as i32, 2, 3],
3 => vec![3, (i % 8) as i32],
_ => unreachable!(),
}
}