Skip to content

Commit f7f50cd

Browse files
authored
Merge pull request #29 from orxfun/SplitVec-is-extended-by-try_grow
SplitVec is extended by try_grow
2 parents 0d11d87 + 38dcf3d commit f7f50cd

File tree

6 files changed

+68
-15
lines changed

6 files changed

+68
-15
lines changed

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "orx-split-vec"
3-
version = "2.4.0"
3+
version = "2.5.0"
44
edition = "2021"
55
authors = ["orxfun <[email protected]>"]
66
description = "An efficient constant access time vector with dynamic capacity and pinned elements."
@@ -10,7 +10,7 @@ keywords = ["vec", "array", "split", "fragments", "pinned"]
1010
categories = ["data-structures", "rust-patterns"]
1111

1212
[dependencies]
13-
orx-pinned-vec = "2.3"
13+
orx-pinned-vec = "2.4"
1414

1515
[[bench]]
1616
name = "serial_access"

src/common_traits/debug.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use orx_pinned_vec::PinnedVec;
2+
13
use crate::{Growth, SplitVec};
24
use std::fmt::Debug;
35

@@ -7,11 +9,16 @@ where
79
G: Growth,
810
{
911
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10-
writeln!(f, "SplitVec [")?;
12+
writeln!(
13+
f,
14+
"SplitVec {{ len: {}, capacity:{}, data: [",
15+
self.len(),
16+
self.capacity()
17+
)?;
1118
for frag in &self.fragments {
1219
writeln!(f, " {:?}", frag)?;
1320
}
14-
writeln!(f, "]")
21+
writeln!(f, "] }}")
1522
}
1623
}
1724

@@ -28,7 +35,7 @@ mod tests {
2835

2936
let debug_str = format!("{:?}", vec);
3037
assert_eq!(
31-
"SplitVec [\n [0, 1, 2, 3]\n [4, 5, 6, 7, 8, 9, 10, 11]\n [12]\n]\n",
38+
"SplitVec { len: 13, capacity:28, data: [\n [0, 1, 2, 3]\n [4, 5, 6, 7, 8, 9, 10, 11]\n [12]\n] }\n",
3239
debug_str
3340
);
3441
}

src/common_traits/iterator/from_iter.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,20 @@ where
1616

