Skip to content

Commit d3a5a6f

Browse files
committed
add support for zero length HeaderVec
Having a HeaderVec being zero length is mostly useless because it has to reallocated instanly when anything becomes pushed. This clearly should be avoided! Nevertheless supporting zero length takes out a corner-case and a potential panic and removes the burden for users explicitly ensuring zero length HeaderVecs don't happen in practice. Generally improving software reliability.
1 parent 2b4fbf6 commit d3a5a6f

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ impl<H, T> HeaderVec<H, T> {
6060
}
6161

6262
pub fn with_capacity(capacity: usize, head: H) -> Self {
63-
assert!(capacity > 0, "HeaderVec capacity cannot be 0");
6463
// Allocate the initial memory, which is uninitialized.
6564
let layout = Self::layout(capacity);
6665
let ptr = unsafe { alloc::alloc::alloc(layout) } as *mut AlignedHeader<H, T>;
@@ -271,8 +270,6 @@ impl<H, T> HeaderVec<H, T> {
271270
"requested capacity is less than current length"
272271
);
273272
let old_capacity = self.capacity();
274-
debug_assert_ne!(old_capacity, 0, "capacity of 0 not yet supported");
275-
debug_assert_ne!(requested_capacity, 0, "capacity of 0 not yet supported");
276273

277274
let new_capacity = if requested_capacity > old_capacity {
278275
if exact {
@@ -281,11 +278,14 @@ impl<H, T> HeaderVec<H, T> {
281278
} else if requested_capacity <= old_capacity * 2 {
282279
// doubling the capacity is sufficient
283280
old_capacity * 2
284-
} else {
281+
} else if old_capacity > 0 {
285282
// requested more than twice as much space, reserve the next multiple of
286283
// old_capacity that is greater than the requested capacity. This gives headroom
287284
// for new inserts while not doubling the memory requirement with bulk requests
288285
(requested_capacity / old_capacity + 1).saturating_mul(old_capacity)
286+
} else {
287+
// special case when we start at capacity 0
288+
requested_capacity
289289
}
290290
} else if exact {
291291
// exact shrinking

tests/simple.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ struct TestA {
1111
c: usize,
1212
}
1313

14+
#[test]
15+
fn test_empty() {
16+
let mut v_empty = HeaderVec::with_capacity(0, TestA { a: 4, b: !0, c: 66 });
17+
18+
assert_eq!(0, v_empty.len());
19+
assert_eq!(0, v_empty.capacity());
20+
assert_eq!(0, v_empty.as_slice().len());
21+
22+
v_empty.extend_from_slice("the quick brown fox jumps over the lazy dog".as_bytes());
23+
}
24+
1425
#[test]
1526
fn test_head_array() {
1627
let mut v_orig = HeaderVec::new(TestA { a: 4, b: !0, c: 66 });

0 commit comments

Comments
 (0)