lru_mem/
mem_size.rs

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
45/// A trait for types whose size on the heap can be determined at runtime. Note
46/// for all [Sized] types, it is sufficient to implement this trait, as a
47/// blanket implementation of [ValueSize] and consequently [MemSize] is already
48/// provided. The latter is required for the [LruCache](crate::LruCache) to
49/// track the size of its entries. It has implementations for most common data
50/// types and containers.
51///
52/// Note that reference-counting smart pointers deliberately do not implement
53/// this trait, as it is not clear whether a pointer will drop the referenced
54/// content when it is ejected from the cache.
55///
56/// # Example
57///
58/// For simple types which are stored completely in one memory location, such
59/// as primitive types or structs of such types, it usually suffices to
60/// implement this as a constant 0. In such cases, it is recommended to
61/// implement [HeapSize::heap_size_sum_iter] as well to improve performances of
62/// collections of your type.
63///
64/// ```
65/// use lru_mem::HeapSize;
66/// use std::mem;
67///
68/// struct Vector2f {
69///     x: f32,
70///     y: f32
71/// }
72///
73/// impl HeapSize for Vector2f {
74///     fn heap_size(&self) -> usize {
75///         0
76///     }
77///
78///     fn heap_size_sum_iter<'item, Fun, Iter>(_make_iter: Fun) -> usize
79///     where
80///         Self: 'item,
81///         Fun: Fn() -> Iter,
82///         Iter: Iterator<Item = &'item Self>
83///     {
84///         0
85///     }
86/// }
87/// ```
88///
89/// For more complicated types, it may be necessary to account for any
90/// referenced data that is owned by the instance. If the memory is owned by
91/// some field, which already implements `HeapSize`, you can rely on that
92/// implementation to estimate the required heap memory. See below for an
93/// example of this.
94///
95/// ```
96/// use lru_mem::HeapSize;
97///
98/// struct Person {
99///     name: String,
100///     address: String
101/// }
102///
103/// impl HeapSize for Person {
104///     fn heap_size(&self) -> usize {
105///         // Both members may have allocated data, which is accounted for by
106///         // calling heap_size.
107///         self.name.heap_size() + self.address.heap_size()
108///     }
109/// }
110/// ```
111///
112/// In case the previous examples do not apply, consider the implementation on
113/// [String] provided by this library. It demonstrates how to manually account
114/// for any owned referenced data.
115///
116/// ```ignore
117/// use lru_mem::HeapSize;
118/// use std::mem;
119///
120/// impl HeapSize for String {
121///     fn heap_size(&self) -> usize {
122///         // The number of bytes reserved on the heap for UTF-8 data.
123///         self.capacity()
124///     }
125/// }
126/// ```
127///
128/// For types with a constant, non-zero amount of allocated data,
129/// [HeapSize::heap_size_sum_exact_size_iter] can be implemented to improve
130/// performance of collections of this type with known size.
131///
132/// ```
133/// use lru_mem::HeapSize;
134/// use std::mem;
135///
136/// struct BoxedU32(Box<u32>);
137///
138/// impl HeapSize for BoxedU32 {
139///     fn heap_size(&self) -> usize {
140///         mem::size_of::<u32>()
141///     }
142///
143///     fn heap_size_sum_exact_size_iter<'item, Fun, Iter>(make_iter: Fun) -> usize
144///     where
145///         Self: 'item,
146///         Fun: Fn() -> Iter,
147///         Iter: ExactSizeIterator<Item=&'item Self>
148///     {
149///         mem::size_of::<u32>() * make_iter().len()
150///     }
151/// }
152/// ```
153pub trait HeapSize {
154
155    /// The size of the referenced data that is owned by this value in bytes,
156    /// usually allocated on the heap (such as the value of a [Box] or the
157    /// elements and reserved memory of a [Vec]).
158    ///
159    /// # Example
160    ///
161    /// ```
162    /// use lru_mem::HeapSize;
163    ///
164    /// assert_eq!(0, 1u64.heap_size());
165    /// assert_eq!(12, "hello world!".to_owned().heap_size());
166    /// ```
167    fn heap_size(&self) -> usize;
168
169    /// The total sum of the sizes of referenced data that is owned by a value
170    /// in an iterator constructed with the given constructor, in bytes. This is
171    /// default-implemented by computing [HeapSize::heap_size] on every element
172    /// and summing them. In some cases, specialized implementations may be more
173    /// performant. This is common for types which do not allocate any memory at
174    /// all, where this function can be implemented by a constant zero.
175    ///
176    /// # Example
177    ///
178    /// ```
179    /// use lru_mem::HeapSize;
180    ///
181    /// let boxes: [Box<i32>; 3] = [Box::new(1), Box::new(2), Box::new(3)];
182    /// assert_eq!(8, Box::<i32>::heap_size_sum_iter(|| boxes.iter().filter(|item| ***item > 1)));
183    /// ```
184    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    /// The total sum of the sizes of referenced data that is owned by a value
194    /// in an exact-size-iterator constructed with the given constructor, in
195    /// bytes. This is default-implemented by using
196    /// [HeapSize::heap_size_sum_iter]. In some cases, specialized
197    /// implementations relying on the iterator's size may be more performant.
198    /// This is common for types which allocate a constant amount of memory,
199    /// where this function can multiply the iterator's length.
200    ///
201    /// # Example
202    ///
203    /// ```
204    /// use lru_mem::HeapSize;
205    ///
206    /// let boxes: [Box<i32>; 3] = [Box::new(1), Box::new(2), Box::new(3)];
207    ///
208    /// assert_eq!(12, Box::<i32>::heap_size_sum_exact_size_iter(|| boxes.iter()));
209    /// ```
210    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
220/// A trait for types whose value size can be determined at runtime. This only
221/// refers to the size of the value itself, not allocated data. For [Sized]
222/// types, this is equivalent to [mem::size_of], which is provided by a blanket
223/// implementation. For unsized types, [mem::size_of_val] can be used.
224///
225/// # Example
226///
227/// ```
228/// use lru_mem::ValueSize;
229/// use std::mem;
230///
231/// // unsized type
232/// struct FlaggedBytes {
233///     flag: bool,
234///     bytes: [u8]
235/// }
236///
237/// impl ValueSize for FlaggedBytes {
238///     fn value_size(&self) -> usize {
239///         // This is a valid implementation for all unsized types
240///         mem::size_of_val(self)
241///     }
242/// }
243/// ```
244pub trait ValueSize {
245
246    /// The size of this value in bytes, excluding allocated data.
247    ///
248    /// # Example
249    ///
250    /// ```
251    /// use lru_mem::ValueSize;
252    /// use std::mem;
253    ///
254    /// let boxed = Box::new([0u8; 64]);
255    ///
256    /// assert_eq!(mem::size_of::<*const ()>(), boxed.value_size());
257    /// ```
258    fn value_size(&self) -> usize;
259
260    /// The total sum of the sizes of all values in the given iterator, in
261    /// bytes. This is default-implemented by computing [ValueSize::value_size]
262    /// on every element and summing them. For [Sized] types, a more potentially
263    /// efficient implementation using [Iterator::count] is provided. If you are
264    /// implementing this trait manually, it is unlikely to be more efficient to
265    /// provide a manual implementation here.
266    ///
267    /// # Example
268    ///
269    /// ```
270    /// use lru_mem::ValueSize;
271    ///
272    /// let nums: [i32; 3] = [1, 2, 3];
273    ///
274    /// assert_eq!(8, i32::value_size_sum_iter(nums.iter().filter(|item| **item > 1)));
275    /// ```
276    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    /// The total sum of the sizes of all values in the given
284    /// exact-size-iterator, in bytes. This is default-implemented by using
285    /// [ValueSize::value_size_sum_iter]. For [Sized] types, a usually more
286    /// efficient implementation using [ExactSizeIterator::len] is provided. If
287    /// you are implementing this trait manually, it is unlikely to be more
288    /// efficient to provide a manual implementation here.
289    ///
290    /// # Example
291    ///
292    /// ```
293    /// use lru_mem::ValueSize;
294    ///
295    /// let nums: [i32; 3] = [1, 2, 3];
296    ///
297    /// assert_eq!(12, i32::value_size_sum_exact_size_iter(nums.iter()));
298    /// ```
299    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
329/// A trait for types whose total size in memory can be determined at runtime.
330/// This is required for the [LruCache](crate::LruCache) to track the size of
331/// entries. It has implementations for most common data types and containers.
332///
333/// Note that reference-counting smart pointers deliberately do not implement
334/// this trait, as it is not clear whether a pointer will drop the referenced
335/// content when it is ejected from the cache.
336///
337/// This trait is blanked-implemented via the [HeapSize] and [ValueSize]
338/// traits. For [Sized] types, it suffices to implement [HeapSize], otherwise
339/// implement both [HeapSize] and [ValueSize]. This trait will automatically be
340/// implemented.
341pub trait MemSize : ValueSize + HeapSize {
342
343    /// The total size of this value in bytes. This includes the value itself
344    /// as well as all owned referenced data (such as the value on the heap of
345    /// a [Box] or the elements and reserved memory of a [Vec]).
346    ///
347    /// This function is blanket-implemented by adding [ValueSize::value_size]
348    /// and [HeapSize::heap_size] for any given value.
349    ///
350    /// # Example
351    ///
352    /// ```
353    /// use lru_mem::MemSize;
354    /// use std::mem;
355    ///
356    /// assert_eq!(8, 1u64.mem_size());
357    /// assert_eq!(12 + mem::size_of::<String>(),
358    ///     "hello world!".to_owned().mem_size());
359    /// ```
360    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        // cache is not data owner => only memory for reference itself counted
740        0
741    }
742}
743
744impl<T: ?Sized> HeapSize for &mut T {
745    fn heap_size(&self) -> usize {
746        // cache is not data owner => only memory for reference itself counted
747        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}