Skip to content

Commit

Permalink
Merge pull request #42 from orxfun/support-for-concurrency
Browse files Browse the repository at this point in the history
support-for-concurrency
  • Loading branch information
orxfun authored Jul 23, 2024
2 parents 1694406 + f536ba2 commit 0b0359a
Show file tree
Hide file tree
Showing 19 changed files with 704 additions and 690 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "orx-split-vec"
version = "2.14.0"
version = "3.0.0"
edition = "2021"
authors = ["orxfun <[email protected]>"]
description = "An efficient constant access time vector with dynamic capacity and pinned elements."
Expand All @@ -10,7 +10,8 @@ keywords = ["vec", "array", "split", "fragments", "pinned"]
categories = ["data-structures", "rust-patterns"]

[dependencies]
orx-pinned-vec = "2.12"
orx-pseudo-default = "1.0"
orx-pinned-vec = "3.0"

[[bench]]
name = "serial_access"
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,19 @@ use orx_split_vec::*;

#[derive(Clone)]
struct MyCustomGrowth;

impl Growth for MyCustomGrowth {
fn new_fragment_capacity<T>(&self, fragments: &[Fragment<T>]) -> usize {
fragments.last().map(|f| f.capacity() + 1).unwrap_or(4)
fn new_fragment_capacity_from(&self, fragment_capacities: impl ExactSizeIterator<Item = usize>) -> usize {
fragment_capacities.last().map(|f| f + 1).unwrap_or(4)
}
}

impl PseudoDefault for MyCustomGrowth {
fn pseudo_default() -> Self {
MyCustomGrowth
}
}

// set the growth explicitly
let vec: SplitVec<i32, Linear> = SplitVec::with_linear_growth(4);
let vec: SplitVec<i32, Doubling> = SplitVec::with_doubling_growth();
Expand Down
69 changes: 69 additions & 0 deletions src/common_traits/iterator/iter_con.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use super::iter_fragment::FragmentIter;
use crate::fragment::fragment_struct::Fragment;
use std::iter::FusedIterator;

/// Iterator over the `SplitVec`.
///
/// This struct is created by `SplitVec::iter()` method.
#[derive(Debug, Clone)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct IterCon<'a, T> {
num_fragments: usize,
last_fragment_len: usize,
fragments: &'a [Fragment<T>],
inner: FragmentIter<'a, T>,
f: usize,
}

impl<'a, T> IterCon<'a, T> {
pub(crate) fn new(fragments: &'a [Fragment<T>], last_fragment_len: usize) -> Self {
assert!(fragments.len() > 0);

let num_fragments = fragments.len();

let first_fragment_len = match num_fragments {
0 => 0,
1 => last_fragment_len,
_ => fragments[0].capacity(),
};
let inner = FragmentIter::new(&fragments[0], first_fragment_len);

Self {
num_fragments,
last_fragment_len,
fragments,
inner,
f: 0,
}
}

fn next_fragment(&mut self) -> Option<&'a T> {
match self.f + 1 < self.num_fragments {
true => {
self.f += 1;
let fragment_len = match self.f == self.num_fragments - 1 {
false => self.fragments[self.f].capacity(),
true => self.last_fragment_len,
};
self.inner = FragmentIter::new(&self.fragments[self.f], fragment_len);
self.next()
}
false => None,
}
}
}

impl<'a, T> Iterator for IterCon<'a, T> {
type Item = &'a T;

#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
let next_element = self.inner.next();
match next_element.is_some() {
true => next_element,
false => self.next_fragment(),
}
}
}

impl<T> FusedIterator for IterCon<'_, T> {}
35 changes: 35 additions & 0 deletions src/common_traits/iterator/iter_fragment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::Fragment;
use std::marker::PhantomData;

#[derive(Debug, Clone)]
pub(crate) struct FragmentIter<'a, T> {
fragment: &'a [T],
i: usize,
phantom: PhantomData<&'a ()>,
}

impl<'a, T> FragmentIter<'a, T> {
pub(crate) fn new(fragment: &'a Fragment<T>, len: usize) -> Self {
let fragment = unsafe { std::slice::from_raw_parts(fragment.as_ptr(), len) };
Self {
fragment,
i: 0,
phantom: PhantomData,
}
}
}

impl<'a, T: 'a> Iterator for FragmentIter<'a, T> {
type Item = &'a T;

fn next(&mut self) -> Option<Self::Item> {
match self.i < self.fragment.len() {
true => {
let element = unsafe { self.fragment.get_unchecked(self.i) };
self.i += 1;
Some(element)
}
false => None,
}
}
}
2 changes: 2 additions & 0 deletions src/common_traits/iterator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ mod eq;
mod from_iter;
pub(crate) mod into_iter;
pub(crate) mod iter;
pub(crate) mod iter_con;
mod iter_fragment;
pub(crate) mod iter_mut;
pub(crate) mod iter_mut_rev;
pub(crate) mod iter_rev;
Expand Down
Loading

0 comments on commit 0b0359a

Please sign in to comment.