Skip to main content

leveled_hash_map/
lib.rs

1use std::{
2    collections::{HashMap, HashSet},
3    error::Error,
4    fmt::{self, Debug, Display, Formatter},
5    hash::Hash,
6    sync::Arc,
7};
8
9/// A single stored entry: the optional parent key at the superior level paired with the value.
10type Entry<K, V> = (Option<Arc<K>>, V);
11
12/// One level of the map, mapping each key to its entry.
13type Level<K, V> = HashMap<Arc<K>, Entry<K, V>>;
14
15/// The children of every key at one level, mapping each key to the set of its child keys at the inferior level.
16type ChildKeys<K> = HashMap<Arc<K>, HashSet<Arc<K>>>;
17
18/// The outcome of removing a node: its parent key, its value, and the levels of its removed subtree (`[i]` holds the descendants one level plus `i` below the removed node).
19type Removed<K, V> = (Option<Arc<K>>, V, Vec<Level<K, V>>);
20
21/// A structure to separate values into different levels with keys. Every key-value entry which is not at the top level has a parent key at the superior level. Keys at the same level are unique, no matter what parent keys they have.
22#[derive(Debug)]
23pub struct LeveledHashMap<K: Eq + Hash, V> {
24    pool: Vec<Level<K, V>>,
25    sub:  Vec<ChildKeys<K>>,
26}
27
28/// Possible errors come from `LeveledHashMap`.
29pub enum LeveledHashMapError<K> {
30    /// The length of a key chain is over the max level of a `LeveledHashMap`.
31    /// ```
32    /// use std::sync::Arc;
33    ///
34    /// use leveled_hash_map::{LeveledHashMap, LeveledHashMapError};
35    ///
36    /// let mut map = LeveledHashMap::new();
37    ///
38    /// map.insert(&[Arc::new("food")], 100).unwrap();
39    ///
40    /// // now the map has "Level 0", "Level 0" is available to be got, "Level 0" and "Level 1" are available to be inserted
41    ///
42    /// assert_eq!(&100, map.get_advanced(&[Arc::new("food")], 0).unwrap());
43    ///
44    /// // try to get value at "Level 1"
45    ///
46    /// match map.get_professional(&[Arc::new("food"), Arc::new("dessert")], 0) {
47    ///     Ok(_) => unreachable!(),
48    ///     Err(err) => match err {
49    ///         LeveledHashMapError::KeyTooMany => (),
50    ///         _ => unreachable!()
51    ///     }
52    /// }
53    ///
54    /// // try to insert value to "Level 2"
55    ///
56    /// match map.insert(&[Arc::new("food"), Arc::new("dessert"), Arc::new("cake")], 10) {
57    ///     Ok(_) => unreachable!(),
58    ///     Err(err) => match err {
59    ///         LeveledHashMapError::KeyTooMany => (),
60    ///         _ => unreachable!()
61    ///     }
62    /// }
63    ///
64    /// // try to insert value to "Level 1"
65    ///
66    /// match map.insert(&[Arc::new("food"), Arc::new("dessert")], 10) {
67    ///     Ok(_) => (),
68    ///     Err(err) => unreachable!()
69    /// }
70    /// ```
71    KeyTooMany,
72    /// The key chain is correct, but the last key in the key chain does not exist.
73    /// ```
74    /// use std::sync::Arc;
75    ///
76    /// use leveled_hash_map::{LeveledHashMap, LeveledHashMapError};
77    ///
78    /// let mut map = LeveledHashMap::new();
79    ///
80    /// map.insert(&[Arc::new("food")], 100).unwrap();
81    ///
82    /// map.insert(&[Arc::new("food"), Arc::new("dessert")], 100).unwrap();
83    ///
84    /// map.insert(&[Arc::new("food"), Arc::new("dessert"), Arc::new("cake")], 100)
85    ///     .unwrap();
86    ///
87    /// // try to get "food/dessert/chocolate"
88    ///
89    /// match map.get_professional(
90    ///     &[Arc::new("food"), Arc::new("dessert"), Arc::new("chocolate")],
91    ///     0,
92    /// ) {
93    ///     Ok(_) => unreachable!(),
94    ///     Err(err) => match err {
95    ///         LeveledHashMapError::KeyNotExist {
96    ///             level,
97    ///             key,
98    ///         } => {
99    ///             assert_eq!(2, level);
100    ///             assert_eq!(Arc::new("chocolate"), key);
101    ///         },
102    ///         _ => unreachable!(),
103    ///     },
104    /// }
105    /// ```
106    KeyNotExist { level: usize, key: Arc<K> },
107    /// The key chain is empty.
108    /// ```
109    /// use std::sync::Arc;
110    ///
111    /// use leveled_hash_map::{LeveledHashMap, LeveledHashMapError};
112    ///
113    /// let mut map = LeveledHashMap::new();
114    ///
115    /// map.insert(&[Arc::new("food")], 100).unwrap();
116    ///
117    /// // try to get ""
118    ///
119    /// match map.get_professional(&[], 0) {
120    ///     Ok(_) => unreachable!(),
121    ///     Err(err) => match err {
122    ///         LeveledHashMapError::KeyChainEmpty => (),
123    ///         _ => unreachable!(),
124    ///     },
125    /// }
126    /// ```
127    KeyChainEmpty,
128    /// The key chain is incorrect.
129    /// ```
130    /// use std::sync::Arc;
131    ///
132    /// use leveled_hash_map::{LeveledHashMap, LeveledHashMapError};
133    ///
134    /// let mut map = LeveledHashMap::new();
135    ///
136    /// map.insert(&[Arc::new("food")], 100).unwrap();
137    ///
138    /// map.insert(&[Arc::new("food"), Arc::new("meat")], 200).unwrap();
139    ///
140    /// map.insert(&[Arc::new("food"), Arc::new("dessert")], 100).unwrap();
141    ///
142    /// map.insert(&[Arc::new("food"), Arc::new("dessert"), Arc::new("cake")], 100)
143    ///     .unwrap();
144    ///
145    /// // try to get "food/meat/cake", here "food/meat" exists
146    ///
147    /// match map.get_professional(
148    ///     &[Arc::new("food"), Arc::new("meat"), Arc::new("cake")],
149    ///     0,
150    /// ) {
151    ///     Ok(_) => unreachable!(),
152    ///     Err(err) => match err {
153    ///         LeveledHashMapError::KeyChainIncorrect {
154    ///             level,
155    ///             key,
156    ///             last_key,
157    ///         } => {
158    ///             assert_eq!(2, level);
159    ///             assert_eq!(Arc::new("cake"), key);
160    ///             assert_eq!(Some(Arc::new("dessert")), last_key);
161    ///         },
162    ///         _ => unreachable!(),
163    ///     },
164    /// }
165    /// ```
166    KeyChainIncorrect { level: usize, key: Arc<K>, last_key: Option<Arc<K>> },
167}
168
169impl<K> Debug for LeveledHashMapError<K> {
170    #[inline]
171    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
172        match self {
173            LeveledHashMapError::KeyTooMany => f.write_str("KeyTooMany"),
174            LeveledHashMapError::KeyNotExist {
175                level, ..
176            } => {
177                let mut s = f.debug_struct("KeyNotExist");
178                s.field("Level", level);
179                s.finish()
180            },
181            LeveledHashMapError::KeyChainEmpty => f.write_str("KeyChainEmpty"),
182            LeveledHashMapError::KeyChainIncorrect {
183                level, ..
184            } => {
185                let mut s = f.debug_struct("KeyChainIncorrect");
186                s.field("Level", level);
187                s.finish()
188            },
189        }
190    }
191}
192
193impl<K> Display for LeveledHashMapError<K> {
194    #[inline]
195    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
196        match self {
197            LeveledHashMapError::KeyTooMany => f.write_str(
198                "The length of a key chain is over the max level of a `LeveledHashMap`.",
199            ),
200            LeveledHashMapError::KeyNotExist {
201                level, ..
202            } => write!(
203                f,
204                "The key chain is correct, but the last key at level {level} in the key chain \
205                 does not exist."
206            ),
207            LeveledHashMapError::KeyChainEmpty => f.write_str("The key chain is empty."),
208            LeveledHashMapError::KeyChainIncorrect {
209                level, ..
210            } => write!(f, "The key chain is incorrect at level {level}."),
211        }
212    }
213}
214
215impl<K> Error for LeveledHashMapError<K> {}
216
217impl<K> Clone for LeveledHashMapError<K> {
218    /// Clone the error. The `Arc<K>` keys are shared, so no `K: Clone` bound is required.
219    #[inline]
220    fn clone(&self) -> Self {
221        match self {
222            LeveledHashMapError::KeyTooMany => LeveledHashMapError::KeyTooMany,
223            LeveledHashMapError::KeyNotExist {
224                level,
225                key,
226            } => LeveledHashMapError::KeyNotExist {
227                level: *level, key: Arc::clone(key)
228            },
229            LeveledHashMapError::KeyChainEmpty => LeveledHashMapError::KeyChainEmpty,
230            LeveledHashMapError::KeyChainIncorrect {
231                level,
232                key,
233                last_key,
234            } => LeveledHashMapError::KeyChainIncorrect {
235                level:    *level,
236                key:      Arc::clone(key),
237                last_key: last_key.as_ref().map(Arc::clone),
238            },
239        }
240    }
241}
242
243impl<K: Eq + Hash, V> LeveledHashMap<K, V> {
244    /// Create a new `LeveledHashMap` instance. The key needs to be implemented `Eq` and `Hash` traits.
245    /// ```
246    /// use leveled_hash_map::LeveledHashMap;
247    ///
248    /// let _map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
249    /// ```
250    #[inline]
251    pub const fn new() -> LeveledHashMap<K, V> {
252        LeveledHashMap {
253            pool: Vec::new(), sub: Vec::new()
254        }
255    }
256
257    /// Walk the whole key chain from `start_level`, validating every intermediate link, and return the level index of the final key on success. Unlike `get_professional`, this does not clone the parent key.
258    fn locate(
259        &self,
260        key_chain: &[Arc<K>],
261        start_level: usize,
262    ) -> Result<usize, LeveledHashMapError<K>> {
263        let key_chain_len = key_chain.len();
264
265        if key_chain_len == 0 {
266            return Err(LeveledHashMapError::KeyChainEmpty);
267        } else if key_chain_len + start_level > self.pool.len() {
268            return Err(LeveledHashMapError::KeyTooMany);
269        }
270
271        let mut last_key: Option<&Arc<K>> = None;
272
273        for (i, ck) in key_chain.iter().enumerate() {
274            let ii = i + start_level;
275
276            match self.pool[ii].get(ck) {
277                Some((pk, _)) => {
278                    // The first key sits at `start_level` and has no parent to check against within this chain.
279                    if ii > start_level && last_key != pk.as_ref() {
280                        return Err(LeveledHashMapError::KeyChainIncorrect {
281                            level:    ii,
282                            key:      Arc::clone(ck),
283                            last_key: pk.as_ref().map(Arc::clone),
284                        });
285                    }
286                    last_key = Some(ck);
287                },
288                None => {
289                    return Err(LeveledHashMapError::KeyNotExist {
290                        level: ii,
291                        key:   Arc::clone(ck),
292                    });
293                },
294            }
295        }
296
297        Ok(key_chain_len - 1 + start_level)
298    }
299
300    /// Get a value by a key chain. The key chain starts at Level 0.
301    /// ```
302    /// use std::sync::Arc;
303    ///
304    /// use leveled_hash_map::LeveledHashMap;
305    ///
306    /// let map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
307    ///
308    /// let _result = map.get(&[Arc::new("first_key")]);
309    /// ```
310    #[inline]
311    pub fn get(&self, key_chain: &[Arc<K>]) -> Option<&V> {
312        self.get_advanced(key_chain, 0)
313    }
314
315    /// Get a value by a key chain. The key chain starts at Level 0.
316    /// ```
317    /// use std::sync::Arc;
318    ///
319    /// use leveled_hash_map::LeveledHashMap;
320    ///
321    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
322    ///
323    /// let _result = map.get_mut(&[Arc::new("first_key")]);
324    /// ```
325    #[inline]
326    pub fn get_mut(&mut self, key_chain: &[Arc<K>]) -> Option<&mut V> {
327        self.get_advanced_mut(key_chain, 0)
328    }
329
330    /// Get a value by a key chain and a level which the key chain starts with.
331    /// ```
332    /// use std::sync::Arc;
333    ///
334    /// use leveled_hash_map::LeveledHashMap;
335    ///
336    /// let map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
337    ///
338    /// let _result = map.get_advanced(&[Arc::new("second_key")], 1);
339    /// ```
340    #[inline]
341    pub fn get_advanced(&self, key_chain: &[Arc<K>], start_level: usize) -> Option<&V> {
342        let level = self.locate(key_chain, start_level).ok()?;
343
344        self.pool[level].get(&key_chain[key_chain.len() - 1]).map(|(_, v)| v)
345    }
346
347    /// Get a value by a key chain and a level which the key chain starts with.
348    /// ```
349    /// use std::sync::Arc;
350    ///
351    /// use leveled_hash_map::LeveledHashMap;
352    ///
353    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
354    ///
355    /// let _result = map.get_advanced_mut(&[Arc::new("second_key")], 1);
356    /// ```
357    #[inline]
358    pub fn get_advanced_mut(&mut self, key_chain: &[Arc<K>], start_level: usize) -> Option<&mut V> {
359        let level = self.locate(key_chain, start_level).ok()?;
360
361        self.pool[level].get_mut(&key_chain[key_chain.len() - 1]).map(|(_, v)| v)
362    }
363
364    /// Get a value and its parent key by a key chain and a level which the key chain starts with. It returns a `Err(LeveledHashMapError)` instance to describe the reason of the getting failure.
365    /// ```
366    /// use std::sync::Arc;
367    ///
368    /// use leveled_hash_map::LeveledHashMap;
369    ///
370    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
371    ///
372    /// map.insert(&[Arc::new("food")], "食物".to_string()).unwrap();
373    ///
374    /// map.insert(&[Arc::new("food"), Arc::new("dessert")], "甜點".to_string())
375    ///     .unwrap();
376    ///
377    /// let result_1 = map.get_professional(&[Arc::new("food")], 0).unwrap();
378    ///
379    /// let result_2 = map
380    ///     .get_professional(&[Arc::new("food"), Arc::new("dessert")], 0)
381    ///     .unwrap();
382    ///
383    /// assert_eq!(None, result_1.0);
384    /// assert_eq!("食物", result_1.1);
385    ///
386    /// assert_eq!(Some(Arc::new("food")), result_2.0);
387    /// assert_eq!("甜點", result_2.1);
388    /// ```
389    pub fn get_professional(
390        &self,
391        key_chain: &[Arc<K>],
392        start_level: usize,
393    ) -> Result<(Option<Arc<K>>, &V), LeveledHashMapError<K>> {
394        let level = self.locate(key_chain, start_level)?;
395
396        // `locate` already confirmed the final key exists at this level.
397        let (pk, v) = self.pool[level].get(&key_chain[key_chain.len() - 1]).unwrap();
398
399        Ok((pk.as_ref().map(Arc::clone), v))
400    }
401
402    /// Get a value and its parent key by a key chain and a level which the key chain starts with. It returns a `Err(LeveledHashMapError)` instance to describe the reason of the getting failure.
403    /// ```
404    /// use std::sync::Arc;
405    ///
406    /// use leveled_hash_map::LeveledHashMap;
407    ///
408    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
409    ///
410    /// map.insert(&[Arc::new("food")], "食物".to_string()).unwrap();
411    ///
412    /// map.insert(&[Arc::new("food"), Arc::new("dessert")], "甜點".to_string())
413    ///     .unwrap();
414    ///
415    /// let result = map.get_professional_mut(&[Arc::new("food")], 0).unwrap();
416    ///
417    /// result.1.push_str("/食品");
418    ///
419    /// assert_eq!(None, result.0);
420    /// assert_eq!("食物/食品", result.1);
421    /// ```
422    pub fn get_professional_mut(
423        &mut self,
424        key_chain: &[Arc<K>],
425        start_level: usize,
426    ) -> Result<(Option<Arc<K>>, &mut V), LeveledHashMapError<K>> {
427        let level = self.locate(key_chain, start_level)?;
428
429        // `locate` already confirmed the final key exists at this level.
430        let (pk, v) = self.pool[level].get_mut(&key_chain[key_chain.len() - 1]).unwrap();
431
432        Ok((pk.as_ref().map(Arc::clone), v))
433    }
434
435    /// Remove a value by a key chain. The key chain starts at Level 0.
436    /// ```
437    /// use std::sync::Arc;
438    ///
439    /// use leveled_hash_map::LeveledHashMap;
440    ///
441    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
442    ///
443    /// map.insert(&[Arc::new("food")], "食物".to_string()).unwrap();
444    ///
445    /// map.insert(&[Arc::new("food"), Arc::new("dessert")], "甜點".to_string())
446    ///     .unwrap();
447    ///
448    /// map.insert(&[Arc::new("food"), Arc::new("meat")], "肉類".to_string())
449    ///     .unwrap();
450    ///
451    /// let result = map.remove(&[Arc::new("food"), Arc::new("dessert")]).unwrap();
452    ///
453    /// assert_eq!("甜點", result.0);
454    /// assert_eq!(0, result.1.len());
455    ///
456    /// let result = map.remove(&[Arc::new("food")]).unwrap();
457    ///
458    /// assert_eq!("食物", result.0);
459    /// assert_eq!(1, result.1.len());
460    /// assert_eq!(
461    ///     &(Some(Arc::new("food")), "肉類".to_string()),
462    ///     result.1[0].get(&Arc::new("meat")).unwrap()
463    /// );
464    /// ```
465    #[inline]
466    pub fn remove(&mut self, key_chain: &[Arc<K>]) -> Option<(V, Vec<Level<K, V>>)> {
467        self.remove_advanced(key_chain, 0)
468    }
469
470    /// Remove a value by a key chain and a level which the key chain starts with.
471    /// ```
472    /// use std::sync::Arc;
473    ///
474    /// use leveled_hash_map::LeveledHashMap;
475    ///
476    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
477    ///
478    /// map.insert(&[Arc::new("food")], "食物".to_string()).unwrap();
479    ///
480    /// map.insert(&[Arc::new("food"), Arc::new("dessert")], "甜點".to_string())
481    ///     .unwrap();
482    ///
483    /// map.insert(&[Arc::new("food"), Arc::new("meat")], "肉類".to_string())
484    ///     .unwrap();
485    ///
486    /// let result = map.remove_advanced(&[Arc::new("dessert")], 1).unwrap();
487    ///
488    /// assert_eq!("甜點", result.0);
489    /// assert_eq!(0, result.1.len());
490    ///
491    /// let result = map.remove_advanced(&[Arc::new("food")], 0).unwrap();
492    ///
493    /// assert_eq!("食物", result.0);
494    /// assert_eq!(1, result.1.len());
495    /// assert_eq!(
496    ///     &(Some(Arc::new("food")), "肉類".to_string()),
497    ///     result.1[0].get(&Arc::new("meat")).unwrap()
498    /// );
499    /// ```
500    #[inline]
501    pub fn remove_advanced(
502        &mut self,
503        key_chain: &[Arc<K>],
504        start_level: usize,
505    ) -> Option<(V, Vec<Level<K, V>>)> {
506        self.remove_professional(key_chain, start_level).ok().map(|v| (v.1, v.2))
507    }
508
509    /// Remove a value by a key chain and a level which the key chain starts with. It returns a `Err(LeveledHashMapError)` instance to describe the reason of the getting failure.
510    /// ```
511    /// use std::sync::Arc;
512    ///
513    /// use leveled_hash_map::LeveledHashMap;
514    ///
515    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
516    ///
517    /// map.insert(&[Arc::new("food")], "食物".to_string()).unwrap();
518    ///
519    /// map.insert(&[Arc::new("food"), Arc::new("dessert")], "甜點".to_string())
520    ///     .unwrap();
521    ///
522    /// map.insert(&[Arc::new("food"), Arc::new("meat")], "肉類".to_string())
523    ///     .unwrap();
524    ///
525    /// let result = map.remove_professional(&[Arc::new("dessert")], 1).unwrap();
526    ///
527    /// assert_eq!(Some(Arc::new("food")), result.0);
528    /// assert_eq!("甜點", result.1);
529    /// assert_eq!(0, result.2.len());
530    ///
531    /// let result = map.remove_professional(&[Arc::new("food")], 0).unwrap();
532    ///
533    /// assert_eq!(None, result.0);
534    /// assert_eq!("食物", result.1);
535    /// assert_eq!(1, result.2.len());
536    /// assert_eq!(
537    ///     &(Some(Arc::new("food")), "肉類".to_string()),
538    ///     result.2[0].get(&Arc::new("meat")).unwrap()
539    /// );
540    /// ```
541    pub fn remove_professional(
542        &mut self,
543        key_chain: &[Arc<K>],
544        start_level: usize,
545    ) -> Result<Removed<K, V>, LeveledHashMapError<K>> {
546        let last_key = self.get_professional(key_chain, start_level)?.0;
547
548        let key_chain_len = key_chain.len();
549
550        let key_chain_len_dec = key_chain_len - 1;
551
552        let level = key_chain_len_dec + start_level;
553
554        let (pk, v) = self.pool[level].remove(&key_chain[key_chain_len_dec]).unwrap();
555
556        if level > 0 {
557            if let Some(v) = self.sub[level - 1].get_mut(&last_key.unwrap()) {
558                v.remove(&key_chain[key_chain_len_dec]);
559            }
560        }
561
562        let sub = self.sub[level].remove(&key_chain[key_chain_len_dec]).unwrap();
563
564        if sub.is_empty() {
565            return Ok((pk, v, Vec::new()));
566        }
567
568        // `levels[i]` collects every removed descendant living at `level + 1 + i`.
569        let mut levels: Vec<Level<K, V>> = Vec::new();
570        let mut direct_children = HashMap::new();
571
572        for s in sub {
573            let (parent, value, descendants) =
574                self.remove_professional(&[Arc::clone(&s)], level + 1).unwrap();
575
576            // Merge each depth of this child's subtree into the shared depth-aligned accumulator.
577            for (i, descendant_level) in descendants.into_iter().enumerate() {
578                match levels.get_mut(i) {
579                    Some(existing) => existing.extend(descendant_level),
580                    None => levels.push(descendant_level),
581                }
582            }
583
584            direct_children.insert(s, (parent, value));
585        }
586
587        levels.insert(0, direct_children);
588
589        Ok((pk, v, levels))
590    }
591
592    /// Insert a value by a key chain. It returns a `Err(LeveledHashMapError)` instance to describe the reason of the getting failure.
593    /// ```
594    /// use std::sync::Arc;
595    ///
596    /// use leveled_hash_map::LeveledHashMap;
597    ///
598    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
599    ///
600    /// map.insert(&[Arc::new("food")], "食物".to_string()).unwrap();
601    ///
602    /// {
603    ///     let result = map.get(&[Arc::new("food")]).unwrap();
604    ///
605    ///     assert_eq!("食物", result);
606    /// }
607    ///
608    /// let result = map.insert(&[Arc::new("food")], "食品".to_string()).unwrap();
609    ///
610    /// assert_eq!(Some("食物".to_string()), result);
611    ///
612    /// let result = map.get(&[Arc::new("food")]).unwrap();
613    ///
614    /// assert_eq!("食品", result);
615    /// ```
616    pub fn insert(
617        &mut self,
618        key_chain: &[Arc<K>],
619        value: V,
620    ) -> Result<Option<V>, LeveledHashMapError<K>> {
621        let key_chain_len = key_chain.len();
622
623        if key_chain_len == 0 {
624            return Err(LeveledHashMapError::KeyChainEmpty);
625        }
626
627        let last = key_chain_len - 1;
628
629        // Validate the parent chain first so we never build a dangling link. Any error (a missing intermediate key, an incorrect link, or too many keys) is reported to the caller instead of corrupting the map.
630        if last > 0 {
631            self.locate(&key_chain[..last], 0)?;
632        }
633
634        let final_key = &key_chain[last];
635
636        match self.pool.get(last).and_then(|level| level.get(final_key)) {
637            Some((pk, _)) => {
638                // The key already exists, so make sure it hangs under the expected parent before overwriting it.
639                let expected_parent = if last > 0 { Some(&key_chain[last - 1]) } else { None };
640
641                if pk.as_ref() != expected_parent {
642                    return Err(LeveledHashMapError::KeyChainIncorrect {
643                        level:    last,
644                        key:      Arc::clone(final_key),
645                        last_key: pk.as_ref().map(Arc::clone),
646                    });
647                }
648
649                let parent = expected_parent.map(Arc::clone);
650
651                Ok(self.pool[last].insert(Arc::clone(final_key), (parent, value)).map(|v| v.1))
652            },
653            None => {
654                // A brand-new key. Append a fresh deepest level when this key introduces one.
655                if last == self.pool.len() {
656                    self.pool.push(HashMap::new());
657                    self.sub.push(HashMap::new());
658                }
659
660                let parent = if last > 0 { Some(Arc::clone(&key_chain[last - 1])) } else { None };
661
662                self.pool[last].insert(Arc::clone(final_key), (parent, value));
663                self.sub[last].insert(Arc::clone(final_key), HashSet::new());
664
665                if last > 0 {
666                    self.sub[last - 1]
667                        .get_mut(&key_chain[last - 1])
668                        .unwrap()
669                        .insert(Arc::clone(final_key));
670                }
671
672                Ok(None)
673            },
674        }
675    }
676
677    /// Insert values by a key chain and a `HashMap` instance and a level which the key chain starts with. It returns a `Err(LeveledHashMapError)` instance to describe the reason of the getting failure.
678    /// ```
679    /// use std::{collections::HashMap, sync::Arc};
680    ///
681    /// use leveled_hash_map::LeveledHashMap;
682    ///
683    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
684    ///
685    /// map.insert(&[Arc::new("food")], "食物".to_string()).unwrap();
686    ///
687    /// let mut insert_map = HashMap::new();
688    ///
689    /// insert_map.insert("dessert", "甜點".to_string());
690    /// insert_map.insert("meat", "肉類".to_string());
691    ///
692    /// map.insert_many(&[Arc::new("food")], insert_map, 0).unwrap();
693    ///
694    /// let result = map.get(&[Arc::new("food"), Arc::new("dessert")]).unwrap();
695    ///
696    /// assert_eq!("甜點", result);
697    ///
698    /// let result = map.get(&[Arc::new("food"), Arc::new("meat")]).unwrap();
699    ///
700    /// assert_eq!("肉類", result);
701    /// ```
702    pub fn insert_many(
703        &mut self,
704        key_chain: &[Arc<K>],
705        value: HashMap<K, V>,
706        start_level: usize,
707    ) -> Result<HashMap<Arc<K>, V>, LeveledHashMapError<K>> {
708        let key_chain_len = key_chain.len();
709
710        if key_chain_len > self.pool.len() + 1 {
711            return Err(LeveledHashMapError::KeyTooMany);
712        }
713
714        match self.get_professional(key_chain, start_level) {
715            Ok(_) => {
716                let key_chain_len_dec = key_chain_len - 1;
717
718                let mut previous = HashMap::new();
719
720                let level = key_chain_len + start_level;
721
722                if level >= self.pool.len() {
723                    self.pool.push(HashMap::new());
724                    self.sub.push(HashMap::new());
725                }
726
727                let last_key = &key_chain[key_chain_len_dec];
728
729                let mut temp = HashMap::new();
730
731                for (k, v) in value {
732                    let k = Arc::new(k);
733
734                    if let Some((pk, _)) = self.pool[level].get(&k) {
735                        if last_key.ne(pk.as_ref().unwrap()) {
736                            return Err(LeveledHashMapError::KeyChainIncorrect {
737                                level,
738                                key: Arc::clone(&k),
739                                last_key: pk.as_ref().map(Arc::clone),
740                            });
741                        }
742                    }
743
744                    temp.insert(k, v);
745                }
746
747                for (k, v) in temp {
748                    match self.pool[level].insert(Arc::clone(&k), (Some(Arc::clone(last_key)), v)) {
749                        Some((_, v)) => {
750                            previous.insert(k, v);
751                        },
752                        None => {
753                            self.sub[level].insert(Arc::clone(&k), HashSet::new());
754                            self.sub[level - 1].get_mut(last_key).unwrap().insert(Arc::clone(&k));
755                        },
756                    }
757                }
758
759                Ok(previous)
760            },
761            Err(err) => match err {
762                LeveledHashMapError::KeyChainIncorrect {
763                    level,
764                    key,
765                    last_key,
766                } => Err(LeveledHashMapError::KeyChainIncorrect {
767                    level,
768                    key,
769                    last_key,
770                }),
771                LeveledHashMapError::KeyNotExist {
772                    level,
773                    key,
774                } => Err(LeveledHashMapError::KeyNotExist {
775                    level,
776                    key,
777                }),
778                LeveledHashMapError::KeyTooMany => Err(LeveledHashMapError::KeyTooMany),
779                LeveledHashMapError::KeyChainEmpty => {
780                    if start_level > 0 {
781                        return Err(LeveledHashMapError::KeyChainEmpty);
782                    }
783
784                    if self.pool.is_empty() {
785                        self.pool.push(HashMap::new());
786                        self.sub.push(HashMap::new());
787                    }
788
789                    let mut previous = HashMap::new();
790
791                    for (k, v) in value {
792                        let k = Arc::new(k);
793                        match self.pool[0].insert(Arc::clone(&k), (None, v)) {
794                            Some((_, v)) => {
795                                previous.insert(k, v);
796                            },
797                            None => {
798                                self.sub[0].insert(Arc::clone(&k), HashSet::new());
799                            },
800                        }
801                    }
802
803                    Ok(previous)
804                },
805            },
806        }
807    }
808
809    /// Get the keys at a specific level.
810    /// ```
811    /// use std::{collections::HashMap, sync::Arc};
812    ///
813    /// use leveled_hash_map::LeveledHashMap;
814    ///
815    /// let mut map: LeveledHashMap<&'static str, String> = LeveledHashMap::new();
816    ///
817    /// map.insert(&[Arc::new("food")], "食物".to_string()).unwrap();
818    ///
819    /// let mut insert_map = HashMap::new();
820    ///
821    /// insert_map.insert("dessert", "甜點".to_string());
822    /// insert_map.insert("meat", "肉類".to_string());
823    ///
824    /// map.insert_many(&[Arc::new("food")], insert_map, 0).unwrap();
825    ///
826    /// let result = map.keys(0).unwrap();
827    ///
828    /// assert_eq!(1, result.len());
829    ///
830    /// let result = map.keys(1).unwrap();
831    ///
832    /// assert_eq!(2, result.len());
833    /// ```
834    #[inline]
835    pub fn keys(&self, level: usize) -> Option<&ChildKeys<K>> {
836        self.sub.get(level)
837    }
838
839    /// Get the number of levels currently allocated in this `LeveledHashMap`.
840    /// ```
841    /// use std::sync::Arc;
842    ///
843    /// use leveled_hash_map::LeveledHashMap;
844    ///
845    /// let mut map: LeveledHashMap<&'static str, u8> = LeveledHashMap::new();
846    ///
847    /// assert_eq!(0, map.levels());
848    ///
849    /// map.insert(&[Arc::new("food")], 100).unwrap();
850    /// map.insert(&[Arc::new("food"), Arc::new("dessert")], 10).unwrap();
851    ///
852    /// assert_eq!(2, map.levels());
853    /// ```
854    #[inline]
855    pub const fn levels(&self) -> usize {
856        self.pool.len()
857    }
858
859    /// Get the total number of entries stored across all levels.
860    /// ```
861    /// use std::sync::Arc;
862    ///
863    /// use leveled_hash_map::LeveledHashMap;
864    ///
865    /// let mut map: LeveledHashMap<&'static str, u8> = LeveledHashMap::new();
866    ///
867    /// map.insert(&[Arc::new("food")], 100).unwrap();
868    /// map.insert(&[Arc::new("food"), Arc::new("dessert")], 10).unwrap();
869    ///
870    /// assert_eq!(2, map.len());
871    /// ```
872    #[inline]
873    pub fn len(&self) -> usize {
874        self.pool.iter().map(HashMap::len).sum()
875    }
876
877    /// Return whether this `LeveledHashMap` holds no entry at all. An empty top level means every level is empty, because a deeper key always needs a parent above it.
878    /// ```
879    /// use std::sync::Arc;
880    ///
881    /// use leveled_hash_map::LeveledHashMap;
882    ///
883    /// let mut map: LeveledHashMap<&'static str, u8> = LeveledHashMap::new();
884    ///
885    /// assert!(map.is_empty());
886    ///
887    /// map.insert(&[Arc::new("food")], 100).unwrap();
888    ///
889    /// assert!(!map.is_empty());
890    /// ```
891    #[inline]
892    pub fn is_empty(&self) -> bool {
893        match self.pool.first() {
894            Some(level) => level.is_empty(),
895            None => true,
896        }
897    }
898
899    /// Return whether a value exists for the given key chain, which starts at Level 0.
900    /// ```
901    /// use std::sync::Arc;
902    ///
903    /// use leveled_hash_map::LeveledHashMap;
904    ///
905    /// let mut map: LeveledHashMap<&'static str, u8> = LeveledHashMap::new();
906    ///
907    /// map.insert(&[Arc::new("food")], 100).unwrap();
908    ///
909    /// assert!(map.contains_key(&[Arc::new("food")]));
910    /// assert!(!map.contains_key(&[Arc::new("drink")]));
911    /// ```
912    #[inline]
913    pub fn contains_key(&self, key_chain: &[Arc<K>]) -> bool {
914        self.get(key_chain).is_some()
915    }
916
917    /// Remove every entry and level, resetting this `LeveledHashMap` to its initial state.
918    /// ```
919    /// use std::sync::Arc;
920    ///
921    /// use leveled_hash_map::LeveledHashMap;
922    ///
923    /// let mut map: LeveledHashMap<&'static str, u8> = LeveledHashMap::new();
924    ///
925    /// map.insert(&[Arc::new("food")], 100).unwrap();
926    ///
927    /// map.clear();
928    ///
929    /// assert!(map.is_empty());
930    /// assert_eq!(0, map.levels());
931    /// ```
932    #[inline]
933    pub fn clear(&mut self) {
934        self.pool.clear();
935        self.sub.clear();
936    }
937}
938
939impl<K: Eq + Hash, V> Default for LeveledHashMap<K, V> {
940    #[inline]
941    fn default() -> Self {
942        LeveledHashMap::new()
943    }
944}