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}