mirror of
https://github.com/clockworklabs/SpacetimeDB.git
synced 2026-05-10 17:49:49 -04:00
ed2a18cff7
# Description of Changes There were mentions of `hashbrown` in the repo that did not go through `spacetimedb_data_structures::map`. This caused compile errors on master when running certain tests locally. These have been replaced with the proper imports. The PR also bump hashbrown to 0.16.1 and foldhash to 0.2.0. # API and ABI breaking changes None # Expected complexity level and risk 2 # Testing Covered by existing tests.
143 lines
4.1 KiB
Rust
143 lines
4.1 KiB
Rust
use core::mem;
|
|
use core::sync::atomic::AtomicUsize;
|
|
|
|
/// For inspecting how much memory a value is using.
|
|
///
|
|
/// This trait specifically measures heap memory. If you want to measure stack memory too, add
|
|
/// `mem::size_of_val()` to it. (This only really matters for the outermost type in a hierarchy.)
|
|
pub trait MemoryUsage {
|
|
/// The **heap** memory usage of this type. The default implementation returns 0.
|
|
#[inline(always)]
|
|
fn heap_usage(&self) -> usize {
|
|
0
|
|
}
|
|
}
|
|
|
|
impl MemoryUsage for () {}
|
|
impl MemoryUsage for bool {}
|
|
impl MemoryUsage for u8 {}
|
|
impl MemoryUsage for u16 {}
|
|
impl MemoryUsage for u32 {}
|
|
impl MemoryUsage for u64 {}
|
|
impl MemoryUsage for u128 {}
|
|
#[cfg(feature = "ethnum")]
|
|
impl MemoryUsage for ethnum::u256 {}
|
|
impl MemoryUsage for usize {}
|
|
impl MemoryUsage for AtomicUsize {}
|
|
impl MemoryUsage for i8 {}
|
|
impl MemoryUsage for i16 {}
|
|
impl MemoryUsage for i32 {}
|
|
impl MemoryUsage for i64 {}
|
|
impl MemoryUsage for i128 {}
|
|
#[cfg(feature = "ethnum")]
|
|
impl MemoryUsage for ethnum::i256 {}
|
|
impl MemoryUsage for isize {}
|
|
impl MemoryUsage for f32 {}
|
|
impl MemoryUsage for f64 {}
|
|
#[cfg(feature = "decorum")]
|
|
impl MemoryUsage for decorum::Total<f32> {}
|
|
#[cfg(feature = "decorum")]
|
|
impl MemoryUsage for decorum::Total<f64> {}
|
|
|
|
impl<T: MemoryUsage + ?Sized> MemoryUsage for &T {
|
|
fn heap_usage(&self) -> usize {
|
|
(*self).heap_usage()
|
|
}
|
|
}
|
|
|
|
impl<T: MemoryUsage + ?Sized> MemoryUsage for Box<T> {
|
|
fn heap_usage(&self) -> usize {
|
|
mem::size_of_val::<T>(self) + T::heap_usage(self)
|
|
}
|
|
}
|
|
|
|
impl<T: MemoryUsage + ?Sized> MemoryUsage for std::sync::Arc<T> {
|
|
fn heap_usage(&self) -> usize {
|
|
let refcounts = mem::size_of::<usize>() * 2;
|
|
refcounts + mem::size_of_val::<T>(self) + T::heap_usage(self)
|
|
}
|
|
}
|
|
|
|
impl<T: MemoryUsage + ?Sized> MemoryUsage for std::rc::Rc<T> {
|
|
fn heap_usage(&self) -> usize {
|
|
let refcounts = mem::size_of::<usize>() * 2;
|
|
refcounts + mem::size_of_val::<T>(self) + T::heap_usage(self)
|
|
}
|
|
}
|
|
|
|
impl<T: MemoryUsage> MemoryUsage for [T] {
|
|
fn heap_usage(&self) -> usize {
|
|
self.iter().map(T::heap_usage).sum()
|
|
}
|
|
}
|
|
|
|
impl<T: MemoryUsage, const N: usize> MemoryUsage for [T; N] {
|
|
fn heap_usage(&self) -> usize {
|
|
self.iter().map(T::heap_usage).sum()
|
|
}
|
|
}
|
|
|
|
impl MemoryUsage for str {}
|
|
|
|
impl<T: MemoryUsage> MemoryUsage for Option<T> {
|
|
fn heap_usage(&self) -> usize {
|
|
self.as_ref().map_or(0, T::heap_usage)
|
|
}
|
|
}
|
|
|
|
impl<A: MemoryUsage, B: MemoryUsage> MemoryUsage for (A, B) {
|
|
fn heap_usage(&self) -> usize {
|
|
self.0.heap_usage() + self.1.heap_usage()
|
|
}
|
|
}
|
|
|
|
impl MemoryUsage for String {
|
|
fn heap_usage(&self) -> usize {
|
|
self.capacity()
|
|
}
|
|
}
|
|
|
|
impl<T: MemoryUsage> MemoryUsage for Vec<T> {
|
|
fn heap_usage(&self) -> usize {
|
|
self.capacity() * mem::size_of::<T>() + self.iter().map(T::heap_usage).sum::<usize>()
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "hash_map")]
|
|
impl<K: MemoryUsage + Eq + core::hash::Hash, V: MemoryUsage, S: core::hash::BuildHasher> MemoryUsage
|
|
for hashbrown::HashMap<K, V, S>
|
|
{
|
|
fn heap_usage(&self) -> usize {
|
|
self.allocation_size() + self.iter().map(|(k, v)| k.heap_usage() + v.heap_usage()).sum::<usize>()
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "hash_map")]
|
|
impl<K: MemoryUsage + Eq + core::hash::Hash, S: core::hash::BuildHasher> MemoryUsage for hashbrown::HashSet<K, S> {
|
|
fn heap_usage(&self) -> usize {
|
|
self.allocation_size() + self.iter().map(|k| k.heap_usage()).sum::<usize>()
|
|
}
|
|
}
|
|
|
|
impl<K: MemoryUsage, V: MemoryUsage> MemoryUsage for std::collections::BTreeMap<K, V> {
|
|
fn heap_usage(&self) -> usize {
|
|
// NB: this is best-effort, since we don't have a `capacity()` method on `BTreeMap`.
|
|
self.len() * mem::size_of::<(K, V)>() + self.iter().map(|(k, v)| k.heap_usage() + v.heap_usage()).sum::<usize>()
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "smallvec")]
|
|
impl<A: smallvec::Array> MemoryUsage for smallvec::SmallVec<A>
|
|
where
|
|
A::Item: MemoryUsage,
|
|
{
|
|
fn heap_usage(&self) -> usize {
|
|
self.as_slice().heap_usage()
|
|
+ if self.spilled() {
|
|
self.capacity() * mem::size_of::<A::Item>()
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
}
|