1mod sparse_array_usize;
2
3use super::entry::Entry;
4use crate::List;
5use crate::list;
6use crate::utils::DefaultBuildHasher;
7use alloc::vec::Vec;
8use archery::{ArcTK, RcK, SharedPointer, SharedPointerKind};
9use core::borrow::Borrow;
10use core::fmt::Display;
11use core::hash::BuildHasher;
12use core::hash::Hash;
13use core::iter;
14use core::iter::FromIterator;
15use core::ops::Index;
16use core::slice;
17use sparse_array_usize::SparseArrayUsize;
18
19type HashValue = u64;
20
21pub type Iter<'a, K, V, P> =
23 iter::Map<IterPtr<'a, K, V, P>, fn(&'a SharedPointer<Entry<K, V>, P>) -> (&'a K, &'a V)>;
24pub type IterKeys<'a, K, V, P> = iter::Map<Iter<'a, K, V, P>, fn((&'a K, &V)) -> &'a K>;
25pub type IterValues<'a, K, V, P> = iter::Map<Iter<'a, K, V, P>, fn((&K, &'a V)) -> &'a V>;
26
27#[allow(clippy::cast_possible_truncation)]
28const DEFAULT_DEGREE: u8 = usize::BITS as u8;
29
30#[macro_export]
43macro_rules! ht_map {
44 ($($k:expr => $v:expr),*) => {
45 {
46 #[allow(unused_mut)]
47 let mut m = $crate::HashTrieMap::new();
48 $(
49 m.insert_mut($k, $v);
50 )*
51 m
52 }
53 };
54}
55
56#[macro_export]
70macro_rules! ht_map_sync {
71 ($($k:expr => $v:expr),*) => {
72 {
73 #[allow(unused_mut)]
74 let mut m = $crate::HashTrieMap::new_sync();
75 $(
76 m.insert_mut($k, $v);
77 )*
78 m
79 }
80 };
81}
82
83#[derive(Debug)]
114pub struct HashTrieMap<K, V, P = RcK, H: BuildHasher = DefaultBuildHasher>
115where
116 P: SharedPointerKind,
117{
118 root: SharedPointer<Node<K, V, P>, P>,
119 size: usize,
120 degree: u8,
121 hasher_builder: H,
122}
123
124pub type HashTrieMapSync<K, V, H = DefaultBuildHasher> = HashTrieMap<K, V, ArcTK, H>;
125
126#[derive(Debug)]
181enum Node<K, V, P = RcK>
182where
183 P: SharedPointerKind,
184{
185 Branch(SparseArrayUsize<SharedPointer<Node<K, V, P>, P>>),
186 Leaf(Bucket<K, V, P>),
187}
188
189#[derive(Debug)]
190enum Bucket<K, V, P = RcK>
191where
192 P: SharedPointerKind,
193{
194 Single(EntryWithHash<K, V, P>),
195 Collision(List<EntryWithHash<K, V, P>, P>),
196}
197
198#[derive(Debug)]
199struct EntryWithHash<K, V, P = RcK>
200where
201 P: SharedPointerKind,
202{
203 entry: SharedPointer<Entry<K, V>, P>,
204 key_hash: HashValue,
205}
206
207mod node_utils {
208 use super::HashValue;
209 use core::hash::BuildHasher;
210 use core::hash::Hash;
211 use core::mem::size_of_val;
212
213 #[inline]
217 pub fn index_from_hash(hash: HashValue, depth: usize, degree: u8) -> Option<usize> {
218 debug_assert!(degree.is_power_of_two());
219
220 #[allow(clippy::cast_possible_truncation)]
221 let shift = depth as u32 * degree.trailing_zeros();
222
223 #[allow(clippy::cast_lossless)]
224 if (shift as usize) < 8 * size_of_val(&hash) {
225 let mask = degree as HashValue - 1;
226 #[allow(clippy::cast_possible_truncation)]
227 Some(((hash >> shift) & mask) as usize)
228 } else {
229 None
230 }
231 }
232
233 pub fn hash<T: ?Sized + Hash, H: BuildHasher>(v: &T, hasher_builder: &H) -> HashValue {
234 hasher_builder.hash_one(v)
235 }
236}
237
238impl<K, V, P> Node<K, V, P>
239where
240 K: Eq + Hash,
241 P: SharedPointerKind,
242{
243 fn new_empty_branch() -> Node<K, V, P> {
244 Node::Branch(SparseArrayUsize::new())
245 }
246
247 fn get<Q: ?Sized>(
248 &self,
249 key: &Q,
250 key_hash: HashValue,
251 depth: usize,
252 degree: u8,
253 ) -> Option<&EntryWithHash<K, V, P>>
254 where
255 K: Borrow<Q>,
256 Q: Hash + Eq,
257 {
258 match self {
259 Node::Branch(subtrees) => {
260 let index: usize = node_utils::index_from_hash(key_hash, depth, degree)
261 .expect("hash cannot be exhausted if we are on a branch");
262
263 subtrees
264 .get(index)
265 .and_then(|subtree| subtree.get(key, key_hash, depth + 1, degree))
266 }
267 Node::Leaf(bucket) => bucket.get(key, key_hash),
268 }
269 }
270
271 fn get_mut<Q: ?Sized>(
272 &mut self,
273 key: &Q,
274 key_hash: HashValue,
275 depth: usize,
276 degree: u8,
277 ) -> Option<&mut EntryWithHash<K, V, P>>
278 where
279 K: Borrow<Q>,
280 Q: Hash + Eq,
281 {
282 match self {
283 Node::Branch(subtrees) => {
284 let index: usize = node_utils::index_from_hash(key_hash, depth, degree)
285 .expect("hash cannot be exhausted if we are on a branch");
286
287 subtrees.get_mut(index).and_then(|subtree| {
288 SharedPointer::make_mut(subtree).get_mut(key, key_hash, depth + 1, degree)
289 })
290 }
291 Node::Leaf(bucket) => bucket.get_mut(key, key_hash),
292 }
293 }
294
295 fn insert(&mut self, entry: EntryWithHash<K, V, P>, depth: usize, degree: u8) -> bool {
297 match self {
298 Node::Branch(subtrees) => {
299 let index: usize = node_utils::index_from_hash(entry.key_hash, depth, degree)
300 .expect("hash cannot be exhausted if we are on a branch");
301
302 match subtrees.get_mut(index) {
303 Some(subtree) => {
304 SharedPointer::make_mut(subtree).insert(entry, depth + 1, degree)
305 }
306
307 None => {
308 let new_subtree = Node::Leaf(Bucket::Single(entry));
309 subtrees.set(index, SharedPointer::new(new_subtree));
310 true
311 }
312 }
313 }
314 Node::Leaf(bucket) => {
315 let maximum_depth =
318 node_utils::index_from_hash(entry.key_hash, depth, degree).is_none();
319
320 let bucket_contains_key: bool = bucket.contains_key(entry.key(), entry.key_hash);
321
322 match maximum_depth {
323 false if bucket_contains_key => bucket.insert(entry),
326
327 false => {
331 let old_entry: EntryWithHash<K, V, P> = match bucket {
333 Bucket::Single(e) => e.clone(),
334 Bucket::Collision(_) => unreachable!(
335 "hash is not exhausted, so there cannot be a collision here"
336 ),
337 };
338
339 *self = Node::new_empty_branch();
340
341 self.insert(old_entry, depth, degree);
342 self.insert(entry, depth, degree);
343
344 true
345 }
346
347 true => bucket.insert(entry),
349 }
350 }
351 }
352 }
353
354 fn compress(&mut self) {
357 let new_node = match self {
358 Node::Branch(subtrees) => {
359 match subtrees.size() {
360 1 => {
361 let compress: bool = {
362 let subtree = subtrees.first().unwrap();
363
364 matches!(subtree.borrow(), Node::Leaf(Bucket::Single(_)))
366 };
367
368 match compress {
369 true => subtrees.pop(),
370 false => None,
371 }
372 }
373 _ => None,
374 }
375 }
376 Node::Leaf(_) => None,
377 };
378
379 if let Some(node) = new_node {
380 crate::utils::replace(self, node);
381 }
382 }
383
384 fn remove<Q: ?Sized>(&mut self, key: &Q, key_hash: HashValue, depth: usize, degree: u8) -> bool
386 where
387 K: Borrow<Q>,
388 Q: Hash + Eq,
389 {
390 match self {
391 Node::Branch(subtrees) => {
392 let index: usize = node_utils::index_from_hash(key_hash, depth, degree)
393 .expect("hash cannot be exhausted if we are on a branch");
394
395 match subtrees.get_mut(index) {
396 Some(subtree) => {
397 let subtree = SharedPointer::make_mut(subtree);
398 let removed = subtree.remove(key, key_hash, depth + 1, degree);
399
400 match (subtree.is_empty(), removed) {
401 (_, false) => (),
402 (false, true) => {
403 self.compress();
408 }
409 (true, true) => {
410 subtrees.remove(index);
411
412 self.compress();
413 }
414 }
415
416 removed
417 }
418
419 None => false,
420 }
421 }
422
423 Node::Leaf(bucket) => {
424 let mut bucket_ref = Some(bucket);
425 let removed = Bucket::remove(&mut bucket_ref, key, key_hash);
426
427 if bucket_ref.is_none() {
428 *self = Node::new_empty_branch();
434 }
435
436 removed
437 }
438 }
439 }
440
441 fn is_empty(&self) -> bool {
442 match self {
443 Node::Branch(subtrees) => subtrees.size() == 0,
444 Node::Leaf(Bucket::Single(_)) => false,
445 Node::Leaf(Bucket::Collision(entries)) => {
446 debug_assert!(entries.len() >= 2, "collisions must have at least two entries");
447 false
448 }
449 }
450 }
451}
452
453impl<K, V, P> Clone for Node<K, V, P>
454where
455 K: Eq + Hash,
456 P: SharedPointerKind,
457{
458 fn clone(&self) -> Node<K, V, P> {
459 match self {
460 Node::Branch(subtrees) => Node::Branch(subtrees.clone()),
461 Node::Leaf(bucket) => Node::Leaf(bucket.clone()),
462 }
463 }
464}
465
466mod bucket_utils {
467 use super::*;
468
469 pub fn list_remove_first<T: Clone, P: SharedPointerKind, F: Fn(&T) -> bool>(
470 list: &mut List<T, P>,
471 predicate: F,
472 ) -> Option<T> {
473 let mut before_needle: Vec<T> = Vec::with_capacity(list.len());
474 let remaining: &mut List<T, P> = list;
475 let mut removed = None;
476
477 while !remaining.is_empty() {
478 let e: T = remaining.first().unwrap().clone();
479
480 remaining.drop_first_mut();
481
482 if predicate(&e) {
483 removed = Some(e);
484 break;
485 }
486
487 before_needle.push(e);
488 }
489
490 let new_entries = remaining;
491
492 while let Some(e) = before_needle.pop() {
493 new_entries.push_front_mut(e);
494 }
495
496 removed
497 }
498}
499
500impl<K, V, P> Bucket<K, V, P>
501where
502 K: Eq + Hash,
503 P: SharedPointerKind,
504{
505 fn get<Q: ?Sized>(&self, key: &Q, key_hash: HashValue) -> Option<&EntryWithHash<K, V, P>>
506 where
507 K: Borrow<Q>,
508 Q: Hash + Eq,
509 {
510 match self {
511 Bucket::Single(entry) if entry.matches(key, key_hash) => Some(entry),
512 Bucket::Single(_) => None,
513 Bucket::Collision(entries) => entries.iter().find(|e| e.matches(key, key_hash)),
514 }
515 }
516
517 fn get_mut<Q: ?Sized>(
518 &mut self,
519 key: &Q,
520 key_hash: HashValue,
521 ) -> Option<&mut EntryWithHash<K, V, P>>
522 where
523 K: Borrow<Q>,
524 Q: Hash + Eq,
525 {
526 match self {
527 Bucket::Single(entry) if entry.matches(key, key_hash) => Some(entry),
528 Bucket::Single(_) => None,
529 Bucket::Collision(entries) => {
530 let removed =
531 bucket_utils::list_remove_first(entries, |e| e.matches(key, key_hash));
532 removed.and_then(|e| {
533 entries.push_front_mut(e);
534 entries.first_mut()
535 })
536 }
537 }
538 }
539
540 #[inline]
541 fn contains_key<Q: ?Sized>(&self, key: &Q, key_hash: HashValue) -> bool
542 where
543 K: Borrow<Q>,
544 Q: Hash + Eq,
545 {
546 self.get(key, key_hash).is_some()
547 }
548
549 fn insert(&mut self, entry: EntryWithHash<K, V, P>) -> bool {
556 match self {
557 Bucket::Single(existing_entry)
558 if existing_entry.matches(entry.key(), entry.key_hash) =>
559 {
560 *existing_entry = entry;
561 false
562 }
563 Bucket::Single(existing_entry) => {
564 let mut entries = List::new_with_ptr_kind();
565
566 entries.push_front_mut(existing_entry.clone());
568 entries.push_front_mut(entry);
569
570 *self = Bucket::Collision(entries);
571
572 true
573 }
574 Bucket::Collision(entries) => {
575 let key_existed = bucket_utils::list_remove_first(entries, |e| {
576 e.matches(entry.key(), entry.key_hash)
577 })
578 .is_some();
579
580 entries.push_front_mut(entry);
581
582 !key_existed
583 }
584 }
585 }
586
587 fn remove<Q: ?Sized>(
591 bucket: &mut Option<&mut Bucket<K, V, P>>,
592 key: &Q,
593 key_hash: HashValue,
594 ) -> bool
595 where
596 K: Borrow<Q>,
597 Q: Hash + Eq,
598 {
599 match bucket.take() {
600 Some(b) => {
601 match b {
602 Bucket::Single(existing_entry) if existing_entry.matches(key, key_hash) => {
603 true
605 }
606 Bucket::Single(_) => {
607 *bucket = Some(b);
609 false
610 }
611
612 Bucket::Collision(entries) => {
613 let removed =
614 bucket_utils::list_remove_first(entries, |e| e.matches(key, key_hash))
615 .is_some();
616
617 match entries.len() {
618 0 => unreachable!(
619 "impossible to have collision with a single or no entry"
620 ),
621 1 => {
622 let entry = entries.first().unwrap().clone();
623
624 *b = Bucket::Single(entry);
625 }
626 _ => (),
627 }
628
629 *bucket = Some(b);
630
631 removed
632 }
633 }
634 }
635 None => false,
636 }
637 }
638}
639
640impl<K, V, P> Clone for Bucket<K, V, P>
641where
642 K: Eq + Hash,
643 P: SharedPointerKind,
644{
645 fn clone(&self) -> Bucket<K, V, P> {
646 match self {
647 Bucket::Single(entry) => Bucket::Single(EntryWithHash::clone(entry)),
648 Bucket::Collision(entries) => Bucket::Collision(List::clone(entries)),
649 }
650 }
651}
652
653impl<K, V, P> EntryWithHash<K, V, P>
654where
655 K: Eq + Hash,
656 P: SharedPointerKind,
657{
658 fn new<H: BuildHasher>(key: K, value: V, hash_builder: &H) -> EntryWithHash<K, V, P> {
659 let key_hash = node_utils::hash(&key, hash_builder);
660
661 EntryWithHash { entry: SharedPointer::new(Entry::new(key, value)), key_hash }
662 }
663
664 fn key(&self) -> &K {
665 &self.entry.key
666 }
667
668 fn value(&self) -> &V {
669 &self.entry.value
670 }
671
672 #[inline]
673 fn matches<Q: ?Sized>(&self, key: &Q, key_hash: HashValue) -> bool
674 where
675 K: Borrow<Q>,
676 Q: Hash + Eq,
677 {
678 self.key_hash == key_hash && self.key().borrow() == key
679 }
680}
681
682impl<K, V, P> EntryWithHash<K, V, P>
683where
684 K: Eq + Hash + Clone,
685 V: Clone,
686 P: SharedPointerKind,
687{
688 fn value_mut(&mut self) -> &mut V {
689 &mut SharedPointer::make_mut(&mut self.entry).value
690 }
691}
692
693impl<K, V, P> Clone for EntryWithHash<K, V, P>
694where
695 K: Eq + Hash,
696 P: SharedPointerKind,
697{
698 fn clone(&self) -> EntryWithHash<K, V, P> {
699 EntryWithHash { entry: SharedPointer::clone(&self.entry), key_hash: self.key_hash }
700 }
701}
702
703impl<K, V> HashTrieMap<K, V>
704where
705 K: Eq + Hash,
706{
707 #[must_use]
708 pub fn new() -> HashTrieMap<K, V> {
709 HashTrieMap::new_with_degree(DEFAULT_DEGREE)
710 }
711
712 #[must_use]
713 pub fn new_with_degree(degree: u8) -> HashTrieMap<K, V> {
714 HashTrieMap::new_with_hasher_and_degree_and_ptr_kind(DefaultBuildHasher::default(), degree)
715 }
716}
717
718impl<K, V> HashTrieMapSync<K, V>
719where
720 K: Eq + Hash,
721{
722 #[must_use]
723 pub fn new_sync() -> HashTrieMapSync<K, V> {
724 HashTrieMap::new_sync_with_degree(DEFAULT_DEGREE)
725 }
726
727 #[must_use]
728 pub fn new_sync_with_degree(degree: u8) -> HashTrieMapSync<K, V> {
729 HashTrieMap::new_with_hasher_and_degree_and_ptr_kind(DefaultBuildHasher::default(), degree)
730 }
731}
732
733impl<K, V, P, H: BuildHasher> HashTrieMap<K, V, P, H>
734where
735 K: Eq + Hash,
736 H: Clone,
737 P: SharedPointerKind,
738{
739 #[must_use]
740 pub fn new_with_hasher_and_ptr_kind(hasher_builder: H) -> HashTrieMap<K, V, P, H> {
741 HashTrieMap::new_with_hasher_and_degree_and_ptr_kind(hasher_builder, DEFAULT_DEGREE)
742 }
743
744 #[must_use]
745 pub fn new_with_hasher_and_degree_and_ptr_kind(
746 hasher_builder: H,
747 degree: u8,
748 ) -> HashTrieMap<K, V, P, H> {
749 assert!(degree.is_power_of_two(), "degree must be a power of two");
750 assert!(degree <= DEFAULT_DEGREE, "degree is too big");
751
752 HashTrieMap {
753 root: SharedPointer::new(Node::new_empty_branch()),
754 size: 0,
755 degree,
756 hasher_builder,
757 }
758 }
759
760 #[must_use]
761 pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
762 where
763 K: Borrow<Q>,
764 Q: Hash + Eq,
765 {
766 let key_hash = node_utils::hash(key, &self.hasher_builder);
767
768 self.root.get(key, key_hash, 0, self.degree).map(EntryWithHash::value)
769 }
770
771 #[must_use]
772 pub fn get_key_value<Q: ?Sized>(&self, key: &Q) -> Option<(&K, &V)>
773 where
774 K: Borrow<Q>,
775 Q: Hash + Eq,
776 {
777 let key_hash = node_utils::hash(key, &self.hasher_builder);
778
779 self.root.get(key, key_hash, 0, self.degree).map(|e| (e.key(), e.value()))
780 }
781
782 #[must_use]
783 pub fn insert(&self, key: K, value: V) -> HashTrieMap<K, V, P, H> {
784 let mut new_map = self.clone();
785
786 new_map.insert_mut(key, value);
787
788 new_map
789 }
790
791 pub fn insert_mut(&mut self, key: K, value: V) {
792 let entry = EntryWithHash::new(key, value, &self.hasher_builder);
793 let is_new_key = SharedPointer::make_mut(&mut self.root).insert(entry, 0, self.degree);
794
795 if is_new_key {
796 self.size += 1;
797 }
798 }
799
800 #[must_use]
801 pub fn remove<Q: ?Sized>(&self, key: &Q) -> HashTrieMap<K, V, P, H>
802 where
803 K: Borrow<Q>,
804 Q: Hash + Eq,
805 {
806 let mut new_map = self.clone();
807
808 if new_map.remove_mut(key) {
809 new_map
810 } else {
811 self.clone()
813 }
814 }
815
816 pub fn remove_mut<Q: ?Sized>(&mut self, key: &Q) -> bool
817 where
818 K: Borrow<Q>,
819 Q: Hash + Eq,
820 {
821 let key_hash = node_utils::hash(key, &self.hasher_builder);
822 let removed = SharedPointer::make_mut(&mut self.root).remove(key, key_hash, 0, self.degree);
823
824 if removed {
828 self.size -= 1;
829 }
830
831 removed
832 }
833
834 #[must_use]
835 pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
836 where
837 K: Borrow<Q>,
838 Q: Hash + Eq,
839 {
840 self.get(key).is_some()
841 }
842
843 pub(crate) fn ptr_eq<PO: SharedPointerKind, HO: BuildHasher>(
848 &self,
849 other: &HashTrieMap<K, V, PO, HO>,
850 ) -> bool {
851 let a = SharedPointer::as_ptr(&self.root);
852 let b = SharedPointer::as_ptr(&other.root).cast::<Node<K, V, P>>();
856 core::ptr::eq(a, b)
857 }
858
859 #[must_use]
860 #[inline]
861 pub fn size(&self) -> usize {
862 self.size
863 }
864
865 #[must_use]
866 #[inline]
867 pub fn is_empty(&self) -> bool {
868 self.size() == 0
869 }
870
871 #[allow(clippy::iter_without_into_iter)]
872 pub fn iter(&self) -> Iter<'_, K, V, P> {
873 self.iter_ptr().map(|e| (&e.key, &e.value))
874 }
875
876 #[must_use]
877 fn iter_ptr(&self) -> IterPtr<'_, K, V, P> {
878 IterPtr::new(self)
879 }
880
881 pub fn keys(&self) -> IterKeys<'_, K, V, P> {
882 self.iter().map(|(k, _)| k)
883 }
884
885 pub fn values(&self) -> IterValues<'_, K, V, P> {
886 self.iter().map(|(_, v)| v)
887 }
888}
889
890impl<K, V, P, H: BuildHasher> HashTrieMap<K, V, P, H>
891where
892 K: Eq + Hash + Clone,
893 V: Clone,
894 H: Clone,
895 P: SharedPointerKind,
896{
897 pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
898 where
899 K: Borrow<Q>,
900 Q: Hash + Eq,
901 {
902 let key_hash = node_utils::hash(key, &self.hasher_builder);
905 SharedPointer::make_mut(&mut self.root)
906 .get_mut(key, key_hash, 0, self.degree)
907 .map(EntryWithHash::value_mut)
908 }
909}
910
911impl<K, Q: ?Sized, V, P, H: BuildHasher> Index<&Q> for HashTrieMap<K, V, P, H>
912where
913 K: Eq + Hash + Borrow<Q>,
914 Q: Hash + Eq,
915 H: Clone,
916 P: SharedPointerKind,
917{
918 type Output = V;
919
920 fn index(&self, key: &Q) -> &V {
921 self.get(key).expect("no entry found for key")
922 }
923}
924
925impl<K, V, P, H: BuildHasher> Clone for HashTrieMap<K, V, P, H>
926where
927 K: Eq + Hash,
928 H: Clone,
929 P: SharedPointerKind,
930{
931 fn clone(&self) -> HashTrieMap<K, V, P, H> {
932 HashTrieMap {
933 root: SharedPointer::clone(&self.root),
934 size: self.size,
935 degree: self.degree,
936 hasher_builder: self.hasher_builder.clone(),
937 }
938 }
939}
940
941impl<K, V, P, H: BuildHasher> Default for HashTrieMap<K, V, P, H>
942where
943 K: Eq + Hash,
944 H: Default + Clone,
945 P: SharedPointerKind,
946{
947 fn default() -> HashTrieMap<K, V, P, H> {
948 HashTrieMap::new_with_hasher_and_ptr_kind(H::default())
949 }
950}
951
952impl<K: Eq, V: PartialEq, P, PO, H: BuildHasher> PartialEq<HashTrieMap<K, V, PO, H>>
953 for HashTrieMap<K, V, P, H>
954where
955 K: Hash,
956 H: Clone,
957 P: SharedPointerKind,
958 PO: SharedPointerKind,
959{
960 fn eq(&self, other: &HashTrieMap<K, V, PO, H>) -> bool {
961 if self.ptr_eq(other) {
962 return true;
963 }
964 self.size() == other.size()
965 && self.iter().all(|(key, value)| other.get(key).is_some_and(|v| *value == *v))
966 }
967}
968
969impl<K: Eq, V: Eq, P, H: BuildHasher> Eq for HashTrieMap<K, V, P, H>
970where
971 K: Hash,
972 H: Clone,
973 P: SharedPointerKind,
974{
975}
976
977impl<K, V, P, H: BuildHasher> Display for HashTrieMap<K, V, P, H>
978where
979 K: Eq + Hash + Display,
980 V: Display,
981 H: Clone,
982 P: SharedPointerKind,
983{
984 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
985 let mut first = true;
986
987 fmt.write_str("{")?;
988
989 for (k, v) in self.iter() {
990 if !first {
991 fmt.write_str(", ")?;
992 }
993 k.fmt(fmt)?;
994 fmt.write_str(": ")?;
995 v.fmt(fmt)?;
996 first = false;
997 }
998
999 fmt.write_str("}")
1000 }
1001}
1002
1003impl<'a, K, V, P, H: BuildHasher> IntoIterator for &'a HashTrieMap<K, V, P, H>
1004where
1005 K: Eq + Hash,
1006 H: Default + Clone,
1007 P: SharedPointerKind,
1008{
1009 type Item = (&'a K, &'a V);
1010 type IntoIter = Iter<'a, K, V, P>;
1011
1012 fn into_iter(self) -> Iter<'a, K, V, P> {
1013 self.iter()
1014 }
1015}
1016
1017impl<K, V, P, H> FromIterator<(K, V)> for HashTrieMap<K, V, P, H>
1018where
1019 K: Eq + Hash,
1020 H: BuildHasher + Clone + Default,
1021 P: SharedPointerKind,
1022{
1023 fn from_iter<I: IntoIterator<Item = (K, V)>>(into_iter: I) -> HashTrieMap<K, V, P, H> {
1024 let mut map = HashTrieMap::new_with_hasher_and_ptr_kind(Default::default());
1025
1026 for (k, v) in into_iter {
1027 map.insert_mut(k, v);
1028 }
1029
1030 map
1031 }
1032}
1033
1034#[derive(Debug)]
1035pub struct IterPtr<'a, K, V, P>
1036where
1037 P: SharedPointerKind,
1038{
1039 stack: Vec<IterStackElement<'a, K, V, P>>,
1040 size: usize,
1041}
1042
1043#[derive(Debug)]
1044enum IterStackElement<'a, K, V, P>
1045where
1046 P: SharedPointerKind,
1047{
1048 Branch(slice::Iter<'a, SharedPointer<Node<K, V, P>, P>>),
1049 LeafCollision(list::Iter<'a, EntryWithHash<K, V, P>, P>),
1050 LeafSingle(iter::Once<&'a SharedPointer<Entry<K, V>, P>>),
1051}
1052
1053impl<'a, K, V, P> IterStackElement<'a, K, V, P>
1054where
1055 K: Eq + Hash,
1056 P: SharedPointerKind,
1057{
1058 #[inline]
1059 fn new(node: &Node<K, V, P>) -> IterStackElement<'_, K, V, P> {
1060 match node {
1061 Node::Branch(children) => IterStackElement::Branch(children.iter()),
1062 Node::Leaf(Bucket::Collision(entries)) => {
1063 IterStackElement::LeafCollision(entries.iter())
1064 }
1065 Node::Leaf(Bucket::Single(entry)) => {
1066 IterStackElement::LeafSingle(iter::once(&entry.entry))
1067 }
1068 }
1069 }
1070
1071 #[inline]
1074 fn next(&mut self) -> Option<Result<&'a SharedPointer<Entry<K, V>, P>, Self>> {
1075 match self {
1076 IterStackElement::Branch(i) => i.next().map(|node| match &**node {
1077 Node::Branch(_) | Node::Leaf(Bucket::Collision(_)) => {
1078 Err(IterStackElement::new(node))
1079 }
1080 Node::Leaf(Bucket::Single(e)) => Ok(&e.entry),
1081 }),
1082 IterStackElement::LeafCollision(i) => i.next().map(|i| Ok(&i.entry)),
1083 IterStackElement::LeafSingle(i) => i.next().map(Ok),
1084 }
1085 }
1086}
1087
1088mod iter_utils {
1089 use super::HashValue;
1090
1091 pub fn trie_max_height(degree: u8) -> usize {
1092 let bits_per_level = (degree - 1).count_ones() as usize;
1093 let hash_bits = HashValue::BITS as usize;
1094
1095 (hash_bits / bits_per_level) + usize::from(hash_bits % bits_per_level > 0)
1096 }
1097}
1098
1099impl<K, V, P> IterPtr<'_, K, V, P>
1100where
1101 K: Eq + Hash,
1102 P: SharedPointerKind,
1103{
1104 fn new<H: BuildHasher + Clone>(map: &HashTrieMap<K, V, P, H>) -> IterPtr<'_, K, V, P> {
1105 let mut stack: Vec<IterStackElement<'_, K, V, P>> =
1106 Vec::with_capacity(iter_utils::trie_max_height(map.degree) + 1);
1107
1108 if map.size() > 0 {
1109 stack.push(IterStackElement::new(map.root.borrow()));
1110 }
1111
1112 IterPtr { stack, size: map.size() }
1113 }
1114}
1115
1116impl<'a, K, V, P> Iterator for IterPtr<'a, K, V, P>
1117where
1118 K: Eq + Hash,
1119 P: SharedPointerKind,
1120{
1121 type Item = &'a SharedPointer<Entry<K, V>, P>;
1122
1123 fn next(&mut self) -> Option<&'a SharedPointer<Entry<K, V>, P>> {
1124 while let Some(stack_element) = self.stack.last_mut() {
1125 match stack_element.next() {
1126 Some(Ok(elem)) => {
1127 self.size -= 1;
1128 return Some(elem);
1129 }
1130 Some(Err(stack_elem)) => {
1131 self.stack.push(stack_elem);
1132 }
1133 None => {
1134 self.stack.pop();
1135 }
1136 }
1137 }
1138 None
1139 }
1140
1141 #[inline]
1142 fn size_hint(&self) -> (usize, Option<usize>) {
1143 (self.size, Some(self.size))
1144 }
1145}
1146
1147impl<K: Eq + Hash, V, P> ExactSizeIterator for IterPtr<'_, K, V, P> where P: SharedPointerKind {}
1148
1149#[cfg(feature = "serde")]
1150pub mod serde {
1151 use super::*;
1152 use ::serde::de::{Deserialize, Deserializer, MapAccess, Visitor};
1153 use ::serde::ser::{Serialize, Serializer};
1154 use core::fmt;
1155 use core::marker::PhantomData;
1156
1157 impl<K, V, P, H> Serialize for HashTrieMap<K, V, P, H>
1158 where
1159 K: Eq + Hash + Serialize,
1160 V: Serialize,
1161 H: BuildHasher + Clone + Default,
1162 P: SharedPointerKind,
1163 {
1164 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1165 serializer.collect_map(self)
1166 }
1167 }
1168
1169 impl<'de, K, V, P, H> Deserialize<'de> for HashTrieMap<K, V, P, H>
1170 where
1171 K: Eq + Hash + Deserialize<'de>,
1172 V: Deserialize<'de>,
1173 H: BuildHasher + Clone + Default,
1174 P: SharedPointerKind,
1175 {
1176 fn deserialize<D: Deserializer<'de>>(
1177 deserializer: D,
1178 ) -> Result<HashTrieMap<K, V, P, H>, D::Error> {
1179 deserializer.deserialize_map(HashTrieMapVisitor {
1180 _phantom_entry: PhantomData,
1181 _phantom_h: PhantomData,
1182 _phantom_p: PhantomData,
1183 })
1184 }
1185 }
1186
1187 struct HashTrieMapVisitor<K, V, P, H>
1188 where
1189 P: SharedPointerKind,
1190 {
1191 _phantom_entry: PhantomData<(K, V)>,
1192 _phantom_h: PhantomData<H>,
1193 _phantom_p: PhantomData<P>,
1194 }
1195
1196 impl<'de, K, V, P, H> Visitor<'de> for HashTrieMapVisitor<K, V, P, H>
1197 where
1198 K: Eq + Hash + Deserialize<'de>,
1199 V: Deserialize<'de>,
1200 H: BuildHasher + Clone + Default,
1201 P: SharedPointerKind,
1202 {
1203 type Value = HashTrieMap<K, V, P, H>;
1204
1205 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1206 formatter.write_str("a map")
1207 }
1208
1209 fn visit_map<A>(self, mut map: A) -> Result<HashTrieMap<K, V, P, H>, A::Error>
1210 where
1211 A: MapAccess<'de>,
1212 {
1213 let mut hash_trie_map = HashTrieMap::new_with_hasher_and_ptr_kind(Default::default());
1214
1215 while let Some((k, v)) = map.next_entry()? {
1216 hash_trie_map.insert_mut(k, v);
1217 }
1218
1219 Ok(hash_trie_map)
1220 }
1221 }
1222}
1223
1224#[cfg(test)]
1225mod test;