1717
#[cfg(test)]
1818
mod tests {
19-
use crate::{Doubling, Linear, SplitVec};
19+
use crate::{Doubling, Recursive, SplitVec};
2020

2121
#[test]
2222
fn collect() {
2323
let vec = SplitVec::<_, Doubling>::from_iter([0, 1, 2, 3, 4, 5]);
2424
assert_eq!(&vec, &[0, 1, 2, 3, 4, 5]);
2525

26-
let vec = SplitVec::<_, Linear>::from_iter([0, 1, 2, 3, 4, 5]);
27-
assert_eq!(&vec, &[0, 1, 2, 3, 4, 5]);
28-
2926
let vec = SplitVec::<_>::from_iter([0, 1, 2, 3, 4, 5]);
3027
assert_eq!(&vec, &[0, 1, 2, 3, 4, 5]);
3128

3229
let vec: SplitVec<_, Doubling> = (0..6).collect();
3330
assert_eq!(&vec, &[0, 1, 2, 3, 4, 5]);
3431

35-
let vec: SplitVec<_, Linear> = (0..6).collect();
32+
let vec: SplitVec<_, Recursive> = (0..6).collect();
3633
assert_eq!(&vec, &[0, 1, 2, 3, 4, 5]);
3734

3835
let vec: SplitVec<_> = (0..6).collect();
@@ -44,7 +41,7 @@ mod tests {
4441
let vec: SplitVec<_, Doubling> = (0..6).filter(|x| x % 2 == 0).collect();
4542
assert_eq!(&vec, &[0, 2, 4]);
4643

47-
let vec: SplitVec<_, Linear> = (0..6).filter(|x| x % 2 == 0).collect();
44+
let vec: SplitVec<_, Recursive> = (0..6).filter(|x| x % 2 == 0).collect();
4845
assert_eq!(&vec, &[0, 2, 4]);
4946
}
5047
}

src/fragment/fragment_struct.rs

+4
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,27 @@
88
pub struct Fragment<T> {
99
pub(crate) data: Vec<T>,
1010
}
11+
1112
impl<T> Fragment<T> {
1213
/// Creates a new fragment with the given `capacity` and pushes already the `first_value`.
1314
pub fn new_with_first_value(capacity: usize, first_value: T) -> Self {
1415
let mut data = Vec::with_capacity(capacity);
1516
data.push(first_value);
1617
Self { data }
1718
}
19+
1820
/// Creates a new fragment with the given `capacity`.
1921
pub fn new(capacity: usize) -> Self {
2022
Self {
2123
data: Vec::with_capacity(capacity),
2224
}
2325
}
26+
2427
/// Returns whether the fragment has room to push a new item or not.
2528
pub fn has_capacity_for_one(&self) -> bool {
2629
self.data.len() < self.data.capacity()
2730
}
31+
2832
/// Returns the available capacity in the fragment.
2933
pub fn room(&self) -> usize {
3034
self.data.capacity() - self.data.len()

src/growth/linear/linear_growth.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use crate::{Fragment, SplitVec};
3636
/// assert_eq!(Some(16), vec.fragments().last().map(|f| f.capacity()));
3737
/// assert_eq!(Some(1), vec.fragments().last().map(|f| f.len()));
3838
/// ```
39-
#[derive(Debug, Default, Clone, PartialEq)]
39+
#[derive(Debug, Clone, PartialEq)]
4040
pub struct Linear {
4141
constant_fragment_capacity_exponent: usize,
4242
constant_fragment_capacity: usize,

src/pinned_vec.rs

+48-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{Growth, SplitVec};
22
use orx_pinned_vec::utils::slice;
3-
use orx_pinned_vec::PinnedVec;
3+
use orx_pinned_vec::{PinnedVec, PinnedVecGrowthError};
44

55
impl<T, G> PinnedVec<T> for SplitVec<T, G>
66
where
@@ -552,16 +552,29 @@ where
552552
for fragment in &mut self.fragments {
553553
let capacity = fragment.capacity();
554554
if remaining <= capacity {
555-
unsafe { fragment.set_len(remaining) };
555+
if fragment.len() != remaining {
556+
unsafe { fragment.set_len(remaining) };
557+
}
556558
} else {
557-
unsafe { fragment.set_len(capacity) };
559+
if fragment.len() != capacity {
560+
unsafe { fragment.set_len(capacity) };
561+
}
558562
remaining -= capacity;
559563
}
560564
}
561565

562566
debug_assert_eq!(new_len, self.len());
563567
debug_assert_eq!(new_len, self.fragments.iter().map(|x| x.len()).sum());
564568
}
569+
570+
fn try_grow(&mut self) -> Result<usize, PinnedVecGrowthError> {
571+
if self.len() < self.capacity() {
572+
Err(PinnedVecGrowthError::CanOnlyGrowWhenVecIsAtCapacity)
573+
} else {
574+
self.add_fragment();
575+
Ok(self.capacity())
576+
}
577+
}
565578
}
566579

567580
#[cfg(test)]
@@ -910,4 +923,36 @@ mod tests {
910923
assert!(unsafe { vec.get_ptr_mut(i) }.is_none());
911924
}
912925
}
926+
927+
#[test]
928+
fn try_grow() {
929+
fn test<G: Growth>(mut vec: SplitVec<usize, G>) {
930+
fn grow_one_fragment<G: Growth>(vec: &mut SplitVec<usize, G>) {
931+
let old_len = vec.len();
932+
let old_capacity = vec.capacity();
933+
assert!(old_len < old_capacity);
934+
935+
for i in old_len..old_capacity {
936+
assert_eq!(
937+
Err(PinnedVecGrowthError::CanOnlyGrowWhenVecIsAtCapacity),
938+
vec.try_grow()
939+
);
940+
vec.push(i);
941+
}
942+
assert_eq!(vec.capacity(), old_capacity);
943+
944+
let result = vec.try_grow();
945+
assert!(result.is_ok());
946+
let new_capacity = result.expect("is-ok");
947+
assert!(new_capacity > old_capacity);
948+
}
949+
950+
for _ in 0..5 {
951+
grow_one_fragment(&mut vec);
952+
}
953+
954+
assert_eq!(5 + 1, vec.fragments().len());
955+
}
956+
test_all_growth_types!(test);
957+
}
913958
}

0 commit comments

Comments
 (0)