1use crate::{
2 arenas::AnyArena,
3 hasher::RandomState,
4 keys::{Key, Spur},
5 resolver::RodeoResolver,
6 util::{Iter, Strings},
7 Rodeo,
8};
9use alloc::vec::Vec;
10#[cfg(feature = "serialize")]
11use core::hash::{Hash, Hasher};
12use core::{hash::BuildHasher, ops::Index};
13use hashbrown::HashMap;
14
15#[derive(Debug)]
24pub struct RodeoReader<K = Spur, S = RandomState> {
25 map: HashMap<K, (), ()>,
28 hasher: S,
29 pub(crate) strings: Vec<&'static str>,
30 __arena: AnyArena,
31}
32
33impl<K, S> RodeoReader<K, S> {
34 pub(crate) unsafe fn new(
42 map: HashMap<K, (), ()>,
43 hasher: S,
44 strings: Vec<&'static str>,
45 arena: AnyArena,
46 ) -> Self {
47 Self {
48 map,
49 hasher,
50 strings,
51 __arena: arena,
52 }
53 }
54
55 #[cfg_attr(feature = "inline-more", inline)]
73 pub fn get<T>(&self, val: T) -> Option<K>
74 where
75 T: AsRef<str>,
76 S: BuildHasher,
77 K: Key,
78 {
79 let string_slice: &str = val.as_ref();
80
81 let hash = self.hasher.hash_one(string_slice);
83
84 let entry = self.map.raw_entry().from_hash(hash, |key| {
86 let key_string: &str = unsafe { index_unchecked!(self.strings, key.into_usize()) };
88
89 string_slice == key_string
91 });
92
93 entry.map(|(key, ())| *key)
94 }
95
96 #[cfg_attr(feature = "inline-more", inline)]
114 pub fn contains<T>(&self, val: T) -> bool
115 where
116 T: AsRef<str>,
117 S: BuildHasher,
118 K: Key,
119 {
120 self.get(val).is_some()
121 }
122
123 #[cfg_attr(feature = "inline-more", inline)]
141 pub fn contains_key(&self, key: &K) -> bool
142 where
143 K: Key,
144 {
145 key.into_usize() < self.strings.len()
146 }
147
148 #[cfg_attr(feature = "inline-more", inline)]
170 pub fn resolve<'a>(&'a self, key: &K) -> &'a str
171 where
172 K: Key,
173 {
174 unsafe {
179 assert!(key.into_usize() < self.strings.len());
180 self.strings.get_unchecked(key.into_usize())
181 }
182 }
183
184 #[cfg_attr(feature = "inline-more", inline)]
202 pub fn try_resolve<'a>(&'a self, key: &K) -> Option<&'a str>
203 where
204 K: Key,
205 {
206 unsafe {
211 if key.into_usize() < self.strings.len() {
212 Some(self.strings.get_unchecked(key.into_usize()))
213 } else {
214 None
215 }
216 }
217 }
218
219 #[cfg_attr(feature = "inline-more", inline)]
242 pub unsafe fn resolve_unchecked<'a>(&'a self, key: &K) -> &'a str
243 where
244 K: Key,
245 {
246 unsafe { self.strings.get_unchecked(key.into_usize()) }
247 }
248
249 #[cfg_attr(feature = "inline-more", inline)]
265 pub fn len(&self) -> usize {
266 self.strings.len()
267 }
268
269 #[cfg_attr(feature = "inline-more", inline)]
284 pub fn is_empty(&self) -> bool {
285 self.len() == 0
286 }
287
288 #[cfg_attr(feature = "inline-more", inline)]
290 pub fn iter(&self) -> Iter<'_, K> {
291 Iter::from_reader(self)
292 }
293
294 #[cfg_attr(feature = "inline-more", inline)]
296 pub fn strings(&self) -> Strings<'_, K> {
297 Strings::from_reader(self)
298 }
299
300 #[cfg_attr(feature = "inline-more", inline)]
322 #[must_use]
323 pub fn into_resolver(self) -> RodeoResolver<K> {
324 let RodeoReader {
325 strings, __arena, ..
326 } = self;
327
328 unsafe { RodeoResolver::new(strings, __arena) }
331 }
332}
333
334unsafe impl<K: Sync, S: Sync> Sync for RodeoReader<K, S> {}
335unsafe impl<K: Send, S: Send> Send for RodeoReader<K, S> {}
336
337impl<'a, K: Key, S> IntoIterator for &'a RodeoReader<K, S> {
338 type Item = (K, &'a str);
339 type IntoIter = Iter<'a, K>;
340
341 #[cfg_attr(feature = "inline-more", inline)]
342 fn into_iter(self) -> Self::IntoIter {
343 self.iter()
344 }
345}
346
347impl<K, S> Index<K> for RodeoReader<K, S>
348where
349 K: Key,
350 S: BuildHasher,
351{
352 type Output = str;
353
354 #[cfg_attr(feature = "inline-more", inline)]
355 fn index(&self, idx: K) -> &Self::Output {
356 self.resolve(&idx)
357 }
358}
359
360impl<K, S> Eq for RodeoReader<K, S> {}
361
362impl<K, S> PartialEq<Self> for RodeoReader<K, S> {
363 #[cfg_attr(feature = "inline-more", inline)]
364 fn eq(&self, other: &Self) -> bool {
365 self.strings == other.strings
366 }
367}
368
369impl<K, S> PartialEq<RodeoResolver<K>> for RodeoReader<K, S> {
370 #[cfg_attr(feature = "inline-more", inline)]
371 fn eq(&self, other: &RodeoResolver<K>) -> bool {
372 self.strings == other.strings
373 }
374}
375
376impl<K, S> PartialEq<Rodeo<K, S>> for RodeoReader<K, S> {
377 #[cfg_attr(feature = "inline-more", inline)]
378 fn eq(&self, other: &Rodeo<K, S>) -> bool {
379 self.strings == other.strings
380 }
381}
382
383compile! {
384 if #[feature = "serialize"] {
385 use crate::{Capacity, arenas::Arena};
386 use alloc::string::String;
387 use core::num::NonZeroUsize;
388 use hashbrown::hash_map::RawEntryMut;
389 use serde::{
390 de::{Deserialize, Deserializer},
391 ser::{Serialize, Serializer},
392 };
393 }
394}
395
396#[cfg(feature = "serialize")]
397impl<K, H> Serialize for RodeoReader<K, H> {
398 #[cfg_attr(feature = "inline-more", inline)]
399 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
400 where
401 S: Serializer,
402 {
403 self.strings.serialize(serializer)
405 }
406}
407
408#[cfg(feature = "serialize")]
409impl<'de, K: Key, S: BuildHasher + Default> Deserialize<'de> for RodeoReader<K, S> {
410 #[cfg_attr(feature = "inline-more", inline)]
411 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
412 where
413 D: Deserializer<'de>,
414 {
415 let vector: Vec<String> = Vec::deserialize(deserializer)?;
416 let capacity = {
417 let total_bytes = vector.iter().map(|s| s.len()).sum::<usize>();
418 let total_bytes =
419 NonZeroUsize::new(total_bytes).unwrap_or_else(|| Capacity::default().bytes());
420
421 Capacity::new(vector.len(), total_bytes)
422 };
423
424 let hasher: S = Default::default();
425 let mut strings = Vec::with_capacity(capacity.strings);
426 let mut map = HashMap::with_capacity_and_hasher(capacity.strings, ());
427 let mut arena = Arena::new(capacity.bytes, usize::max_value())
428 .expect("failed to allocate memory for interner");
429
430 for (key, string) in vector.into_iter().enumerate() {
431 let allocated = unsafe {
432 arena
433 .store_str(&string)
434 .expect("failed to allocate enough memory")
435 };
436
437 let hash = {
438 let mut state = hasher.build_hasher();
439 allocated.hash(&mut state);
440
441 state.finish()
442 };
443
444 let entry = map.raw_entry_mut().from_hash(hash, |key: &K| {
446 let key_string: &str = unsafe { index_unchecked!(strings, key.into_usize()) };
448
449 allocated == key_string
451 });
452
453 match entry {
454 RawEntryMut::Occupied(..) => {
455 debug_assert!(false, "re-interned a key while deserializing");
456 }
457 RawEntryMut::Vacant(entry) => {
458 let key =
460 K::try_from_usize(key).expect("failed to create key while deserializing");
461
462 strings.push(allocated);
464
465 entry.insert_with_hasher(hash, key, (), |key| {
467 let key_string: &str =
468 unsafe { index_unchecked!(strings, key.into_usize()) };
469
470 let mut state = hasher.build_hasher();
471 key_string.hash(&mut state);
472
473 state.finish()
474 });
475 }
476 }
477 }
478
479 Ok(Self {
480 map,
481 hasher,
482 strings,
483 __arena: AnyArena::Arena(arena),
484 })
485 }
486}
487
488#[cfg(test)]
489mod tests {
490 mod single_threaded {
491 #[cfg(feature = "serialize")]
492 use crate::RodeoReader;
493 use crate::{Key, Rodeo, Spur};
494
495 #[test]
496 fn get() {
497 let mut rodeo = Rodeo::default();
498 let key = rodeo.get_or_intern("A");
499
500 let reader = rodeo.into_reader();
501 assert_eq!(Some(key), reader.get("A"));
502
503 assert!(reader.get("F").is_none());
504 }
505
506 #[test]
507 fn resolve() {
508 let mut rodeo = Rodeo::default();
509 let key = rodeo.get_or_intern("A");
510
511 let reader = rodeo.into_reader();
512 assert_eq!("A", reader.resolve(&key));
513 }
514
515 #[test]
516 #[should_panic]
517 #[cfg(not(miri))]
518 fn resolve_panics() {
519 let reader = Rodeo::default().into_reader();
520 reader.resolve(&Spur::try_from_usize(100).unwrap());
521 }
522
523 #[test]
524 fn try_resolve() {
525 let mut rodeo = Rodeo::default();
526 let key = rodeo.get_or_intern("A");
527
528 let reader = rodeo.into_reader();
529 assert_eq!(Some("A"), reader.try_resolve(&key));
530 assert_eq!(
531 None,
532 reader.try_resolve(&Spur::try_from_usize(100).unwrap())
533 );
534 }
535
536 #[test]
537 fn resolve_unchecked() {
538 let mut rodeo = Rodeo::default();
539 let key = rodeo.get_or_intern("A");
540
541 let reader = rodeo.into_reader();
542 unsafe {
543 assert_eq!("A", reader.resolve_unchecked(&key));
544 }
545 }
546
547 #[test]
548 fn len() {
549 let mut rodeo = Rodeo::default();
550 rodeo.get_or_intern("A");
551 rodeo.get_or_intern("B");
552 rodeo.get_or_intern("C");
553
554 let reader = rodeo.into_reader();
555 assert_eq!(reader.len(), 3);
556 }
557
558 #[test]
559 fn empty() {
560 let rodeo = Rodeo::default();
561 let reader = rodeo.into_reader();
562
563 assert!(reader.is_empty());
564 }
565
566 #[test]
567 fn iter() {
568 let mut rodeo = Rodeo::default();
569 let a = rodeo.get_or_intern("a");
570 let b = rodeo.get_or_intern("b");
571 let c = rodeo.get_or_intern("c");
572
573 let resolver = rodeo.into_reader();
574 let mut iter = resolver.iter();
575
576 assert_eq!(Some((a, "a")), iter.next());
577 assert_eq!(Some((b, "b")), iter.next());
578 assert_eq!(Some((c, "c")), iter.next());
579 assert_eq!(None, iter.next());
580 }
581
582 #[test]
583 fn strings() {
584 let mut rodeo = Rodeo::default();
585 rodeo.get_or_intern("a");
586 rodeo.get_or_intern("b");
587 rodeo.get_or_intern("c");
588
589 let resolver = rodeo.into_reader();
590 let mut iter = resolver.strings();
591
592 assert_eq!(Some("a"), iter.next());
593 assert_eq!(Some("b"), iter.next());
594 assert_eq!(Some("c"), iter.next());
595 assert_eq!(None, iter.next());
596 }
597
598 #[test]
599 fn drops() {
600 let rodeo = Rodeo::default();
601 let _ = rodeo.into_reader();
602 }
603
604 #[test]
605 fn into_resolver() {
606 let mut rodeo = Rodeo::default();
607 let key = rodeo.get_or_intern("A");
608
609 let resolver = rodeo.into_reader().into_resolver();
610 assert_eq!("A", resolver.resolve(&key));
611 }
612
613 #[test]
614 #[cfg(not(any(feature = "no-std", feature = "ahasher")))]
615 fn debug() {
616 let reader = Rodeo::default().into_reader();
617 println!("{:?}", reader);
618 }
619
620 #[test]
621 fn contains() {
622 let mut rodeo = Rodeo::default();
623 rodeo.get_or_intern("");
624 let resolver = rodeo.into_reader();
625
626 assert!(resolver.contains(""));
627 assert!(resolver.contains(""));
628 }
629
630 #[test]
631 fn contains_key() {
632 let mut rodeo = Rodeo::default();
633 let key = rodeo.get_or_intern("");
634 let resolver = rodeo.into_reader();
635
636 assert!(resolver.contains(""));
637 assert!(resolver.contains_key(&key));
638 assert!(!resolver.contains_key(&Spur::try_from_usize(10000).unwrap()));
639 }
640
641 #[test]
642 fn into_iterator() {
643 let rodeo = ["a", "b", "c", "d", "e"]
644 .iter()
645 .collect::<Rodeo>()
646 .into_reader();
647
648 for ((key, string), (expected_key, expected_string)) in rodeo.into_iter().zip(
649 [(0usize, "a"), (1, "b"), (2, "c"), (3, "d"), (4, "e")]
650 .iter()
651 .copied(),
652 ) {
653 assert_eq!(key, Spur::try_from_usize(expected_key).unwrap());
654 assert_eq!(string, expected_string);
655 }
656 }
657
658 #[test]
659 fn index() {
660 let mut rodeo = Rodeo::default();
661 let key = rodeo.get_or_intern("A");
662
663 let reader = rodeo.into_reader();
664 assert_eq!("A", &reader[key]);
665 }
666
667 #[test]
668 #[cfg(feature = "serialize")]
669 fn empty_serialize() {
670 let rodeo = Rodeo::default().into_reader();
671
672 let ser = serde_json::to_string(&rodeo).unwrap();
673 let ser2 = serde_json::to_string(&rodeo).unwrap();
674 assert_eq!(ser, ser2);
675
676 let deser: RodeoReader = serde_json::from_str(&ser).unwrap();
677 assert!(deser.is_empty());
678 let deser2: RodeoReader = serde_json::from_str(&ser2).unwrap();
679 assert!(deser2.is_empty());
680 }
681
682 #[test]
683 #[cfg(feature = "serialize")]
684 fn filled_serialize() {
685 let mut rodeo = Rodeo::default();
686 let a = rodeo.get_or_intern("a");
687 let b = rodeo.get_or_intern("b");
688 let c = rodeo.get_or_intern("c");
689 let d = rodeo.get_or_intern("d");
690 let rodeo = rodeo.into_reader();
691
692 let ser = serde_json::to_string(&rodeo).unwrap();
693 let ser2 = serde_json::to_string(&rodeo).unwrap();
694 assert_eq!(ser, ser2);
695
696 let deser: RodeoReader = serde_json::from_str(&ser).unwrap();
697 let deser2: RodeoReader = serde_json::from_str(&ser2).unwrap();
698
699 for (((correct_key, correct_str), (key1, str1)), (key2, str2)) in
700 [(a, "a"), (b, "b"), (c, "c"), (d, "d")]
701 .iter()
702 .copied()
703 .zip(&deser)
704 .zip(&deser2)
705 {
706 assert_eq!(correct_key, key1);
707 assert_eq!(correct_key, key2);
708
709 assert_eq!(correct_str, str1);
710 assert_eq!(correct_str, str2);
711 }
712 }
713
714 #[test]
715 fn reader_eq() {
716 let a = Rodeo::default();
717 let b = Rodeo::default();
718 assert_eq!(a.into_reader(), b.into_reader());
719
720 let mut a = Rodeo::default();
721 a.get_or_intern("a");
722 a.get_or_intern("b");
723 a.get_or_intern("c");
724 let mut b = Rodeo::default();
725 b.get_or_intern("a");
726 b.get_or_intern("b");
727 b.get_or_intern("c");
728 assert_eq!(a.into_reader(), b.into_reader());
729 }
730
731 #[test]
732 fn resolver_eq() {
733 let a = Rodeo::default();
734 let b = Rodeo::default();
735 assert_eq!(a.into_reader(), b.into_resolver());
736
737 let mut a = Rodeo::default();
738 a.get_or_intern("a");
739 a.get_or_intern("b");
740 a.get_or_intern("c");
741 let mut b = Rodeo::default();
742 b.get_or_intern("a");
743 b.get_or_intern("b");
744 b.get_or_intern("c");
745 assert_eq!(a.into_reader(), b.into_resolver());
746 }
747 }
748
749 #[cfg(all(not(any(miri, feature = "no-std")), feature = "multi-threaded"))]
750 mod multi_threaded {
751 #[cfg(feature = "serialize")]
752 use crate::RodeoReader;
753 use crate::{keys::Key, locks::Arc, Spur, ThreadedRodeo};
754 use std::thread;
755
756 #[test]
757 fn get() {
758 let rodeo = ThreadedRodeo::default();
759 let key = rodeo.get_or_intern("A");
760
761 let reader = rodeo.into_reader();
762 assert_eq!(Some(key), reader.get("A"));
763
764 assert!(reader.get("F").is_none());
765 }
766
767 #[test]
768 #[cfg(not(miri))]
769 fn get_threaded() {
770 let rodeo = ThreadedRodeo::default();
771 let key = rodeo.get_or_intern("A");
772
773 let reader = Arc::new(rodeo.into_reader());
774
775 let moved = Arc::clone(&reader);
776 thread::spawn(move || {
777 assert_eq!(Some(key), moved.get("A"));
778 assert!(moved.get("F").is_none());
779 });
780
781 assert_eq!(Some(key), reader.get("A"));
782 assert!(reader.get("F").is_none());
783 }
784
785 #[test]
786 fn resolve() {
787 let rodeo = ThreadedRodeo::default();
788 let key = rodeo.get_or_intern("A");
789
790 let reader = rodeo.into_reader();
791 assert_eq!("A", reader.resolve(&key));
792 }
793
794 #[test]
795 #[cfg(not(miri))]
796 fn resolve_threaded() {
797 let rodeo = ThreadedRodeo::default();
798 let key = rodeo.get_or_intern("A");
799
800 let reader = Arc::new(rodeo.into_reader());
801
802 let moved = Arc::clone(&reader);
803 thread::spawn(move || {
804 assert_eq!("A", moved.resolve(&key));
805 });
806
807 assert_eq!("A", reader.resolve(&key));
808 }
809
810 #[test]
811 fn len() {
812 let rodeo = ThreadedRodeo::default();
813 rodeo.get_or_intern("A");
814 rodeo.get_or_intern("B");
815 rodeo.get_or_intern("C");
816
817 let reader = rodeo.into_reader();
818 assert_eq!(reader.len(), 3);
819 }
820
821 #[test]
822 fn empty() {
823 let rodeo = ThreadedRodeo::default();
824 let reader = rodeo.into_reader();
825
826 assert!(reader.is_empty());
827 }
828
829 #[test]
847 fn iter() {
848 let rodeo = ThreadedRodeo::default();
849 let a = rodeo.get_or_intern("a");
850 let b = rodeo.get_or_intern("b");
851 let c = rodeo.get_or_intern("c");
852
853 let resolver = rodeo.into_resolver();
854 let mut iter = resolver.iter();
855
856 assert_eq!(Some((a, "a")), iter.next());
857 assert_eq!(Some((b, "b")), iter.next());
858 assert_eq!(Some((c, "c")), iter.next());
859 assert_eq!(None, iter.next());
860 }
861
862 #[test]
863 fn strings() {
864 let rodeo = ThreadedRodeo::default();
865 rodeo.get_or_intern("a");
866 rodeo.get_or_intern("b");
867 rodeo.get_or_intern("c");
868
869 let resolver = rodeo.into_resolver();
870 let mut iter = resolver.strings();
871
872 assert_eq!(Some("a"), iter.next());
873 assert_eq!(Some("b"), iter.next());
874 assert_eq!(Some("c"), iter.next());
875 assert_eq!(None, iter.next());
876 }
877
878 #[test]
879 fn drops() {
880 let rodeo = ThreadedRodeo::default();
881 let _ = rodeo.into_reader();
882 }
883
884 #[test]
885 #[cfg(not(miri))]
886 fn drop_threaded() {
887 let rodeo = ThreadedRodeo::default();
888 let reader = Arc::new(rodeo.into_reader());
889
890 let moved = Arc::clone(&reader);
891 thread::spawn(move || {
892 let _ = moved;
893 });
894 }
895
896 #[test]
897 fn into_resolver() {
898 let rodeo = ThreadedRodeo::default();
899 let key = rodeo.get_or_intern("A");
900
901 let resolver = rodeo.into_reader().into_resolver();
902 assert_eq!("A", resolver.resolve(&key));
903 }
904
905 #[test]
906 #[cfg(not(feature = "no-std"))]
907 fn debug() {
908 let reader = ThreadedRodeo::default().into_reader();
909 println!("{:?}", reader);
910 }
911
912 #[test]
913 fn contains() {
914 let rodeo = ThreadedRodeo::default();
915 rodeo.get_or_intern("");
916 let resolver = rodeo.into_reader();
917
918 assert!(resolver.contains(""));
919 assert!(resolver.contains(""));
920 }
921
922 #[test]
923 fn contains_key() {
924 let rodeo = ThreadedRodeo::default();
925 let key = rodeo.get_or_intern("");
926 let resolver = rodeo.into_reader();
927
928 assert!(resolver.contains(""));
929 assert!(resolver.contains_key(&key));
930 assert!(!resolver.contains_key(&Spur::try_from_usize(10000).unwrap()));
931 }
932
933 #[test]
934 fn into_iterator() {
935 let rodeo = ["a", "b", "c", "d", "e"]
936 .iter()
937 .collect::<ThreadedRodeo>()
938 .into_reader();
939
940 for ((key, string), (expected_key, expected_string)) in rodeo.into_iter().zip(
941 [(0usize, "a"), (1, "b"), (2, "c"), (3, "d"), (4, "e")]
942 .iter()
943 .copied(),
944 ) {
945 assert_eq!(key, Spur::try_from_usize(expected_key).unwrap());
946 assert_eq!(string, expected_string);
947 }
948 }
949
950 #[test]
951 fn index() {
952 let rodeo = ThreadedRodeo::default();
953 let key = rodeo.get_or_intern("A");
954
955 let reader = rodeo.into_reader();
956 assert_eq!("A", &reader[key]);
957 }
958
959 #[test]
960 #[cfg(feature = "serialize")]
961 fn empty_serialize() {
962 let rodeo = ThreadedRodeo::default().into_reader();
963
964 let ser = serde_json::to_string(&rodeo).unwrap();
965 let ser2 = serde_json::to_string(&rodeo).unwrap();
966 assert_eq!(ser, ser2);
967
968 let deser: RodeoReader = serde_json::from_str(&ser).unwrap();
969 assert!(deser.is_empty());
970 let deser2: RodeoReader = serde_json::from_str(&ser2).unwrap();
971 assert!(deser2.is_empty());
972 }
973
974 #[test]
975 #[cfg(feature = "serialize")]
976 fn filled_serialize() {
977 let rodeo = ThreadedRodeo::default();
978 let a = rodeo.get_or_intern("a");
979 let b = rodeo.get_or_intern("b");
980 let c = rodeo.get_or_intern("c");
981 let d = rodeo.get_or_intern("d");
982 let rodeo = rodeo.into_reader();
983
984 let ser = serde_json::to_string(&rodeo).unwrap();
985 let ser2 = serde_json::to_string(&rodeo).unwrap();
986 assert_eq!(ser, ser2);
987
988 let deser: RodeoReader = serde_json::from_str(&ser).unwrap();
989 let deser2: RodeoReader = serde_json::from_str(&ser2).unwrap();
990
991 for (((correct_key, correct_str), (key1, str1)), (key2, str2)) in
992 [(a, "a"), (b, "b"), (c, "c"), (d, "d")]
993 .iter()
994 .copied()
995 .zip(&deser)
996 .zip(&deser2)
997 {
998 assert_eq!(correct_key, key1);
999 assert_eq!(correct_key, key2);
1000
1001 assert_eq!(correct_str, str1);
1002 assert_eq!(correct_str, str2);
1003 }
1004 }
1005 }
1006}