Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 43 additions & 3 deletions src/impls/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,11 @@ where
/// Reserve space for `additional` elements.
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.smol.reserve(additional);
if self.chonk.is_empty() {
self.smol.reserve(additional);
} else {
self.chonk.reserve(additional);
}
}

/// Remove all elements.
Expand Down Expand Up @@ -299,6 +303,15 @@ where
fn is_empty(&self) -> bool {
self.is_empty()
}

#[inline]
fn capacity(&self) -> usize {
if self.chonk.is_empty() {
self.smol.capacity()
} else {
self.chonk.capacity()
}
}
}

impl<S, L> IndexContainer<usize> for IndexList<S, L>
Expand Down Expand Up @@ -407,6 +420,16 @@ where
fn heap_size<F: FnMut(usize, usize)>(&self, callback: F) {
self.spilled.heap_size(callback);
}

#[inline]
fn capacity(&self) -> usize {
if self.spilled.is_empty() {
// TODO: What else could we do here? `usize::MAX`?
1
} else {
self.spilled.capacity()
}
}
}

impl<S, L> IndexContainer<usize> for IndexOptimized<S, L>
Expand Down Expand Up @@ -439,8 +462,25 @@ where
where
I::IntoIter: ExactSizeIterator,
{
for item in iter {
self.push(item);
let mut iter = iter.into_iter();
if !self.spilled.is_empty() {
// We certainly push into `spilled`, so reserve enough space.
let (lower, upper) = iter.size_hint();
self.spilled.reserve(upper.unwrap_or(lower));
}
while let Some(item) = iter.next() {
if self.spilled.is_empty() {
let inserted = self.strided.push(item);
if !inserted {
// This is a transition point from pushing into `strided` to pushing into
// `spilled`.
let (lower, upper) = iter.size_hint();
self.spilled.reserve(upper.unwrap_or(lower));
self.spilled.push(item);
}
} else {
self.spilled.push(item);
}
}
}

Expand Down
60 changes: 59 additions & 1 deletion src/impls/mirror.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use std::marker::PhantomData;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{Index, IntoOwned, Push, Region, RegionPreference, ReserveItems};
use crate::{
CanPush, Index, IntoOwned, Push, Region, RegionPreference, Reserve, ReserveItems, TryPush,
};

/// A region for types where the read item type is equal to the index type.
///
Expand Down Expand Up @@ -99,6 +101,25 @@ where
}
}

impl<T> TryPush<T> for MirrorRegion<T>
where
for<'a> T: Index + IntoOwned<'a, Owned = T>,
{
#[inline(always)]
fn try_push(&mut self, item: T) -> Result<Self::Index, T> {
Ok(item)
}
}

impl<T> CanPush<T> for MirrorRegion<T> {
fn can_push<I>(&self, _: I) -> bool
where
I: Iterator<Item = T> + Clone,
{
true
}
}

impl<T> Push<&T> for MirrorRegion<T>
where
for<'a> T: Index + IntoOwned<'a, Owned = T>,
Expand All @@ -109,6 +130,25 @@ where
}
}

impl<'a, T> CanPush<&'a T> for MirrorRegion<T> {
fn can_push<I>(&self, _: I) -> bool
where
I: Iterator<Item = &'a T> + Clone,
{
true
}
}

impl<'b, T> TryPush<&'b T> for MirrorRegion<T>
where
for<'a> T: Index + IntoOwned<'a, Owned = T>,
{
#[inline(always)]
fn try_push(&mut self, item: &'b T) -> Result<Self::Index, &'b T> {
Ok(*item)
}
}

impl<T> Push<&&T> for MirrorRegion<T>
where
for<'a> T: Index + IntoOwned<'a, Owned = T>,
Expand All @@ -119,6 +159,16 @@ where
}
}

impl<'b, 'c, T> TryPush<&'b &'c T> for MirrorRegion<T>
where
for<'a> T: Index + IntoOwned<'a, Owned = T>,
{
#[inline(always)]
fn try_push(&mut self, item: &'b &'c T) -> Result<Self::Index, &'b &'c T> {
Ok(**item)
}
}

impl<T> ReserveItems<T> for MirrorRegion<T>
where
for<'a> T: Index + IntoOwned<'a, Owned = T>,
Expand All @@ -145,6 +195,14 @@ where
}
}

impl<T> Reserve for MirrorRegion<T> {
type Reserve = ();

fn reserve(&mut self, (): &Self::Reserve) {
// No storage
}
}

macro_rules! implement_for {
($index_type:ty) => {
impl RegionPreference for $index_type {
Expand Down
13 changes: 12 additions & 1 deletion src/impls/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{IntoOwned, Push, Region, RegionPreference, ReserveItems};
use crate::{IntoOwned, Push, Region, RegionPreference, Reserve, ReserveItems};

impl<T: RegionPreference> RegionPreference for Option<T> {
type Owned = Option<T::Owned>;
Expand Down Expand Up @@ -167,6 +167,17 @@ where
}
}

impl<R> Reserve for OptionRegion<R>
where
R: Reserve,
{
type Reserve = R::Reserve;

fn reserve(&mut self, size: &Self::Reserve) {
self.inner.reserve(size);
}
}

#[cfg(test)]
mod tests {
use crate::{MirrorRegion, OwnedRegion, Region, ReserveItems};
Expand Down
15 changes: 14 additions & 1 deletion src/impls/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{IntoOwned, Push, Region, RegionPreference, ReserveItems};
use crate::{IntoOwned, Push, Region, RegionPreference, Reserve, ReserveItems};

impl<T: RegionPreference, E: RegionPreference> RegionPreference for Result<T, E> {
type Owned = Result<T::Owned, E::Owned>;
Expand Down Expand Up @@ -194,6 +194,19 @@ where
}
}

impl<T, E> Reserve for ResultRegion<T, E>
where
T: Reserve,
E: Reserve,
{
type Reserve = (T::Reserve, E::Reserve);

fn reserve(&mut self, (t, e): &Self::Reserve) {
self.oks.reserve(t);
self.errs.reserve(e);
}
}

#[cfg(test)]
mod tests {
use crate::{MirrorRegion, OwnedRegion, Region, ReserveItems};
Expand Down
Loading