diff --git a/Cargo.lock b/Cargo.lock index 61fabfd9..62931cd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,6 +82,7 @@ dependencies = [ "parking_lot_core", "rayon", "serde", + "typesize", ] [[package]] @@ -158,9 +159,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -239,15 +240,35 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "syn" -version = "2.0.29" +version = "2.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "typesize" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "666137410f50df35fabf3c8ac6380d47281e9523799c74df192abba1b508b4bf" +dependencies = [ + "typesize-derive", +] + +[[package]] +name = "typesize-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905e88c2a4cc27686bd57e495121d451f027e441388a67f773be729ad4be1ea8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-ident" version = "1.0.11" diff --git a/Cargo.toml b/Cargo.toml index 5b3dd767..b82156d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ categories = ["concurrency", "algorithms", "data-structures"] [features] raw-api = [] +typesize = ["dep:typesize"] inline = ["hashbrown/inline-more"] [dependencies] @@ -27,6 +28,7 @@ rayon = { version = "1.7.0", optional = true } once_cell = "1.18.0" arbitrary = { version = "1.3.0", optional = true } crossbeam-utils = "0.8" +typesize = { version = "0.1.8", default-features = false, optional = true } [package.metadata.docs.rs] features = ["rayon", "raw-api", "serde"] diff --git a/src/lib.rs b/src/lib.rs index ad2b321a..c0abb5e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1346,6 +1346,45 @@ impl FromIterator<(K, V)> for } } +#[cfg(feature = "typesize")] +impl typesize::TypeSize for DashMap +where + K: typesize::TypeSize + Eq + Hash, + V: typesize::TypeSize, + S: typesize::TypeSize + Clone + BuildHasher, +{ + fn extra_size(&self) -> usize { + let shards_extra_size: usize = self + .shards + .iter() + .map(|shard_lock| { + let shard = shard_lock.read(); + let hashtable_size = shard.allocation_info().1.size(); + + // Safety: The iterator is dropped before the HashTable + let iter = unsafe { shard.iter() }; + let entry_size_iter = iter.map(|bucket| { + // Safety: The iterator returns buckets with valid pointers to entries + let (key, value) = unsafe { bucket.as_ref() }; + key.extra_size() + value.get().extra_size() + }); + + core::mem::size_of::>>>() + + hashtable_size + + entry_size_iter.sum::() + }) + .sum(); + + self.hasher.extra_size() + shards_extra_size + } + + typesize::if_typesize_details! { + fn get_collection_item_count(&self) -> Option { + Some(self.len()) + } + } +} + #[cfg(test)] mod tests { use crate::DashMap; diff --git a/src/set.rs b/src/set.rs index 14110084..84c9dd16 100644 --- a/src/set.rs +++ b/src/set.rs @@ -415,6 +415,23 @@ impl FromIterator for DashSet } } +#[cfg(feature = "typesize")] +impl typesize::TypeSize for DashSet +where + K: typesize::TypeSize + Eq + Hash, + S: typesize::TypeSize + Clone + BuildHasher, +{ + fn extra_size(&self) -> usize { + self.inner.extra_size() + } + + typesize::if_typesize_details! { + fn get_collection_item_count(&self) -> Option { + Some(self.len()) + } + } +} + #[cfg(test)] mod tests { use crate::DashSet;