1use std::cmp::Ordering;
2use std::collections::{HashMap, HashSet, BinaryHeap};
3use std::collections::hash_map::RandomState;
4use std::ffi::{CStr, CString, OsStr, OsString};
5use std::fmt::Alignment;
6use std::marker::{PhantomData, PhantomPinned};
7use std::mem;
8use std::net::{
9 IpAddr,
10 Ipv4Addr,
11 Ipv6Addr,
12 Shutdown,
13 SocketAddr,
14 SocketAddrV4,
15 SocketAddrV6
16};
17use std::num::{
18 NonZeroI8,
19 NonZeroI16,
20 NonZeroI32,
21 NonZeroI64,
22 NonZeroI128,
23 NonZeroIsize,
24 NonZeroU8,
25 NonZeroU16,
26 NonZeroU32,
27 NonZeroU64,
28 NonZeroU128,
29 NonZeroUsize, Wrapping
30};
31use std::ops::{
32 Range,
33 RangeFrom,
34 RangeFull,
35 RangeInclusive,
36 RangeTo,
37 RangeToInclusive
38};
39use std::path::{Path, PathBuf};
40use std::slice::Iter as SliceIter;
41use std::sync::{Mutex, RwLock};
42use std::thread::ThreadId;
43use std::time::{Duration, Instant};
44
45pub trait HeapSize {
154
155 fn heap_size(&self) -> usize;
168
169 fn heap_size_sum_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
185 where
186 Self: 'item,
187 Fun: Fn() -> Iter,
188 Iter: Iterator<Item = &'item Self>
189 {
190 make_iter().map(HeapSize::heap_size).sum()
191 }
192
193 fn heap_size_sum_exact_size_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
211 where
212 Self: 'item,
213 Fun: Fn() -> Iter,
214 Iter: ExactSizeIterator<Item = &'item Self>
215 {
216 Self::heap_size_sum_iter(make_iter)
217 }
218}
219
220pub trait ValueSize {
245
246 fn value_size(&self) -> usize;
259
260 fn value_size_sum_iter<'item>(iterator: impl Iterator<Item = &'item Self>) -> usize
277 where
278 Self: 'item
279 {
280 iterator.map(ValueSize::value_size).sum()
281 }
282
283 fn value_size_sum_exact_size_iter<'item>(iterator: impl ExactSizeIterator<Item = &'item Self>)
300 -> usize
301 where
302 Self: 'item
303 {
304 Self::value_size_sum_iter(iterator)
305 }
306}
307
308impl<T: Sized> ValueSize for T {
309 fn value_size(&self) -> usize {
310 mem::size_of::<Self>()
311 }
312
313 fn value_size_sum_iter<'item>(iterator: impl Iterator<Item = &'item Self>) -> usize
314 where
315 Self: 'item
316 {
317 mem::size_of::<Self>() * iterator.count()
318 }
319
320 fn value_size_sum_exact_size_iter<'item>(iterator: impl ExactSizeIterator<Item = &'item Self>)
321 -> usize
322 where
323 Self: 'item
324 {
325 mem::size_of::<Self>() * iterator.len()
326 }
327}
328
329pub trait MemSize : ValueSize + HeapSize {
342
343 fn mem_size(&self) -> usize;
361}
362
363impl<T: HeapSize + ValueSize + ?Sized> MemSize for T {
364 fn mem_size(&self) -> usize {
365 self.value_size() + self.heap_size()
366 }
367}
368
369macro_rules! basic_mem_size {
370 ( $t: ty ) => {
371 impl HeapSize for $t {
372 fn heap_size(&self) -> usize {
373 0
374 }
375
376 fn heap_size_sum_iter<'item, Fun, Iter>(_make_iter: Fun) -> usize
377 where
378 Self: 'item,
379 Fun: Fn() -> Iter,
380 Iter: Iterator<Item = &'item Self>
381 {
382 0
383 }
384
385 fn heap_size_sum_exact_size_iter<'item, Fun, Iter>(_make_iter: Fun) -> usize
386 where
387 Self: 'item,
388 Fun: Fn() -> Iter,
389 Iter: ExactSizeIterator<Item = &'item Self>
390 {
391 0
392 }
393 }
394 };
395}
396
397basic_mem_size!(());
398basic_mem_size!(u8);
399basic_mem_size!(u16);
400basic_mem_size!(u32);
401basic_mem_size!(u64);
402basic_mem_size!(u128);
403basic_mem_size!(usize);
404basic_mem_size!(i8);
405basic_mem_size!(i16);
406basic_mem_size!(i32);
407basic_mem_size!(i64);
408basic_mem_size!(i128);
409basic_mem_size!(isize);
410basic_mem_size!(f32);
411basic_mem_size!(f64);
412basic_mem_size!(bool);
413basic_mem_size!(char);
414
415basic_mem_size!(str);
416basic_mem_size!(CStr);
417basic_mem_size!(OsStr);
418
419basic_mem_size!(NonZeroU8);
420basic_mem_size!(NonZeroU16);
421basic_mem_size!(NonZeroU32);
422basic_mem_size!(NonZeroU64);
423basic_mem_size!(NonZeroU128);
424basic_mem_size!(NonZeroUsize);
425basic_mem_size!(NonZeroI8);
426basic_mem_size!(NonZeroI16);
427basic_mem_size!(NonZeroI32);
428basic_mem_size!(NonZeroI64);
429basic_mem_size!(NonZeroI128);
430basic_mem_size!(NonZeroIsize);
431
432basic_mem_size!(Ordering);
433
434basic_mem_size!(Duration);
435basic_mem_size!(Instant);
436
437basic_mem_size!(Alignment);
438
439basic_mem_size!(PhantomPinned);
440
441basic_mem_size!(Shutdown);
442
443basic_mem_size!(RangeFull);
444
445basic_mem_size!(ThreadId);
446
447basic_mem_size!(Ipv4Addr);
448basic_mem_size!(Ipv6Addr);
449basic_mem_size!(IpAddr);
450basic_mem_size!(SocketAddrV4);
451basic_mem_size!(SocketAddrV6);
452basic_mem_size!(SocketAddr);
453
454basic_mem_size!(RandomState);
455
456macro_rules! tuple_heap_size {
457 ( $($ts: ident),+ ) => {
458 impl<$($ts),+> HeapSize for ($($ts,)+)
459 where
460 $($ts: HeapSize),+
461 {
462 fn heap_size(&self) -> usize {
463 #[allow(non_snake_case)]
464 let ($($ts,)+) = self;
465 0 $(+ $ts.heap_size())+
466 }
467
468 fn heap_size_sum_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
469 where
470 Self: 'item,
471 Fun: Fn() -> Iter,
472 Iter: Iterator<Item = &'item Self>
473 {
474 tuple_heap_size!(
475 @sum_iter_terms
476 heap_size_sum_iter,
477 make_iter,
478 $($ts),+ ;
479 ($($ts),+))
480 }
481
482 fn heap_size_sum_exact_size_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
483 where
484 Self: 'item,
485 Fun: Fn() -> Iter,
486 Iter: ExactSizeIterator<Item = &'item Self>
487 {
488 tuple_heap_size!(
489 @sum_iter_terms
490 heap_size_sum_exact_size_iter,
491 make_iter,
492 $($ts),+ ;
493 ($($ts),+))
494 }
495 }
496 };
497
498 ( @sum_iter_terms $sum_iter:ident, $make_iter: expr, $($ts: ident),+ ; $types: tt ) => {
499 0 $(+
500 $ts::$sum_iter(||
501 $make_iter().map(|tuple|
502 tuple_heap_size!(@extract_from_tuple tuple, $ts, $types))))+
503 };
504
505 ( @extract_from_tuple $tuple: expr, $extracted: ident, ($($ts: ident),+) ) => {
506 {
507 #[allow(non_snake_case)]
508 #[allow(unused)]
509 let ($($ts,)+) = $tuple;
510 $extracted
511 }
512 };
513}
514
515tuple_heap_size!(A);
516tuple_heap_size!(A, B);
517tuple_heap_size!(A, B, C);
518tuple_heap_size!(A, B, C, D);
519tuple_heap_size!(A, B, C, D, E);
520tuple_heap_size!(A, B, C, D, E, F);
521tuple_heap_size!(A, B, C, D, E, F, G);
522tuple_heap_size!(A, B, C, D, E, F, G, H);
523tuple_heap_size!(A, B, C, D, E, F, G, H, I);
524tuple_heap_size!(A, B, C, D, E, F, G, H, I, J);
525
526impl<T: MemSize> HeapSize for Wrapping<T> {
527 fn heap_size(&self) -> usize {
528 self.0.heap_size()
529 }
530
531 fn heap_size_sum_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
532 where
533 Self: 'item,
534 Fun: Fn() -> Iter,
535 Iter: Iterator<Item = &'item Self>
536 {
537 T::heap_size_sum_iter(|| make_iter().map(|item| &item.0))
538 }
539
540 fn heap_size_sum_exact_size_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
541 where
542 Self: 'item,
543 Fun: Fn() -> Iter,
544 Iter: ExactSizeIterator<Item = &'item Self>
545 {
546 T::heap_size_sum_exact_size_iter(|| make_iter().map(|item| &item.0))
547 }
548}
549
550impl<T> ValueSize for [T] {
551 fn value_size(&self) -> usize {
552 mem::size_of_val(self)
553 }
554}
555
556impl<T: MemSize> HeapSize for [T] {
557 fn heap_size(&self) -> usize {
558 T::heap_size_sum_exact_size_iter(|| self.iter())
559 }
560}
561
562struct SizedArrayFlatIterator<'item, T, I, const N: usize> {
563 current_section: SliceIter<'item, T>,
564 subsequent_sections: I
565}
566
567impl<'item, T, I, const N: usize> Iterator for SizedArrayFlatIterator<'item, T, I, N>
568where
569 I: ExactSizeIterator<Item = &'item [T; N]>
570{
571 type Item = &'item T;
572
573 fn next(&mut self) -> Option<Self::Item> {
574 if let item @ Some(_) = self.current_section.next() {
575 return item;
576 }
577
578 if let Some(next_section) = self.subsequent_sections.next() {
579 self.current_section = next_section.iter();
580 return self.next();
581 }
582
583 None
584 }
585
586 fn size_hint(&self) -> (usize, Option<usize>) {
587 let len = self.current_section.len() + self.subsequent_sections.len() * N;
588
589 (len, Some(len))
590 }
591}
592
593impl<'item, T, I, const N: usize> ExactSizeIterator for SizedArrayFlatIterator<'item, T, I, N>
594where
595 I: ExactSizeIterator<Item = &'item [T; N]> { }
596
597impl<T: MemSize, const N: usize> HeapSize for [T; N] {
598 fn heap_size(&self) -> usize {
599 self[..].heap_size()
600 }
601
602 fn heap_size_sum_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
603 where
604 Self: 'item,
605 Fun: Fn() -> Iter,
606 Iter: Iterator<Item = &'item Self>
607 {
608 <[T]>::heap_size_sum_iter(|| make_iter().map(|item| &item[..]))
609 }
610
611 fn heap_size_sum_exact_size_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
612 where
613 Self: 'item,
614 Fun: Fn() -> Iter,
615 Iter: ExactSizeIterator<Item = &'item Self>
616 {
617 T::heap_size_sum_exact_size_iter(|| SizedArrayFlatIterator {
618 current_section: SliceIter::default(),
619 subsequent_sections: make_iter()
620 })
621 }
622}
623
624impl<T: MemSize> HeapSize for Vec<T> {
625 fn heap_size(&self) -> usize {
626 let element_heap_size = self.as_slice().heap_size();
627 let own_heap_size = self.capacity() * mem::size_of::<T>();
628 element_heap_size + own_heap_size
629 }
630}
631
632impl<K: MemSize, V: MemSize, S: MemSize> HeapSize for HashMap<K, V, S> {
633 fn heap_size(&self) -> usize {
634 let hasher_heap_size = self.hasher().heap_size();
635 let element_heap_size = K::heap_size_sum_exact_size_iter(|| self.keys()) +
636 V::heap_size_sum_exact_size_iter(|| self.values());
637 let key_value_size = mem::size_of::<(K, V)>();
638 let own_heap_size = self.capacity() * key_value_size;
639
640 hasher_heap_size + element_heap_size + own_heap_size
641 }
642}
643
644impl<T: MemSize, S: MemSize> HeapSize for HashSet<T, S> {
645 fn heap_size(&self) -> usize {
646 let hasher_heap_size = self.hasher().heap_size();
647 let element_heap_size = T::heap_size_sum_exact_size_iter(|| self.iter());
648 let own_heap_size = self.capacity() * mem::size_of::<T>();
649
650 hasher_heap_size + element_heap_size + own_heap_size
651 }
652}
653
654impl<T: MemSize> HeapSize for BinaryHeap<T> {
655 fn heap_size(&self) -> usize {
656 let element_heap_size = T::heap_size_sum_exact_size_iter(|| self.iter());
657 let own_heap_size = self.capacity() * mem::size_of::<T>();
658
659 element_heap_size + own_heap_size
660 }
661}
662
663impl<T: MemSize + ?Sized> HeapSize for Box<T> {
664 fn heap_size(&self) -> usize {
665 T::mem_size(self.as_ref())
666 }
667
668 fn heap_size_sum_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
669 where
670 Self: 'item,
671 Fun: Fn() -> Iter,
672 Iter: Iterator<Item = &'item Self>
673 {
674 T::heap_size_sum_iter(|| make_iter().map(|item| &**item)) +
675 T::value_size_sum_iter(make_iter().map(|item| &**item))
676 }
677
678 fn heap_size_sum_exact_size_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
679 where
680 Self: 'item,
681 Fun: Fn() -> Iter,
682 Iter: ExactSizeIterator<Item = &'item Self>
683 {
684 T::heap_size_sum_exact_size_iter(|| make_iter().map(|item| &**item)) +
685 T::value_size_sum_exact_size_iter(make_iter().map(|item| &**item))
686 }
687}
688
689impl<T: MemSize> HeapSize for Mutex<T> {
690 fn heap_size(&self) -> usize {
691 self.lock().unwrap().heap_size()
692 }
693}
694
695impl<T: MemSize> HeapSize for RwLock<T> {
696 fn heap_size(&self) -> usize {
697 self.read().unwrap().heap_size()
698 }
699}
700
701impl ValueSize for str {
702 fn value_size(&self) -> usize {
703 mem::size_of_val(self)
704 }
705}
706
707impl HeapSize for String {
708 fn heap_size(&self) -> usize {
709 self.capacity()
710 }
711}
712
713impl ValueSize for CStr {
714 fn value_size(&self) -> usize {
715 mem::size_of_val(self)
716 }
717}
718
719impl HeapSize for CString {
720 fn heap_size(&self) -> usize {
721 self.as_bytes_with_nul().len()
722 }
723}
724
725impl ValueSize for OsStr {
726 fn value_size(&self) -> usize {
727 mem::size_of_val(self)
728 }
729}
730
731impl HeapSize for OsString {
732 fn heap_size(&self) -> usize {
733 self.capacity()
734 }
735}
736
737impl<T: ?Sized> HeapSize for &T {
738 fn heap_size(&self) -> usize {
739 0
741 }
742}
743
744impl<T: ?Sized> HeapSize for &mut T {
745 fn heap_size(&self) -> usize {
746 0
748 }
749}
750
751impl<T: MemSize> HeapSize for Option<T> {
752 fn heap_size(&self) -> usize {
753 match self {
754 Some(v) => v.heap_size(),
755 None => 0
756 }
757 }
758}
759
760impl<V: MemSize, E: MemSize> HeapSize for Result<V, E> {
761 fn heap_size(&self) -> usize {
762 match self {
763 Ok(v) => v.heap_size(),
764 Err(e) => e.heap_size()
765 }
766 }
767}
768
769impl<T> HeapSize for PhantomData<T> {
770 fn heap_size(&self) -> usize {
771 0
772 }
773}
774
775impl<I: MemSize> HeapSize for Range<I> {
776 fn heap_size(&self) -> usize {
777 self.start.heap_size() + self.end.heap_size()
778 }
779}
780
781impl<I: MemSize> HeapSize for RangeFrom<I> {
782 fn heap_size(&self) -> usize {
783 self.start.heap_size()
784 }
785}
786
787impl<I: MemSize> HeapSize for RangeTo<I> {
788 fn heap_size(&self) -> usize {
789 self.end.heap_size()
790 }
791}
792
793impl<I: MemSize> HeapSize for RangeInclusive<I> {
794 fn heap_size(&self) -> usize {
795 self.start().heap_size() + self.end().heap_size()
796 }
797}
798
799impl<I: MemSize> HeapSize for RangeToInclusive<I> {
800 fn heap_size(&self) -> usize {
801 self.end.heap_size()
802 }
803}
804
805impl HeapSize for Path {
806 fn heap_size(&self) -> usize {
807 0
808 }
809}
810
811impl ValueSize for Path {
812 fn value_size(&self) -> usize {
813 mem::size_of_val(self)
814 }
815}
816
817impl HeapSize for PathBuf {
818 fn heap_size(&self) -> usize {
819 self.as_path().mem_size()
820 }
821}
822
823#[cfg(test)]
824mod test {
825 use super::*;
826
827 const VEC_SIZE: usize = mem::size_of::<Vec<u8>>();
828 const BOX_SIZE: usize = mem::size_of::<Box<u8>>();
829 const STRING_SIZE: usize = mem::size_of::<String>();
830 const BOXED_SLICE_SIZE: usize = mem::size_of::<Box<[u8]>>();
831 const HASH_MAP_SIZE: usize = mem::size_of::<HashMap<u8, u8>>();
832 const HASH_SET_SIZE: usize = mem::size_of::<HashSet<u8>>();
833 const BINARY_HEAP_SIZE: usize = mem::size_of::<BinaryHeap<u8>>();
834 const STRING_RESULT_SIZE: usize = mem::size_of::<Result<String, String>>();
835 const PATH_BUF_SIZE: usize = mem::size_of::<PathBuf>();
836
837 #[test]
838 fn tuples_have_correct_size() {
839 assert_eq!(mem::size_of::<(u16, u32, i16, char)>(),
840 (1u16, 2u32, 3i16, 'x').mem_size());
841 assert_eq!(mem::size_of::<((u8, i8, u8), i16)>(),
842 ((1u8, 2i8, 3u8), 4i16).mem_size());
843 }
844
845 #[test]
846 fn vectors_have_correct_size() {
847 assert_eq!(24 + VEC_SIZE,
848 vec!['a', 'b', 'c', 'd', 'e', 'f'].mem_size());
849 assert_eq!(24 + 4 * VEC_SIZE,
850 vec![vec![], vec![1u64, 2u64], vec![3u64]].mem_size());
851 }
852
853 #[test]
854 fn vectors_estimate_spare_capacity() {
855 let mut vec = Vec::with_capacity(8);
856
857 assert_eq!(64 + VEC_SIZE, vec.mem_size());
858
859 vec.push(1.0f64);
860
861 assert_eq!(64 + VEC_SIZE, vec.mem_size());
862 }
863
864 #[test]
865 fn byte_vector_has_correct_size() {
866 assert_eq!(5 + VEC_SIZE, vec![0u8; 5].mem_size());
867 }
868
869 #[test]
870 fn boxed_byte_vector_has_correct_size() {
871 let vec = vec![Box::new(0u8); 5];
872 let expected_size = 5 + 5 * BOX_SIZE + VEC_SIZE;
873
874 assert_eq!(expected_size, vec.mem_size());
875 }
876
877 #[test]
878 fn string_vector_has_correct_size() {
879 let vec = vec![
880 "hello".to_owned(),
881 "world".to_owned(),
882 "greetings".to_owned(),
883 "moon".to_owned()
884 ];
885 let expected_size = 23 + 4 * STRING_SIZE + VEC_SIZE;
886
887 assert_eq!(expected_size, vec.mem_size());
888 }
889
890 #[test]
891 fn strings_have_correct_size() {
892 assert_eq!(11 + STRING_SIZE, "hello world".to_owned().mem_size());
893 assert_eq!(26 + STRING_SIZE,
894 "söme döüble byte chärs".to_owned().mem_size());
895 }
896
897 #[test]
898 fn string_with_spare_capacity_has_correct_size() {
899 assert_eq!(16 + STRING_SIZE, String::with_capacity(16).mem_size());
900 }
901
902 #[test]
903 fn options_have_correct_size() {
904 let some = Some(String::from("hello"));
905 let none = None::<String>;
906
907 assert_eq!(none.mem_size() + 5, some.mem_size());
908 }
909
910 #[test]
911 fn wrapping_have_correct_size() {
912 let wrapping = Wrapping(0u64);
913
914 assert_eq!(8, wrapping.mem_size());
915 }
916
917 #[test]
918 fn wrapping_have_correct_sum_iter_size() {
919 let wrappings = [
920 Wrapping(Box::new(0u64)),
921 Wrapping(Box::new(1u64)),
922 Wrapping(Box::new(2u64))
923 ];
924
925 assert_eq!(24, Wrapping::<Box<u64>>::heap_size_sum_iter(|| wrappings.iter()));
926 assert_eq!(24, Wrapping::<Box<u64>>::heap_size_sum_exact_size_iter(|| wrappings.iter()));
927 }
928
929 #[test]
930 fn arrays_with_primitive_entries_have_correct_size() {
931 let array = [0u64; 4];
932
933 assert_eq!(32, array.mem_size());
934 }
935
936 #[test]
937 fn arrays_with_complex_entries_have_correct_size() {
938 let array = [vec![], Vec::<u64>::with_capacity(4)];
939
940 assert_eq!(2 * VEC_SIZE + 32, array.mem_size());
941 }
942
943 #[test]
944 fn boxed_slices_with_primitive_entries_have_correct_size() {
945 let slice = vec![1u32, 2u32, 3u32, 4u32].into_boxed_slice();
946
947 assert_eq!(BOXED_SLICE_SIZE + 16, Box::mem_size(&slice));
948 }
949
950 #[test]
951 fn boxed_slices_with_complex_entries_have_correct_size() {
952 let slice =
953 vec![vec![], Vec::<u64>::with_capacity(4)].into_boxed_slice();
954
955 assert_eq!(BOXED_SLICE_SIZE + 2 * VEC_SIZE + 32, Box::mem_size(&slice));
956 }
957
958 #[test]
959 fn empty_hash_map_has_correct_size() {
960 let hash_map = HashMap::<String, String>::new();
961
962 assert_eq!(HASH_MAP_SIZE, hash_map.mem_size());
963 }
964
965 #[test]
966 fn hash_map_of_primitives_with_abnormal_alignment_has_correct_size() {
967 const ENTRY_SIZE: usize = mem::size_of::<(u8, u16)>();
968
969 let mut hash_map = HashMap::new();
970 hash_map.insert(0u8, 1u16);
971 hash_map.insert(1u8, 2u16);
972 hash_map.insert(2u8, 3u16);
973
974 let expected_size = ENTRY_SIZE * hash_map.capacity() + HASH_MAP_SIZE;
975
976 assert_eq!(expected_size, hash_map.mem_size());
977 }
978
979 #[test]
980 fn hash_map_of_complex_entries_has_correct_size() {
981 const ENTRY_SIZE: usize = mem::size_of::<(String, String)>();
982
983 let mut hash_map = HashMap::new();
984 hash_map.insert("hello".to_owned(), "world".to_owned());
985 hash_map.insert("greetings".to_owned(), "moon".to_owned());
986 hash_map.insert("ahoy".to_owned(), "mars".to_owned());
987
988 let number_of_chars = 31;
989 let expected_size =
990 ENTRY_SIZE * hash_map.capacity() + HASH_MAP_SIZE + number_of_chars;
991
992 assert_eq!(expected_size, hash_map.mem_size());
993 }
994
995 #[test]
996 fn empty_hash_set_has_correct_size() {
997 let hash_set = HashSet::<String>::new();
998
999 assert_eq!(HASH_SET_SIZE, hash_set.mem_size());
1000 }
1001
1002 #[test]
1003 fn hash_set_of_primitives_has_correct_size() {
1004 let mut hash_set = HashSet::new();
1005 hash_set.insert(1u16);
1006 hash_set.insert(2u16);
1007 hash_set.insert(3u16);
1008
1009 let expected_size = 2 * hash_set.capacity() + HASH_SET_SIZE;
1010
1011 assert_eq!(expected_size, hash_set.mem_size());
1012 }
1013
1014 #[test]
1015 fn hash_set_of_complex_entries_has_correct_size() {
1016 let mut hash_set = HashSet::new();
1017 hash_set.insert("hello".to_owned());
1018 hash_set.insert("greetings".to_owned());
1019 hash_set.insert("ahoy".to_owned());
1020
1021 let number_of_chars = 18;
1022 let expected_size =
1023 STRING_SIZE * hash_set.capacity() + HASH_SET_SIZE + number_of_chars;
1024
1025 assert_eq!(expected_size, hash_set.mem_size());
1026 }
1027
1028 #[test]
1029 fn empty_binary_heap_has_correct_size() {
1030 let binary_heap = BinaryHeap::<String>::new();
1031
1032 assert_eq!(BINARY_HEAP_SIZE, binary_heap.mem_size());
1033 }
1034
1035 #[test]
1036 fn binary_heap_of_primitives_has_correct_size() {
1037 let mut binary_heap = BinaryHeap::with_capacity(5);
1038 binary_heap.push(1u16);
1039 binary_heap.push(2u16);
1040 binary_heap.push(3u16);
1041
1042 assert_eq!(BINARY_HEAP_SIZE + 10, binary_heap.mem_size());
1043 }
1044
1045 #[test]
1046 fn binary_heap_of_complex_entries_has_correct_size() {
1047 let mut binary_heap = BinaryHeap::with_capacity(7);
1048 binary_heap.push("hello".to_owned());
1049 binary_heap.push("greetings".to_owned());
1050 binary_heap.push("ahoy".to_owned());
1051
1052 let number_of_chars = 18;
1053 let expected_size =
1054 STRING_SIZE * 7 + BINARY_HEAP_SIZE + number_of_chars;
1055
1056 assert_eq!(expected_size, binary_heap.mem_size());
1057 }
1058
1059 #[test]
1060 fn mutex_of_primitive_type_has_correct_size() {
1061 let mutex = Mutex::new(0u64);
1062
1063 assert_eq!(mem::size_of::<Mutex<u64>>(), mutex.mem_size());
1064 }
1065
1066 #[test]
1067 fn mutex_of_complex_type_has_correct_size() {
1068 let mutex = Mutex::new("hello".to_owned());
1069
1070 assert_eq!(mem::size_of::<Mutex<String>>() + 5, mutex.mem_size());
1071 }
1072
1073 #[test]
1074 fn rw_lock_of_primitive_type_has_correct_size() {
1075 let rw_lock = RwLock::new(0u64);
1076
1077 assert_eq!(mem::size_of::<RwLock<u64>>(), rw_lock.mem_size());
1078 }
1079
1080 #[test]
1081 fn rw_lock_of_complex_type_has_correct_size() {
1082 let rw_lock = RwLock::new("hello".to_owned());
1083
1084 assert_eq!(mem::size_of::<RwLock<String>>() + 5, rw_lock.mem_size());
1085 }
1086
1087 #[test]
1088 fn boxed_str_has_correct_size() {
1089 let string = "hello".to_owned().into_boxed_str();
1090
1091 assert_eq!(mem::size_of::<Box<str>>() + 5, string.mem_size());
1092 }
1093
1094 #[test]
1095 fn boxed_cstr_has_correct_size() {
1096 let string = CString::new("hello").unwrap().into_boxed_c_str();
1097
1098 assert_eq!(mem::size_of::<Box<CStr>>() + 6, string.mem_size());
1099 }
1100
1101 #[test]
1102 fn cstring_has_correct_size(){
1103 let string = CString::new("hello").unwrap();
1104
1105 assert_eq!(mem::size_of::<CString>() + 6, string.mem_size());
1106 }
1107
1108 #[test]
1109 fn references_have_correct_size() {
1110 assert_eq!(mem::size_of::<&u8>(),
1111 <&String>::mem_size(&&"hello".to_owned()));
1112 assert_eq!(mem::size_of::<&u8>(),
1113 <&mut String>::mem_size(&&mut "hello".to_owned()));
1114 }
1115
1116 #[test]
1117 fn some_variant_of_primitive_type_has_correct_size() {
1118 assert_eq!(2, Some(NonZeroI16::new(1).unwrap()).mem_size());
1119 }
1120
1121 #[test]
1122 fn some_variant_of_complex_type_has_correct_size() {
1123 let option = Some("hello".to_owned()).mem_size();
1124
1125 assert_eq!(mem::size_of::<Option<String>>() + 5, option);
1126 }
1127
1128 #[test]
1129 fn none_variant_has_correct_size() {
1130 assert_eq!(2, None::<NonZeroI16>.mem_size());
1131 }
1132
1133 #[test]
1134 fn ok_variant_of_primitive_type_has_correct_size() {
1135 let result: Result<u64, u64> = Ok(1);
1136
1137 assert_eq!(mem::size_of::<Result<u64, u64>>(), result.mem_size());
1138 }
1139
1140 #[test]
1141 fn err_variant_of_primitive_type_has_correct_size() {
1142 let result: Result<u32, u32> = Err(2);
1143
1144 assert_eq!(mem::size_of::<Result<u32, u32>>(), result.mem_size());
1145 }
1146
1147 #[test]
1148 fn ok_variant_of_complex_type_has_correct_size() {
1149 let result: Result<String, String> = Ok("hello".to_owned());
1150
1151 assert_eq!(STRING_RESULT_SIZE + 5, result.mem_size());
1152 }
1153
1154 #[test]
1155 fn err_variant_of_complex_type_has_correct_size() {
1156 let result: Result<String, String> = Err("world".to_owned());
1157
1158 assert_eq!(STRING_RESULT_SIZE + 5, result.mem_size());
1159 }
1160
1161 #[test]
1162 fn phantom_data_has_zero_size() {
1163 assert_eq!(0, PhantomData::<String>.mem_size());
1164 }
1165
1166 #[test]
1167 fn ip_addresses_have_correct_size() {
1168 const IP_ADDR_SIZE: usize = mem::size_of::<IpAddr>();
1169
1170 let v4 = IpAddr::V4("1.2.3.4".parse().unwrap());
1171 let v6 = IpAddr::V6("1234::4321".parse().unwrap());
1172
1173 assert_eq!(IP_ADDR_SIZE, v4.mem_size());
1174 assert_eq!(IP_ADDR_SIZE, v6.mem_size());
1175 }
1176
1177 #[test]
1178 fn socket_addresses_have_correct_size() {
1179 const SOCKET_ADDR_SIZE: usize = mem::size_of::<SocketAddr>();
1180
1181 let v4 = SocketAddr::V4("1.2.3.4:1337".parse().unwrap());
1182 let v6 = SocketAddr::V6("[1234::4321]:1337".parse().unwrap());
1183
1184 assert_eq!(SOCKET_ADDR_SIZE, v4.mem_size());
1185 assert_eq!(SOCKET_ADDR_SIZE, v6.mem_size());
1186 }
1187
1188 #[test]
1189 fn full_range_has_zero_size() {
1190 assert_eq!(0, (..).mem_size());
1191 }
1192
1193 struct MockRangeable {
1194 heap_size: usize
1195 }
1196
1197 impl MockRangeable {
1198 fn new(heap_size: usize) -> MockRangeable {
1199 MockRangeable { heap_size }
1200 }
1201 }
1202
1203 impl HeapSize for MockRangeable {
1204 fn heap_size(&self) -> usize {
1205 self.heap_size
1206 }
1207 }
1208
1209 #[test]
1210 fn ranges_have_correct_size() {
1211 let range_from = MockRangeable::new(42)..;
1212 let range_to = ..MockRangeable::new(42);
1213 let range_to_inclusive = ..=MockRangeable::new(42);
1214 let range = MockRangeable::new(42)..MockRangeable::new(43);
1215 let range_inclusive = MockRangeable::new(42)..=MockRangeable::new(43);
1216
1217 assert_eq!(mem::size_of::<RangeFrom<MockRangeable>>() + 42,
1218 range_from.mem_size());
1219 assert_eq!(mem::size_of::<RangeTo<MockRangeable>>() + 42,
1220 range_to.mem_size());
1221 assert_eq!(mem::size_of::<RangeToInclusive<MockRangeable>>() + 42,
1222 range_to_inclusive.mem_size());
1223 assert_eq!(mem::size_of::<Range<MockRangeable>>() + 85,
1224 range.mem_size());
1225 assert_eq!(mem::size_of::<RangeInclusive<MockRangeable>>() + 85,
1226 range_inclusive.mem_size());
1227 }
1228
1229 #[test]
1230 fn empty_path_has_correct_size() {
1231 let path = Path::new("");
1232
1233 assert_eq!(0, path.mem_size());
1234 }
1235
1236 #[test]
1237 fn non_empty_path_has_correct_size() {
1238 let path = Path::new("hello");
1239 let os_str = OsStr::new("hello");
1240
1241 assert_eq!(os_str.mem_size(), path.mem_size());
1242 }
1243
1244 #[test]
1245 fn empty_path_buf_has_correct_size() {
1246 let path_buf = PathBuf::new();
1247
1248 assert_eq!(PATH_BUF_SIZE, path_buf.mem_size());
1249 }
1250
1251 #[test]
1252 fn non_empty_path_buf_has_correct_size() {
1253 let path_buf = PathBuf::from("hello/world");
1254 let os_str = OsStr::new("hello/world");
1255
1256 assert_eq!(PATH_BUF_SIZE + os_str.mem_size(), path_buf.mem_size());
1257 }
1258
1259 #[test]
1260 fn tuple_heap_size_sum_iter_works_for_stack_types() {
1261 type Tuple = (i32, bool, char);
1262
1263 let zero_heap_size_tuples = [
1264 (1, true, 'a'),
1265 (2, false, 'b')
1266 ];
1267
1268 assert_eq!(0, Tuple::heap_size_sum_iter(|| zero_heap_size_tuples.iter()));
1269 assert_eq!(0, Tuple::heap_size_sum_exact_size_iter(|| zero_heap_size_tuples.iter()));
1270 }
1271
1272 #[test]
1273 fn tuple_heap_size_sum_iter_works_for_allocating_types() {
1274 type Tuple = (Vec<i32>, Box<bool>, char);
1275
1276 let zero_heap_size_tuples = [
1277 (vec![1, 2], Box::new(true), 'a'),
1278 (vec![3, 4, 5], Box::new(false), 'b')
1279 ];
1280
1281 assert_eq!(22, Tuple::heap_size_sum_iter(|| zero_heap_size_tuples.iter()));
1282 assert_eq!(22, Tuple::heap_size_sum_exact_size_iter(|| zero_heap_size_tuples.iter()));
1283 }
1284
1285 #[test]
1286 fn array_heap_size_sum_iter_works_for_zero_heap_size_type() {
1287 type Array = [u32; 3];
1288
1289 let arrays = [
1290 [1, 2, 3],
1291 [4, 5, 6],
1292 [7, 8, 9]
1293 ];
1294
1295 assert_eq!(0, Array::heap_size_sum_iter(|| arrays.iter()));
1296 assert_eq!(0, Array::heap_size_sum_exact_size_iter(|| arrays.iter()));
1297 }
1298
1299 #[test]
1300 fn array_heap_size_sum_iter_works_for_constant_heap_size_type() {
1301 type Array = [Box<u32>; 3];
1302
1303 let arrays = [
1304 [Box::new(1), Box::new(2), Box::new(3)],
1305 [Box::new(4), Box::new(5), Box::new(6)],
1306 [Box::new(7), Box::new(8), Box::new(9)]
1307 ];
1308
1309 assert_eq!(36, Array::heap_size_sum_iter(|| arrays.iter()));
1310 assert_eq!(36, Array::heap_size_sum_exact_size_iter(|| arrays.iter()));
1311 }
1312
1313 #[test]
1314 fn array_heap_size_sum_iter_works_for_variable_heap_size_type() {
1315 type Array = [Vec<u32>; 2];
1316
1317 let arrays = [
1318 [vec![1, 2], vec![3]],
1319 [vec![], vec![4, 5, 6]],
1320 [vec![7], vec![8, 9, 10]]
1321 ];
1322
1323 assert_eq!(40, Array::heap_size_sum_iter(|| arrays.iter()));
1324 assert_eq!(40, Array::heap_size_sum_exact_size_iter(|| arrays.iter()));
1325 }
1326
1327 #[test]
1328 fn value_size_sum_iter_works_with_sized() {
1329 let u32_sum = u32::value_size_sum_iter([1, 2, 3, 4].iter());
1330 let string_sum = String::value_size_sum_iter(["a".to_owned(), "b".to_owned()].iter());
1331
1332 assert_eq!(16, u32_sum);
1333 assert_eq!(STRING_SIZE * 2, string_sum);
1334 }
1335
1336 #[test]
1337 fn value_size_sum_iter_works_with_unsized() {
1338 let arrays: Vec<Box<[u32]>> = vec![
1339 Box::new([1]),
1340 Box::new([2, 3])
1341 ];
1342 let sum =
1343 <[u32]>::value_size_sum_iter(arrays.iter().map(|array| &**array));
1344 let sum_exact_size =
1345 <[u32]>::value_size_sum_exact_size_iter(arrays.iter().map(|array| &**array));
1346
1347 assert_eq!(12, sum);
1348 assert_eq!(12, sum_exact_size);
1349 }
1350
1351 #[test]
1352 fn vec_of_box_of_vec_has_correct_size() {
1353 let vec = vec![
1354 Box::new(vec![1u8, 2u8, 3u8, 4u8]),
1355 Box::new(vec![5u8, 6u8, 7u8, 8u8, 9u8])
1356 ];
1357 let expected_size = 3 * VEC_SIZE + 2 * BOX_SIZE + 9;
1358
1359 assert_eq!(expected_size, vec.mem_size());
1360 }
1361
1362 #[test]
1363 fn vec_of_boxed_slices_has_correct_size() {
1364 let vec: Vec<Box<[u64]>> = vec![
1365 Box::new([1, 2, 3]),
1366 Box::new([4, 5, 6, 7])
1367 ];
1368 let expected_size = VEC_SIZE + 2 * BOXED_SLICE_SIZE + 56;
1369
1370 assert_eq!(expected_size, vec.mem_size());
1371 }
1372
1373 #[test]
1374 fn boxes_of_vecs_have_correct_heap_size_sum_iter() {
1375 let vec: Vec<Box<Vec<u8>>> = vec![
1376 Box::new(vec![1, 2, 3]),
1377 Box::new(vec![4, 5, 6])
1378 ];
1379 let expected_size = VEC_SIZE * 2 + 6;
1380
1381 assert_eq!(expected_size, Box::<Vec<u8>>::heap_size_sum_iter(|| vec.iter()));
1382 assert_eq!(expected_size, Box::<Vec<u8>>::heap_size_sum_exact_size_iter(|| vec.iter()));
1383 }
1384}