Skip to content

Commit

Permalink
Replace Vector::Empty with Vector::Inline using InlineArray.
Browse files Browse the repository at this point in the history
  • Loading branch information
bodil committed May 18, 2019
1 parent b7578f8 commit 60de96d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 83 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -30,6 +30,13 @@ The minimum supported Rust version is now 1.34.0.

### Fixed

- `Vector` now uses
[`sized_chunks::InlineArray`](https://docs.rs/sized-chunks/0.3.0/sized_chunks/inline_array/struct.InlineArray.html)
instead of an `Empty` enum case to avoid allocation at very small sizes,
letting you store a handful of elements on the stack before needing to grow
into a full chunk. This has a beneficial effect on performance as well, as
there's no pointer into the heap to dereference, making it faster than
`std::vec::Vec` in this configuration.
- Some complexity timings have been added and corrected. (#87)
- `OrdSet::is_subset(&self, other)` now returns immediately when `self` is
larger than `other` and thus could not possibly be a subset of it. (#87)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -25,7 +25,7 @@ rustc_version = "0.2"

[dependencies]
typenum = "1.10"
sized-chunks = "0.2.0"
sized-chunks = "0.3.0"
quickcheck = { version = "0.8", optional = true }
proptest = { version = "0.9", optional = true }
serde = { version = "1.0", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion rc/Cargo.toml
Expand Up @@ -24,7 +24,7 @@ rustc_version = "0.2"

[dependencies]
typenum = "1.10"
sized-chunks = "0.1.2"
sized-chunks = "0.3.0"
quickcheck = { version = "0.8", optional = true }
proptest = { version = "0.9", optional = true }
serde = { version = "1.0", optional = true }
Expand Down
20 changes: 2 additions & 18 deletions src/vector/focus.rs
Expand Up @@ -85,8 +85,6 @@ pub enum Focus<'a, A>
where
A: 'a,
{
#[doc(hidden)]
Empty,
#[doc(hidden)]
Single(&'a [A]),
#[doc(hidden)]
Expand All @@ -102,7 +100,7 @@ where
/// [Vector]: enum.Vector.html
pub fn new(vector: &'a Vector<A>) -> Self {
match vector {
Vector::Empty => Focus::Empty,
Vector::Inline(chunk) => Focus::Single(chunk),
Vector::Single(chunk) => Focus::Single(chunk),
Vector::Full(tree) => Focus::Full(TreeFocus::new(tree)),
}
Expand All @@ -113,7 +111,6 @@ where
/// [Vector]: enum.Vector.html
pub fn len(&self) -> usize {
match self {
Focus::Empty => 0,
Focus::Single(chunk) => chunk.len(),
Focus::Full(tree) => tree.len(),
}
Expand All @@ -129,7 +126,6 @@ where
/// Get a reference to the value at a given index.
pub fn get(&mut self, index: usize) -> Option<&A> {
match self {
Focus::Empty => None,
Focus::Single(chunk) => chunk.get(index),
Focus::Full(tree) => tree.get(index),
}
Expand All @@ -152,7 +148,6 @@ where
panic!("vector::Focus::chunk_at: index out of bounds");
}
match self {
Focus::Empty => (0..0, &[]),
Focus::Single(chunk) => (0..len, chunk),
Focus::Full(tree) => tree.get_chunk(index),
}
Expand Down Expand Up @@ -190,7 +185,6 @@ where
panic!("vector::Focus::narrow: range out of bounds");
}
match self {
Focus::Empty => Focus::Empty,
Focus::Single(chunk) => Focus::Single(&chunk[r]),
Focus::Full(tree) => Focus::Full(tree.narrow(r)),
}
Expand Down Expand Up @@ -231,7 +225,6 @@ where
panic!("vector::Focus::split_at: index out of bounds");
}
match self {
Focus::Empty => (Focus::Empty, Focus::Empty),
Focus::Single(chunk) => {
let (left, right) = chunk.split_at(index);
(Focus::Single(left), Focus::Single(right))
Expand Down Expand Up @@ -262,7 +255,6 @@ where
{
fn clone(&self) -> Self {
match self {
Focus::Empty => Focus::Empty,
Focus::Single(chunk) => Focus::Single(chunk),
Focus::Full(tree) => Focus::Full(tree.clone()),
}
Expand Down Expand Up @@ -483,8 +475,6 @@ pub enum FocusMut<'a, A>
where
A: 'a,
{
#[doc(hidden)]
Empty,
#[doc(hidden)]
Single(&'a mut [A]),
#[doc(hidden)]
Expand All @@ -498,7 +488,7 @@ where
/// Construct a `FocusMut` for a `Vector`.
pub fn new(vector: &'a mut Vector<A>) -> Self {
match vector {
Vector::Empty => FocusMut::Empty,
Vector::Inline(chunk) => FocusMut::Single(chunk),
Vector::Single(chunk) => FocusMut::Single(Ref::make_mut(chunk).as_mut_slice()),
Vector::Full(tree) => FocusMut::Full(TreeFocusMut::new(tree)),
}
Expand All @@ -507,7 +497,6 @@ where
/// Get the length of the focused `Vector`.
pub fn len(&self) -> usize {
match self {
FocusMut::Empty => 0,
FocusMut::Single(chunk) => chunk.len(),
FocusMut::Full(tree) => tree.len(),
}
Expand All @@ -526,7 +515,6 @@ where
/// Get a mutable reference to the value at a given index.
pub fn get_mut(&mut self, index: usize) -> Option<&mut A> {
match self {
FocusMut::Empty => None,
FocusMut::Single(chunk) => chunk.get_mut(index),
FocusMut::Full(tree) => tree.get(index),
}
Expand Down Expand Up @@ -645,7 +633,6 @@ where
panic!("vector::FocusMut::chunk_at: index out of bounds");
}
match self {
FocusMut::Empty => (0..0, &mut []),
FocusMut::Single(chunk) => (0..len, chunk),
FocusMut::Full(tree) => {
let (range, chunk) = tree.get_chunk(index);
Expand Down Expand Up @@ -686,7 +673,6 @@ where
panic!("vector::FocusMut::narrow: range out of bounds");
}
match self {
FocusMut::Empty => FocusMut::Empty,
FocusMut::Single(chunk) => FocusMut::Single(&mut chunk[r]),
FocusMut::Full(tree) => FocusMut::Full(tree.narrow(r)),
}
Expand Down Expand Up @@ -734,7 +720,6 @@ where
panic!("vector::FocusMut::split_at: index out of bounds");
}
match self {
FocusMut::Empty => (FocusMut::Empty, FocusMut::Empty),
FocusMut::Single(chunk) => {
let (left, right) = chunk.split_at_mut(index);
(FocusMut::Single(left), FocusMut::Single(right))
Expand All @@ -749,7 +734,6 @@ where
/// Convert a `FocusMut` into a `Focus`.
pub fn unmut(self) -> Focus<'a, A> {
match self {
FocusMut::Empty => Focus::Empty,
FocusMut::Single(chunk) => Focus::Single(chunk),
FocusMut::Full(mut tree) => Focus::Full(TreeFocus {
tree: {
Expand Down

0 comments on commit 60de96d

Please sign in to comment.