├── .gitignore ├── .travis.yml ├── examples ├── debug.rs └── json.rs ├── CHANGELOG.md ├── LICENSE-APACHE ├── Cargo.toml ├── LICENSE-MIT ├── benches └── vs_hashmap.rs ├── README.md └── src ├── serde_tests.rs ├── tests.rs └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | *.swp 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | os: 3 | - linux 4 | script: 5 | - cargo test --verbose 6 | - cargo test --verbose --features=serde 7 | - cargo test --verbose --features=btreemap 8 | - cargo test --verbose --features=serde,btreemap 9 | - cargo doc --no-deps 10 | -------------------------------------------------------------------------------- /examples/debug.rs: -------------------------------------------------------------------------------- 1 | extern crate sequence_trie; 2 | 3 | use sequence_trie::SequenceTrie; 4 | 5 | fn main() { 6 | let mut trie = SequenceTrie::<&str, bool>::new(); 7 | trie.insert(&["wow", "cow"], true); 8 | trie.insert(&["wow", "this"], false); 9 | println!("{:?}", trie); 10 | } 11 | -------------------------------------------------------------------------------- /examples/json.rs: -------------------------------------------------------------------------------- 1 | extern crate sequence_trie; 2 | extern crate serde_json; 3 | 4 | use sequence_trie::SequenceTrie; 5 | 6 | fn main() { 7 | let mut trie = SequenceTrie::new(); 8 | trie.insert(&["hello", "world"], 56); 9 | trie.insert(&["hello", "moon"], 57); 10 | 11 | println!("{}", serde_json::to_string_pretty(&trie).unwrap()); 12 | } 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ==== 3 | 4 | 0.3.6: 5 | 6 | * Add serde (de)serialisation support (`--features=serde`) 7 | * Optionally use a `BTreeMap` instead of a `HashMap` as the backing map (`--features=btreemap`) 8 | 9 | 0.3.5: 10 | 11 | * Enable README rendering on crates.io (no code changes). 12 | 13 | 0.3.4: 14 | 15 | * Allow keys to have lifetimes other than 'static. 16 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Copyright 2016 Michael Sproul and contributors. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sequence_trie" 3 | version = "0.3.6" 4 | description = "Trie-like data-structure for storing sequences of values." 5 | 6 | license = "MIT/Apache-2.0" 7 | authors = ["Michael Sproul ", "Alex Gulyás "] 8 | 9 | documentation = "https://docs.rs/sequence_trie/" 10 | repository = "https://github.com/michaelsproul/rust_sequence_trie" 11 | readme = "README.md" 12 | 13 | keywords = ["trie", "tree", "hash", "data-structure", "collection"] 14 | 15 | [lib] 16 | name = "sequence_trie" 17 | 18 | [features] 19 | btreemap = [] 20 | 21 | [dependencies] 22 | serde = { version = "^1.0", optional = true, features = ["derive"] } 23 | 24 | [dev-dependencies] 25 | serde_json = "^1.0" 26 | 27 | [[example]] 28 | name = "json" 29 | required-features = ["serde"] 30 | 31 | [[example]] 32 | name = "debug" 33 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Michael Sproul and contributors. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /benches/vs_hashmap.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | extern crate test; 3 | extern crate sequence_trie; 4 | 5 | use std::collections::HashMap; 6 | use test::Bencher; 7 | use sequence_trie::SequenceTrie; 8 | 9 | macro_rules! u32_benchmark { 10 | ($map_constructor: expr, $test_id: ident, $num_keys: expr, $key_length: expr) => ( 11 | #[bench] 12 | fn $test_id(b: &mut Bencher) { 13 | let mut test_data = Vec::>::with_capacity($num_keys); 14 | let mut map = $map_constructor; 15 | for i in 0 .. $num_keys { 16 | let mut key = Vec::::with_capacity($key_length); 17 | for j in 0 .. $key_length { 18 | key.push(i * j); 19 | } 20 | 21 | test_data.push(key); 22 | } 23 | 24 | b.iter(|| { 25 | for key in &test_data { 26 | map.insert(&key[..], 7u32); 27 | } 28 | }); 29 | } 30 | ) 31 | } 32 | 33 | u32_benchmark! { HashMap::new(), hashmap_k1024_l16, 1024, 16 } 34 | u32_benchmark! { SequenceTrie::new(), trie_k1024_l16, 1024, 16 } 35 | 36 | u32_benchmark! { HashMap::new(), hashmap_k64_l128, 64, 128 } 37 | u32_benchmark! { SequenceTrie::new(), trie_k64_l128, 64, 128 } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [Sequence Trie][doc] 2 | ==== 3 | 4 | [![Build Status](https://travis-ci.org/michaelsproul/rust_sequence_trie.svg?branch=master)](https://travis-ci.org/michaelsproul/rust_sequence_trie) 5 | 6 | This is a generic Trie implementation that uses a hash map to store child nodes. The Trie is keyed by lists of type `K`, which can be anything implementing `PartialEq`, `Eq`, `Hash` and `Clone`. If your keys are explicit lists and you want to be able to store a different value for each element of a key, this might be the data structure for you! 7 | 8 | For more information, see the [API documentation][doc]. 9 | 10 | [doc]: https://docs.rs/sequence_trie/ 11 | 12 | # Usage 13 | 14 | Add `sequence_trie` to your `Cargo.toml`. 15 | 16 | ```toml 17 | [dependencies] 18 | sequence_trie = "*" 19 | ``` 20 | 21 | # See Also 22 | * [Radix Trie][radix-trie] – a trie operating on byte-strings, with better performance and a less ergonomic API. 23 | 24 | [radix-trie]: https://github.com/michaelsproul/rust_radix_trie 25 | 26 | # License 27 | 28 | Licensed under either of: 29 | 30 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 31 | * [MIT license](http://opensource.org/licenses/MIT) 32 | 33 | at your option. 34 | 35 | ## Contribution 36 | 37 | Unless you explicitly state otherwise, any contribution intentionally submitted 38 | for inclusion in the work by you shall be dual licensed as above, without any 39 | additional terms or conditions. 40 | -------------------------------------------------------------------------------- /src/serde_tests.rs: -------------------------------------------------------------------------------- 1 | extern crate serde_json; 2 | 3 | use super::SequenceTrie; 4 | 5 | type TestTrie = SequenceTrie; 6 | 7 | fn test_trie() -> TestTrie { 8 | let mut trie = SequenceTrie::new(); 9 | trie.insert(vec!["a"], 1u32); 10 | trie.insert(vec!["a", "b", "c", "d"], 4u32); 11 | trie.insert(vec!["a", "b", "x", "y"], 25u32); 12 | trie 13 | } 14 | 15 | #[test] 16 | fn roundtrip() { 17 | let trie = test_trie(); 18 | let rtrip = serde_json::to_string(&trie) 19 | .and_then(|s| serde_json::from_str::(&s)) 20 | .unwrap(); 21 | assert_eq!(rtrip, trie); 22 | } 23 | 24 | #[test] 25 | fn json_deserialise() { 26 | let test_str = r#" 27 | { 28 | "value": null, 29 | "children": { 30 | "hello": { 31 | "value": null, 32 | "children": { 33 | "world": { 34 | "value": 56, 35 | "children": {} 36 | }, 37 | "moon": { 38 | "value": 57, 39 | "children": {} 40 | } 41 | } 42 | } 43 | } 44 | } 45 | "#; 46 | 47 | let trie = serde_json::from_str::(test_str).unwrap(); 48 | 49 | assert_eq!(trie.get(vec!["hello"]), None); 50 | assert_eq!(trie.get(vec!["hello", "world"]), Some(&56)); 51 | assert_eq!(trie.get(vec!["hello", "moon"]), Some(&57)); 52 | } 53 | -------------------------------------------------------------------------------- /src/tests.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | 3 | use super::SequenceTrie; 4 | 5 | fn make_trie() -> SequenceTrie { 6 | let mut trie = SequenceTrie::new(); 7 | trie.insert(&[], 0u32); 8 | trie.insert(&['a'], 1u32); 9 | trie.insert(&['a', 'b', 'c', 'd'], 4u32); 10 | trie.insert(&['a', 'b', 'x', 'y'], 25u32); 11 | trie 12 | } 13 | 14 | #[test] 15 | fn get() { 16 | let trie = make_trie(); 17 | let data = [(vec![], Some(0u32)), 18 | (vec!['a'], Some(1u32)), 19 | (vec!['a', 'b'], None), 20 | (vec!['a', 'b', 'c'], None), 21 | (vec!['a', 'b', 'x'], None), 22 | (vec!['a', 'b', 'c', 'd'], Some(4u32)), 23 | (vec!['a', 'b', 'x', 'y'], Some(25u32)), 24 | (vec!['b', 'x', 'y'], None)]; 25 | for &(ref key, value) in data.iter() { 26 | assert_eq!(trie.get(key), value.as_ref()); 27 | } 28 | } 29 | 30 | #[test] 31 | fn get_mut() { 32 | let mut trie = make_trie(); 33 | let key = ['a', 'b', 'c', 'd']; 34 | *trie.get_mut(&key).unwrap() = 77u32; 35 | assert_eq!(*trie.get(&key).unwrap(), 77u32); 36 | } 37 | 38 | #[test] 39 | fn get_ancestor() { 40 | let trie = make_trie(); 41 | let data = [(vec![], 0u32), 42 | (vec!['a'], 1u32), 43 | (vec!['a', 'b'], 1u32), 44 | (vec!['a', 'b', 'c'], 1u32), 45 | (vec!['a', 'b', 'c', 'd'], 4u32), 46 | (vec!['a', 'b', 'x'], 1u32), 47 | (vec!['a', 'b', 'x', 'y'], 25u32), 48 | (vec!['p', 'q'], 0u32), 49 | (vec!['a', 'p', 'q'], 1u32)]; 50 | for &(ref key, value) in data.iter() { 51 | assert_eq!(*trie.get_ancestor(key).unwrap(), value); 52 | } 53 | } 54 | 55 | #[test] 56 | fn get_prefix_nodes() { 57 | let trie = make_trie(); 58 | let prefix_nodes = trie.get_prefix_nodes(&['a', 'b', 'z']); 59 | // There should be 3 nodes: root, a, b. 60 | assert_eq!(prefix_nodes.len(), 3); 61 | let values = [Some(0u32), Some(1u32), None]; 62 | for (node, value) in prefix_nodes.iter().zip(values.iter()) { 63 | assert_eq!(node.value, *value); 64 | } 65 | } 66 | 67 | #[test] 68 | fn remove() { 69 | let mut trie = make_trie(); 70 | // If the node has children, its value should be set to `None`. 71 | println!("Remove ['a']"); 72 | println!("Before: {:?}", trie); 73 | trie.remove(&['a']); 74 | println!("After: {:?}", trie); 75 | assert_eq!(trie.get_node(&['a']).unwrap().value, None); 76 | 77 | // Same as above, but for the root. 78 | println!("Remove []"); 79 | println!("Before: {:?}", trie); 80 | trie.remove(&[]); 81 | println!("After: {:?}", trie); 82 | assert_eq!(trie.get_node(&[]).unwrap().value, None); 83 | 84 | // Check that lower levels are still accessible. 85 | assert_eq!(trie.get(&['a', 'b', 'c', 'd']), Some(&4u32)); 86 | 87 | // Check that removing a leaf with an empty parent also 88 | // deletes the parent. 89 | println!("Remove ['a', 'b', 'c', 'd']"); 90 | println!("Before: {:?}", trie); 91 | trie.remove(&['a', 'b', 'c', 'd']); 92 | println!("After: {:?}", trie); 93 | assert!(trie.get_node(&['a', 'b', 'c', 'd']).is_none()); 94 | assert!(trie.get_node(&['a', 'b', 'c']).is_none()); 95 | assert!(trie.get_node(&['a', 'b']).is_some()); 96 | 97 | // Bump off the rest of the Trie! 98 | println!("Remove ['a', 'b', 'x', 'y']"); 99 | println!("Before: {:?}", trie); 100 | trie.remove(&['a', 'b', 'x', 'y']); 101 | println!("After: {:?}", trie); 102 | assert!(trie.get_node(&['a', 'b', 'x', 'y']).is_none()); 103 | assert!(trie.get_node(&['a', 'b', 'x']).is_none()); 104 | assert!(trie.get_node(&['a', 'b']).is_none()); 105 | assert!(trie.get_node(&['a']).is_none()); 106 | assert!(trie.value.is_none()); 107 | assert!(trie.children.is_empty()); 108 | } 109 | 110 | #[test] 111 | fn key_iter() { 112 | let trie = make_trie(); 113 | let obs_keys: HashSet> = trie.keys() 114 | .map(|v| -> Vec { v.iter().map(|&&x| x).collect() }) 115 | .collect(); 116 | let mut exp_keys: HashSet> = HashSet::new(); 117 | exp_keys.insert(vec![]); 118 | exp_keys.insert(vec!['a']); 119 | exp_keys.insert(vec!['a', 'b', 'c', 'd']); 120 | exp_keys.insert(vec!['a', 'b', 'x', 'y']); 121 | assert_eq!(exp_keys, obs_keys); 122 | } 123 | 124 | #[derive(PartialEq, Eq, Hash, Clone, PartialOrd, Ord)] 125 | struct Key { 126 | field: usize, 127 | } 128 | 129 | #[test] 130 | fn struct_key() { 131 | SequenceTrie::::new(); 132 | } 133 | 134 | #[test] 135 | fn eq() { 136 | let first_trie = make_trie(); 137 | let second_trie = make_trie(); 138 | assert_eq!(first_trie, second_trie); 139 | } 140 | 141 | #[test] 142 | fn eq_empty() { 143 | let first_trie: SequenceTrie = SequenceTrie::new(); 144 | let second_trie = SequenceTrie::new(); 145 | assert_eq!(first_trie, second_trie); 146 | } 147 | 148 | #[test] 149 | fn ne_value() { 150 | let mut first_trie = SequenceTrie::new(); 151 | first_trie.insert(b"1234", 1234); 152 | first_trie.insert(b"1235", 1235); 153 | let mut second_trie = SequenceTrie::new(); 154 | second_trie.insert(b"1234", 1234); 155 | second_trie.insert(b"1235", 1236); 156 | assert!(first_trie != second_trie); 157 | } 158 | 159 | #[test] 160 | fn ne_key() { 161 | let mut first_trie = SequenceTrie::new(); 162 | first_trie.insert(b"1234", 1234); 163 | first_trie.insert(b"1235", 1235); 164 | let mut second_trie = SequenceTrie::new(); 165 | second_trie.insert(b"1234", 1234); 166 | second_trie.insert(b"1236", 1235); 167 | assert!(first_trie != second_trie); 168 | } 169 | 170 | #[test] 171 | fn ne_missing_key() { 172 | let mut first_trie = SequenceTrie::new(); 173 | first_trie.insert(b"1234", 1234); 174 | first_trie.insert(b"1235", 1235); 175 | let mut second_trie = SequenceTrie::new(); 176 | second_trie.insert(b"1234", 1234); 177 | assert!(first_trie != second_trie); 178 | } 179 | 180 | #[test] 181 | fn clone() { 182 | let first_trie = make_trie(); 183 | let second_trie = first_trie.clone(); 184 | assert_eq!(first_trie, second_trie); 185 | } 186 | 187 | #[test] 188 | fn default() { 189 | let empty_trie: SequenceTrie = ::std::default::Default::default(); 190 | assert_eq!(empty_trie, SequenceTrie::new()); 191 | } 192 | 193 | #[test] 194 | fn string_trie() { 195 | let mut trie: SequenceTrie = SequenceTrie::new(); 196 | trie.insert_owned(vec!["hello".to_string(), "world".to_string()], ()); 197 | trie.insert(&["hello".to_string(), "world".to_string()], ()); 198 | trie.insert(vec!["hello", "world"], ()); 199 | trie.insert(["hello", "world"].iter().map(|&x| x), ()); 200 | } 201 | 202 | #[test] 203 | fn map() { 204 | let mut trie = SequenceTrie::new(); 205 | trie.insert(&[0u32], 0u32); 206 | trie.insert(&[5u32], 10u32); 207 | trie.map(|node| node.value().map(|x| x + 1)); 208 | for (k, v) in trie.iter() { 209 | assert_eq!(*v, 2*k[0] + 1); 210 | } 211 | } 212 | 213 | #[test] 214 | fn non_static_lifetime() { 215 | let a = format!("a"); 216 | let b = format!("b"); 217 | let mut trie: SequenceTrie<&str, u32> = SequenceTrie::new(); 218 | 219 | trie.insert(&[&a[..], &b[..]], 0u32); 220 | } 221 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Sequence Trie - a trie-like data-structure for storing sequences of values. 2 | //! 3 | //! See the `SequenceTrie` type for documentation. 4 | 5 | #[cfg(not(feature = "btreemap"))] 6 | use std::hash::Hash; 7 | #[cfg(not(feature = "btreemap"))] 8 | use std::collections::hash_map::{self, HashMap}; 9 | 10 | #[cfg(feature = "btreemap")] 11 | use std::collections::{btree_map, BTreeMap}; 12 | 13 | use std::hash::BuildHasher; 14 | use std::collections::hash_map::RandomState; 15 | 16 | use std::iter::IntoIterator; 17 | use std::default::Default; 18 | use std::borrow::{Borrow, ToOwned}; 19 | use std::mem; 20 | use std::marker::PhantomData; 21 | 22 | #[cfg(feature = "serde")] 23 | use serde::{Serialize, Deserialize}; 24 | 25 | #[cfg(feature = "serde")] 26 | #[macro_use] 27 | extern crate serde; 28 | 29 | #[cfg(test)] 30 | mod tests; 31 | #[cfg(all(test, feature = "serde"))] 32 | mod serde_tests; 33 | 34 | /// A `SequenceTrie` is recursively defined as a value and a map containing child Tries. 35 | /// 36 | /// Typically, Tries are used to store strings, which can be thought of as lists of `char`s. 37 | /// Generalising this to any key type, a Trie is a data structure storing values for keys 38 | /// which are themselves lists. Let the parts of such a list-key be called "key fragments". 39 | /// In our representation of a Trie, `K` denotes the type of the key fragments. 40 | /// 41 | /// The nesting of child Tries creates a tree structure which can be traversed by mapping 42 | /// key fragments onto nodes. The structure is similar to a k-ary tree, except that the children 43 | /// are stored in `HashMap`s, and there is no bound on the number of children a single node may 44 | /// have (effectively k = ∞). In a `SequenceTrie` with `char` key fragments, the key 45 | /// `['a', 'b', 'c']` might correspond to something like this: 46 | /// 47 | /// ```text 48 | /// SequenceTrie { 49 | /// value: Some(0), 50 | /// children: 'a' => SequenceTrie { 51 | /// value: Some(1), 52 | /// children: 'b' => SequenceTrie { 53 | /// value: None, 54 | /// children: 'c' => SequenceTrie { 55 | /// value: Some(3), 56 | /// children: Nil 57 | /// } 58 | /// } 59 | /// } 60 | /// } 61 | /// ``` 62 | /// 63 | /// Values are stored optionally at each node because inserting a value for a list-key only inserts 64 | /// a value for the last fragment of the key. The intermediate prefix nodes are created with value 65 | /// `None` if they do not exist already. 66 | /// 67 | /// The above `SequenceTrie` could be created using the following sequence of operations: 68 | /// 69 | /// ``` 70 | /// # use sequence_trie::SequenceTrie; 71 | /// let mut trie: SequenceTrie = SequenceTrie::new(); 72 | /// trie.insert(&['a', 'b', 'c'], 3); 73 | /// trie.insert(&[], 0); 74 | /// trie.insert(&['a'], 1); 75 | /// ``` 76 | /// 77 | /// The order of insertion is never important. 78 | /// 79 | /// One interesting thing about Tries is that every key is a *descendant* of the root, which itself 80 | /// has no key fragment. Although this is a rather trivial observation, it means that every key 81 | /// corresponds to a non-empty sequence of prefix nodes in the tree. This observation is the 82 | /// motivation for the `get_prefix_nodes` method, which returns the nodes corresponding to the longest 83 | /// prefix of a given key. 84 | /// 85 | /// The empty list key, `[]`, always corresponds to the root node of the Trie. 86 | /// 87 | /// # The Sequence Trie Invariant 88 | /// All leaf nodes have non-trivial values (not equal to `None`). This invariant is maintained by 89 | /// the insertion and removal methods and can be relied upon. 90 | #[derive(Debug, Clone)] 91 | #[cfg(not(feature = "btreemap"))] 92 | #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 93 | #[cfg_attr(feature = "serde", serde(bound(serialize = "K: Serialize, V: Serialize")))] 94 | #[cfg_attr(feature = "serde", 95 | serde(bound(deserialize = "K: Deserialize<'de>, V: Deserialize<'de>")))] 96 | pub struct SequenceTrie 97 | where K: TrieKey, 98 | S: BuildHasher + Default, 99 | { 100 | /// Node value. 101 | value: Option, 102 | 103 | /// Node children as a hashmap keyed by key fragments. 104 | children: HashMap, S>, 105 | } 106 | 107 | #[derive(Debug, Clone)] 108 | #[cfg(feature = "btreemap")] 109 | #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 110 | #[cfg_attr(feature = "serde", serde(bound(serialize = "K: Serialize, V: Serialize")))] 111 | #[cfg_attr(feature = "serde", 112 | serde(bound(deserialize = "K: Deserialize<'de>, V: Deserialize<'de>")))] 113 | pub struct SequenceTrie 114 | where K: TrieKey, 115 | S: BuildHasher + Default, 116 | { 117 | /// Node value. 118 | value: Option, 119 | 120 | /// Node children as a btreemap keyed by key fragments. 121 | children: BTreeMap>, 122 | 123 | /// Fake hasher for compatibility. 124 | #[cfg_attr(feature = "serde", serde(skip))] 125 | _phantom: PhantomData, 126 | } 127 | 128 | /// Aggregate trait for types which can be used to key a `SequenceTrie`. 129 | /// 130 | /// This trait is automatically implemented for all types implementing 131 | /// the supertraits. 132 | #[cfg(not(feature = "btreemap"))] 133 | pub trait TrieKey: Eq + Hash {} 134 | #[cfg(not(feature = "btreemap"))] 135 | impl TrieKey for K where K: Eq + Hash + ?Sized {} 136 | 137 | #[cfg(feature = "btreemap")] 138 | pub trait TrieKey: Ord {} 139 | #[cfg(feature = "btreemap")] 140 | impl TrieKey for K where K: Ord + ?Sized {} 141 | 142 | #[cfg(not(feature = "btreemap"))] 143 | impl SequenceTrie 144 | where K: TrieKey, 145 | { 146 | /// Creates a new `SequenceTrie` node with no value and an empty child map. 147 | pub fn new() -> SequenceTrie { 148 | SequenceTrie::with_hasher(RandomState::new()) 149 | } 150 | } 151 | 152 | #[cfg(not(feature = "btreemap"))] 153 | impl SequenceTrie 154 | where K: TrieKey, 155 | S: BuildHasher + Default + Clone, 156 | { 157 | pub fn with_hasher(hash_builder: S) -> SequenceTrie { 158 | SequenceTrie { 159 | value: None, 160 | children: HashMap::with_hasher(hash_builder), 161 | } 162 | } 163 | } 164 | 165 | #[cfg(feature = "btreemap")] 166 | impl SequenceTrie 167 | where K: TrieKey, 168 | { 169 | /// Creates a new `SequenceTrie` node with no value and an empty child map. 170 | pub fn new() -> SequenceTrie { 171 | Self::new_generic() 172 | } 173 | } 174 | 175 | #[cfg(feature = "btreemap")] 176 | impl SequenceTrie 177 | where K: TrieKey, 178 | S: BuildHasher + Default + Clone, 179 | { 180 | /// Creates a new `SequenceTrie` node with no value and an empty child map. 181 | pub fn new_generic() -> SequenceTrie { 182 | SequenceTrie { 183 | value: None, 184 | children: BTreeMap::new(), 185 | _phantom: PhantomData, 186 | } 187 | } 188 | } 189 | 190 | impl SequenceTrie 191 | where K: TrieKey, 192 | S: BuildHasher + Default + Clone, 193 | { 194 | /// Retrieve the value stored at this node. 195 | pub fn value(&self) -> Option<&V> { 196 | self.value.as_ref() 197 | } 198 | 199 | /// Retrieve a mutable reference to the value stored at this node. 200 | pub fn value_mut(&mut self) -> Option<&mut V> { 201 | self.value.as_mut() 202 | } 203 | 204 | /// Checks if this node is empty. 205 | /// 206 | /// A node is considered empty when it has no value and no children. 207 | pub fn is_empty(&self) -> bool { 208 | self.is_leaf() && self.value.is_none() 209 | } 210 | 211 | /// Checks if this node has no descendants. 212 | pub fn is_leaf(&self) -> bool { 213 | self.children.is_empty() 214 | } 215 | 216 | /// Inserts a key and value into the SequenceTrie. 217 | /// 218 | /// Returns `None` if the key did not already correspond to a value, otherwise the old value is 219 | /// returned. 220 | pub fn insert<'key, I, Q: 'key + ?Sized>(&mut self, key: I, value: V) -> Option 221 | where I: IntoIterator, 222 | Q: ToOwned, 223 | K: Borrow 224 | { 225 | self.insert_owned(key.into_iter().map(ToOwned::to_owned), value) 226 | } 227 | 228 | /// Version of `insert` that takes an owned sequence of key fragments. 229 | /// 230 | /// This function is used internally by `insert`. 231 | #[cfg(not(feature = "btreemap"))] 232 | pub fn insert_owned(&mut self, key: I, value: V) -> Option 233 | where I: IntoIterator 234 | { 235 | let key_node = key.into_iter().fold(self, |current_node, fragment| { 236 | let hash_builder = current_node.children.hasher().clone(); 237 | current_node.children 238 | .entry(fragment) 239 | .or_insert_with(|| Self::with_hasher(hash_builder)) 240 | }); 241 | 242 | mem::replace(&mut key_node.value, Some(value)) 243 | } 244 | 245 | #[cfg(feature = "btreemap")] 246 | pub fn insert_owned(&mut self, key: I, value: V) -> Option 247 | where I: IntoIterator 248 | { 249 | let key_node = key.into_iter().fold(self, |current_node, fragment| { 250 | current_node.children 251 | .entry(fragment) 252 | .or_insert_with(Self::new_generic) 253 | }); 254 | 255 | mem::replace(&mut key_node.value, Some(value)) 256 | } 257 | 258 | /// Finds a reference to a key's value, if it has one. 259 | pub fn get<'key, I, Q: ?Sized>(&self, key: I) -> Option<&V> 260 | where I: IntoIterator, 261 | K: Borrow, 262 | Q: TrieKey + 'key 263 | { 264 | self.get_node(key).and_then(|node| node.value.as_ref()) 265 | } 266 | 267 | /// Finds a reference to a key's node, if it has one. 268 | pub fn get_node<'key, I, Q: ?Sized>(&self, key: I) -> Option<&SequenceTrie> 269 | where I: IntoIterator, 270 | K: Borrow, 271 | Q: TrieKey + 'key 272 | { 273 | let mut current_node = self; 274 | 275 | for fragment in key { 276 | match current_node.children.get(fragment) { 277 | Some(node) => current_node = node, 278 | None => return None, 279 | } 280 | } 281 | 282 | Some(current_node) 283 | } 284 | 285 | /// Finds a mutable reference to a key's value, if it has one. 286 | pub fn get_mut<'key, I, Q: ?Sized>(&mut self, key: I) -> Option<&mut V> 287 | where I: IntoIterator, 288 | K: Borrow, 289 | Q: TrieKey + 'key 290 | { 291 | self.get_node_mut(key).and_then(|node| node.value.as_mut()) 292 | } 293 | 294 | /// Finds a mutable reference to a key's node, if it has one. 295 | pub fn get_node_mut<'key, I, Q: ?Sized>(&mut self, key: I) -> Option<&mut SequenceTrie> 296 | where I: IntoIterator, 297 | K: Borrow, 298 | Q: TrieKey + 'key 299 | { 300 | let mut current_node = Some(self); 301 | 302 | for fragment in key { 303 | match current_node.and_then(|node| node.children.get_mut(fragment)) { 304 | Some(node) => current_node = Some(node), 305 | None => return None, 306 | } 307 | } 308 | 309 | current_node 310 | } 311 | 312 | /// Finds the longest prefix of nodes which match the given key. 313 | pub fn get_prefix_nodes<'key, I, Q: ?Sized>(&self, key: I) -> Vec<&SequenceTrie> 314 | where I: 'key + IntoIterator, 315 | K: Borrow, 316 | Q: TrieKey + 'key 317 | { 318 | self.prefix_iter(key).collect() 319 | } 320 | 321 | /// Finds the value of the nearest ancestor with a non-empty value, if one exists. 322 | /// 323 | /// If all ancestors have empty (`None`) values, `None` is returned. 324 | pub fn get_ancestor<'key, I, Q: ?Sized>(&self, key: I) -> Option<&V> 325 | where I: 'key + IntoIterator, 326 | K: Borrow, 327 | Q: TrieKey + 'key 328 | { 329 | self.get_ancestor_node(key).and_then(|node| node.value.as_ref()) 330 | } 331 | 332 | /// Finds the nearest ancestor with a non-empty value, if one exists. 333 | /// 334 | /// If all ancestors have empty (`None`) values, `None` is returned. 335 | pub fn get_ancestor_node<'key, I, Q: ?Sized>(&self, key: I) -> Option<&SequenceTrie> 336 | where I: 'key + IntoIterator, 337 | K: Borrow, 338 | Q: TrieKey + 'key 339 | { 340 | self.prefix_iter(key) 341 | .filter(|node| node.value.is_some()) 342 | .last() 343 | } 344 | 345 | /// Removes the node corresponding to the given key. 346 | /// 347 | /// This operation is like the reverse of `insert` in that 348 | /// it also deletes extraneous nodes on the path from the root. 349 | /// 350 | /// If the key node has children, its value is set to `None` and no further 351 | /// action is taken. If the key node is a leaf, then it and its ancestors with 352 | /// empty values and no other children are deleted. Deletion proceeds up the tree 353 | /// from the key node until a node with a non-empty value or children is reached. 354 | /// 355 | /// If the key doesn't match a node in the Trie, no action is taken. 356 | pub fn remove<'key, I, Q: ?Sized>(&mut self, key: I) 357 | where I: IntoIterator, 358 | K: Borrow, 359 | Q: TrieKey + 'key 360 | { 361 | self.remove_recursive(key); 362 | } 363 | 364 | /// Recursive remove method that uses the call stack to safely and 365 | /// efficiently remove a node and its extraneous ancestors. 366 | /// 367 | /// Return `true` if the node should be deleted. 368 | /// 369 | /// See `remove` above. 370 | fn remove_recursive<'key, I, Q: ?Sized>(&mut self, key: I) -> bool 371 | where I: IntoIterator, 372 | K: Borrow, 373 | Q: TrieKey + 'key 374 | { 375 | let mut fragments = key.into_iter(); 376 | match fragments.next() { 377 | // Base case: Leaf node, no key left to recurse on. 378 | None => { 379 | self.value = None; 380 | } 381 | 382 | // Recursive case: Inner node, delete children. 383 | Some(fragment) => { 384 | let delete_child = match self.children.get_mut(fragment) { 385 | Some(child) => child.remove_recursive(fragments), 386 | None => false, 387 | }; 388 | 389 | if delete_child { 390 | self.children.remove(fragment); 391 | } 392 | // NB: If the child isn't found, false will be returned. 393 | // The `self` node is either a leaf, with a non-trivial value, or an 394 | // inner node (with children). 395 | } 396 | } 397 | 398 | // If the node is childless and valueless, mark it for deletion. 399 | self.is_empty() 400 | } 401 | 402 | /// Recursively apply a function to every node in the trie. 403 | /// 404 | /// Nodes are visited "bottom-up" (children before parent). 405 | /// If `f` returns a value, it replaces the value at that node. 406 | /// Otherwise, the node's value remains unchanged. 407 | pub fn map(&mut self, f: F) where F: Fn(&Self) -> Option { 408 | self.map_rec(&f) 409 | } 410 | 411 | /// Internal version of map that takes the closure by reference. 412 | fn map_rec(&mut self, f: &F) where F: Fn(&Self) -> Option { 413 | for child in self.children.values_mut() { 414 | child.map_rec(f); 415 | } 416 | 417 | if let Some(v) = f(&*self) { 418 | self.value = Some(v); 419 | } 420 | } 421 | 422 | /// Returns an iterator over all the key-value pairs in the collection. 423 | pub fn iter(&self) -> Iter { 424 | Iter { 425 | root: self, 426 | root_visited: false, 427 | key: vec![], 428 | stack: vec![], 429 | } 430 | } 431 | 432 | /// Returns an iterator over all the keys in the trie. 433 | pub fn keys(&self) -> Keys { 434 | Keys { inner: self.iter() } 435 | } 436 | 437 | /// Returns an iterator over all the values stored in the trie. 438 | pub fn values(&self) -> Values { 439 | Values { inner: self.iter() } 440 | } 441 | 442 | /// Returns an iterator over the longest prefix of nodes which match the given key. 443 | pub fn prefix_iter<'trie, 'key, I, Q: ?Sized>(&'trie self, 444 | key: I) 445 | -> PrefixIter<'trie, 'key, K, V, Q, I::IntoIter, S> 446 | where I: IntoIterator, 447 | K: Borrow, 448 | Q: TrieKey + 'key 449 | { 450 | PrefixIter { 451 | next_node: Some(self), 452 | fragments: key.into_iter(), 453 | _phantom: PhantomData, 454 | } 455 | } 456 | 457 | /// Return all the children of this node, in an arbitrary order. 458 | pub fn children(&self) -> Vec<&Self> { 459 | self.children.values().collect() 460 | } 461 | 462 | /// Children of this node, with their associated keys in arbitrary order. 463 | pub fn children_with_keys<'a>(&'a self) -> Vec<(&'a K, &'a Self)> { 464 | self.children.iter().collect() 465 | } 466 | } 467 | 468 | /// Iterator over the keys and values of a `SequenceTrie`. 469 | pub struct Iter<'a, K: 'a, V: 'a, S: 'a = RandomState> 470 | where K: TrieKey, 471 | S: BuildHasher + Default 472 | { 473 | root: &'a SequenceTrie, 474 | root_visited: bool, 475 | key: Vec<&'a K>, 476 | stack: Vec>, 477 | } 478 | 479 | /// Vector of key fragment references and values, yielded during iteration. 480 | pub type KeyValuePair<'a, K, V> = (Vec<&'a K>, &'a V); 481 | 482 | /// Iterator over the keys of a `SequenceTrie`. 483 | pub struct Keys<'a, K: 'a, V: 'a, S: 'a = RandomState> 484 | where K: TrieKey, 485 | S: BuildHasher + Default 486 | { 487 | inner: Iter<'a, K, V, S>, 488 | } 489 | 490 | /// Iterator over the values of a `SequenceTrie`. 491 | pub struct Values<'a, K: 'a, V: 'a, S: 'a = RandomState> 492 | where K: TrieKey, 493 | S: BuildHasher + Default 494 | { 495 | inner: Iter<'a, K, V, S>, 496 | } 497 | 498 | /// Information stored on the iteration stack whilst exploring. 499 | struct StackItem<'a, K: 'a, V: 'a, S: 'a = RandomState> 500 | where K: TrieKey, 501 | S: BuildHasher + Default 502 | { 503 | #[cfg(not(feature = "btreemap"))] 504 | child_iter: hash_map::Iter<'a, K, SequenceTrie>, 505 | #[cfg(feature = "btreemap")] 506 | child_iter: btree_map::Iter<'a, K, SequenceTrie>, 507 | } 508 | 509 | /// Delayed action type for iteration stack manipulation. 510 | enum IterAction<'a, K: 'a, V: 'a, S: 'a> 511 | where K: TrieKey, 512 | S: BuildHasher + Default 513 | { 514 | Push(&'a K, &'a SequenceTrie), 515 | Pop, 516 | } 517 | 518 | impl<'a, K, V, S> Iterator for Iter<'a, K, V, S> 519 | where K: TrieKey, 520 | S: BuildHasher + Default 521 | { 522 | type Item = KeyValuePair<'a, K, V>; 523 | 524 | fn next(&mut self) -> Option> { 525 | use IterAction::*; 526 | 527 | // Special handling for the root. 528 | if !self.root_visited { 529 | self.root_visited = true; 530 | self.stack.push(StackItem { child_iter: self.root.children.iter() }); 531 | if let Some(ref root_val) = self.root.value { 532 | return Some((vec![], root_val)); 533 | } 534 | } 535 | 536 | loop { 537 | let action = match self.stack.last_mut() { 538 | Some(stack_top) => { 539 | match stack_top.child_iter.next() { 540 | Some((fragment, child_node)) => Push(fragment, child_node), 541 | None => Pop, 542 | } 543 | } 544 | None => return None, 545 | }; 546 | 547 | match action { 548 | Push(fragment, node) => { 549 | self.stack.push(StackItem { child_iter: node.children.iter() }); 550 | self.key.push(fragment); 551 | if let Some(ref value) = node.value { 552 | return Some((self.key.clone(), value)); 553 | } 554 | } 555 | Pop => { 556 | self.key.pop(); 557 | self.stack.pop(); 558 | } 559 | } 560 | } 561 | } 562 | } 563 | 564 | impl<'a, K, V, S> Iterator for Keys<'a, K, V, S> 565 | where K: TrieKey, 566 | S: BuildHasher + Default, 567 | { 568 | type Item = Vec<&'a K>; 569 | 570 | fn next(&mut self) -> Option> { 571 | self.inner.next().map(|(k, _)| k) 572 | } 573 | } 574 | 575 | impl<'a, K, V, S> Iterator for Values<'a, K, V, S> 576 | where K: TrieKey, 577 | S: BuildHasher + Default 578 | { 579 | type Item = &'a V; 580 | 581 | fn next(&mut self) -> Option<&'a V> { 582 | self.inner.next().map(|(_, v)| v) 583 | } 584 | } 585 | 586 | impl PartialEq for SequenceTrie 587 | where K: TrieKey, 588 | V: PartialEq, 589 | S: BuildHasher + Default 590 | { 591 | fn eq(&self, other: &Self) -> bool { 592 | self.value == other.value && self.children == other.children 593 | } 594 | } 595 | 596 | impl Eq for SequenceTrie 597 | where K: TrieKey, 598 | V: Eq, 599 | S: BuildHasher + Default 600 | {} 601 | 602 | impl Default for SequenceTrie 603 | where K: TrieKey, 604 | S: BuildHasher + Default + Clone 605 | { 606 | fn default() -> Self { 607 | #[cfg(not(feature = "btreemap"))] 608 | { SequenceTrie::with_hasher(S::default()) } 609 | #[cfg(feature = "btreemap")] 610 | { SequenceTrie::new_generic() } 611 | } 612 | } 613 | 614 | /// Iterator over the longest prefix of nodes which matches a key. 615 | pub struct PrefixIter<'trie, 'key, K, V, Q: ?Sized, I, S = RandomState> 616 | where K: 'trie + TrieKey, 617 | V: 'trie, 618 | I: 'key + Iterator, 619 | K: Borrow, 620 | Q: TrieKey + 'key, 621 | S: 'trie + BuildHasher + Default 622 | { 623 | next_node: Option<&'trie SequenceTrie>, 624 | fragments: I, 625 | _phantom: PhantomData<&'key I>, 626 | } 627 | 628 | impl<'trie, 'key, K, V, Q: ?Sized, I, S> Iterator for PrefixIter<'trie, 'key, K, V, Q, I, S> 629 | where K: 'trie + TrieKey, 630 | V: 'trie, 631 | I: 'key + Iterator, 632 | K: Borrow, 633 | Q: TrieKey + 'key, 634 | S: BuildHasher + Default 635 | { 636 | type Item = &'trie SequenceTrie; 637 | 638 | fn next(&mut self) -> Option { 639 | if let Some(current_node) = self.next_node.take() { 640 | if let Some(fragment) = self.fragments.next() { 641 | self.next_node = current_node.children.get(fragment) 642 | } 643 | 644 | return Some(current_node); 645 | } 646 | 647 | None 648 | } 649 | 650 | fn size_hint(&self) -> (usize, Option) { 651 | let lower = if self.next_node.is_some() { 652 | 1 653 | } else { 654 | 0 655 | }; 656 | 657 | (lower, self.fragments.size_hint().1) 658 | } 659 | } 660 | --------------------------------------------------------------------------------