Skip to content

Commit ad3cf2a

Browse files
authored
Merge pull request #78 from sfackler/master
Implement HeapSizeOf for LinkedHashMap
2 parents f757231 + c7e16c9 commit ad3cf2a

File tree

5 files changed

+79
-2
lines changed

5 files changed

+79
-2
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ sudo: false
33
matrix:
44
include:
55
- rust: beta
6-
env: FEATURES="serde_impl"
6+
env: FEATURES="serde_impl heapsize_impl"
77
- rust: nightly
8-
env: FEATURES="serde_impl nightly clippy"
8+
env: FEATURES="serde_impl nightly clippy heapsize_impl"
99
- rust: stable
1010
script:
1111
- cargo build --features "$FEATURES"

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ readme = "README.md"
1818
[features]
1919
nightly = []
2020
serde_impl = ["serde", "serde_test"]
21+
heapsize_impl = ["heapsize"]
2122

2223
[dependencies]
2324
clippy = { version = "0.*", optional = true }
2425
serde = { version = "0.9", optional = true }
2526
serde_test = { version = "0.9", optional = true }
27+
heapsize = { version = "0.3.9", optional = true }

src/heapsize.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
extern crate heapsize;
2+
3+
use self::heapsize::{HeapSizeOf, heap_size_of};
4+
use std::hash::{Hash, BuildHasher};
5+
6+
use {LinkedHashMap, KeyRef, Node};
7+
8+
impl<K> HeapSizeOf for KeyRef<K> {
9+
fn heap_size_of_children(&self) -> usize {
10+
0
11+
}
12+
}
13+
14+
impl<K, V> HeapSizeOf for Node<K, V>
15+
where K: HeapSizeOf,
16+
V: HeapSizeOf
17+
{
18+
fn heap_size_of_children(&self) -> usize {
19+
self.key.heap_size_of_children() + self.value.heap_size_of_children()
20+
}
21+
}
22+
23+
impl<K, V, S> HeapSizeOf for LinkedHashMap<K, V, S>
24+
where K: HeapSizeOf + Hash + Eq,
25+
V: HeapSizeOf,
26+
S: BuildHasher
27+
{
28+
fn heap_size_of_children(&self) -> usize {
29+
unsafe {
30+
let mut size = self.map.heap_size_of_children();
31+
for &value in self.map.values() {
32+
size += (*value).heap_size_of_children();
33+
size += heap_size_of(value as *const _ as *const _);
34+
}
35+
36+
if !self.head.is_null() {
37+
size += heap_size_of(self.head as *const _ as *const _);
38+
}
39+
40+
let mut free = self.free;
41+
while !free.is_null() {
42+
size += heap_size_of(free as *const _ as *const _);
43+
free = (*free).next
44+
}
45+
46+
size
47+
}
48+
}
49+
}

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
// Optional Serde support
3838
#[cfg(feature = "serde_impl")]
3939
pub mod serde;
40+
// Optional Heapsize support
41+
#[cfg(feature = "heapsize_impl")]
42+
mod heapsize;
4043

4144
use std::borrow::Borrow;
4245
use std::cmp::Ordering;

tests/heapsize.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![cfg(feature = "heapsize_impl")]
2+
3+
extern crate heapsize;
4+
extern crate linked_hash_map;
5+
6+
use linked_hash_map::LinkedHashMap;
7+
use heapsize::HeapSizeOf;
8+
9+
#[test]
10+
fn empty() {
11+
assert_eq!(LinkedHashMap::<String, String>::new().heap_size_of_children(), 0);
12+
}
13+
14+
#[test]
15+
fn nonempty() {
16+
let mut map = LinkedHashMap::new();
17+
map.insert("hello".to_string(), "world".to_string());
18+
map.insert("hola".to_string(), "mundo".to_string());
19+
map.insert("bonjour".to_string(), "monde".to_string());
20+
map.remove("hello");
21+
22+
assert!(map.heap_size_of_children() != 0);
23+
}

0 commit comments

Comments
 (0)