Skip to content

Commit 3483d3b

Browse files
committed
Add HeapSizeOf trait and from_slice method
1 parent 855f85c commit 3483d3b

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ documentation = "http://doc.servo.org/smallvec/"
1212
[lib]
1313
name = "smallvec"
1414
path = "lib.rs"
15+
16+
[dependencies]
17+
heapsize = "0.3"

lib.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@
66
//! to the heap for larger allocations. This can be a useful optimization for improving cache
77
//! locality and reducing allocator traffic for workloads that fit within the inline buffer.
88
9+
extern crate heapsize;
10+
911
use std::borrow::{Borrow, BorrowMut};
1012
use std::cmp;
1113
use std::fmt;
1214
use std::hash::{Hash, Hasher};
1315
use std::iter::{IntoIterator, FromIterator};
1416
use std::mem;
17+
use std::os::raw::c_void;
1518
use std::ops;
1619
use std::ptr;
1720
use std::slice;
1821

22+
use heapsize::{HeapSizeOf, heap_size_of};
1923
use SmallVecData::{Inline, Heap};
2024

2125
/// Common operations implemented by both `Vec` and `SmallVec`.
@@ -478,6 +482,12 @@ impl<A: Array> SmallVec<A> {
478482
}
479483

480484
impl<A: Array> SmallVec<A> where A::Item: Copy {
485+
pub fn from_slice(slice: &[A::Item]) -> Self {
486+
let mut vec = Self::new();
487+
vec.extend_from_slice(slice);
488+
vec
489+
}
490+
481491
pub fn insert_from_slice(&mut self, index: usize, slice: &[A::Item]) {
482492
self.reserve(slice.len());
483493

@@ -500,6 +510,19 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
500510
}
501511
}
502512

513+
impl<A: Array> HeapSizeOf for SmallVec<A> where A::Item: HeapSizeOf {
514+
fn heap_size_of_children(&self) -> usize {
515+
match self.data {
516+
Inline { .. } => 0,
517+
Heap { ptr, .. } => {
518+
self.iter().fold(
519+
unsafe { heap_size_of(ptr as *const c_void) },
520+
|n, elem| n + elem.heap_size_of_children())
521+
},
522+
}
523+
}
524+
}
525+
503526
impl<A: Array> ops::Deref for SmallVec<A> {
504527
type Target = [A::Item];
505528
#[inline]
@@ -823,15 +846,17 @@ macro_rules! impl_array(
823846
}
824847
);
825848

826-
impl_array!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32,
849+
impl_array!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36,
827850
0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,
828851
0x10000, 0x20000, 0x40000, 0x80000, 0x100000);
829852

830853
#[cfg(test)]
831854
pub mod tests {
832855
use SmallVec;
856+
use heapsize::HeapSizeOf;
833857
use std::borrow::ToOwned;
834858
use std::iter::FromIterator;
859+
use std::mem::size_of;
835860

836861
// We heap allocate all these strings so that double frees will show up under valgrind.
837862

@@ -1248,6 +1273,35 @@ pub mod tests {
12481273
assert_eq!(&SmallVec::<[u32; 2]>::from(&[1, 2, 3][..])[..], [1, 2, 3]);
12491274
}
12501275

1276+
#[test]
1277+
fn test_from_slice() {
1278+
assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1][..])[..], [1]);
1279+
assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1, 2, 3][..])[..], [1, 2, 3]);
1280+
}
1281+
1282+
#[test]
1283+
fn test_heap_size_of_children() {
1284+
let mut vec = SmallVec::<[u32; 2]>::new();
1285+
assert_eq!(vec.heap_size_of_children(), 0);
1286+
vec.push(1);
1287+
vec.push(2);
1288+
assert_eq!(vec.heap_size_of_children(), 0);
1289+
vec.push(3);
1290+
assert_eq!(vec.heap_size_of_children(), 16);
1291+
1292+
// Now check with reserved space
1293+
let mut vec = SmallVec::<[u32; 2]>::new();
1294+
vec.reserve(10); // Rounds up to 16
1295+
assert_eq!(vec.heap_size_of_children(), 64);
1296+
1297+
// Check with nested heap structures
1298+
let mut vec = SmallVec::<[Vec<u32>; 2]>::new();
1299+
vec.reserve(10);
1300+
vec.push(vec![2, 3, 4]);
1301+
assert_eq!(vec.heap_size_of_children(),
1302+
vec![2, 3, 4].heap_size_of_children() + 16 * size_of::<Vec<u32>>());
1303+
}
1304+
12511305
#[test]
12521306
fn test_exact_size_iterator() {
12531307
let mut vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]);

0 commit comments

Comments
 (0)