From 4d5e80c11e011febcd69ef489d00ee63e85be2b2 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 20 Sep 2025 22:32:27 +0200 Subject: [PATCH 01/18] revise con-pin-vec mod --- Cargo.toml | 2 +- .../con_pinvec.rs} | 6 +++++- src/concurrent_pinned_vec/mod.rs | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) rename src/{concurrent_pinned_vec.rs => concurrent_pinned_vec/con_pinvec.rs} (98%) create mode 100644 src/concurrent_pinned_vec/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 5e0dc81..308fa82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["data-structures", "rust-patterns", "no-std"] [dependencies] orx-iterable = { version = "1.3.0", default-features = false } orx-pseudo-default = { version = "2.1.0", default-features = false } -orx-pinned-vec = { version = "3.17.0", default-features = false } +orx-pinned-vec = { path = "../orx-pinned-vec" } orx-concurrent-iter = { version = "3.1.0", default-features = false } [[bench]] diff --git a/src/concurrent_pinned_vec.rs b/src/concurrent_pinned_vec/con_pinvec.rs similarity index 98% rename from src/concurrent_pinned_vec.rs rename to src/concurrent_pinned_vec/con_pinvec.rs index dabd013..c573c97 100644 --- a/src/concurrent_pinned_vec.rs +++ b/src/concurrent_pinned_vec/con_pinvec.rs @@ -4,9 +4,9 @@ use crate::{ fragment::transformations::{fragment_from_raw, fragment_into_raw}, }; use alloc::vec::Vec; -use core::cell::UnsafeCell; use core::ops::RangeBounds; use core::sync::atomic::{AtomicUsize, Ordering}; +use core::{cell::UnsafeCell, ops::Range}; use orx_pinned_vec::ConcurrentPinnedVec; struct FragmentData { @@ -424,4 +424,8 @@ impl ConcurrentPinnedVec for ConcurrentSp self.maximum_capacity = (0..self.data.len()).map(|f| self.capacity_of(f)).sum(); self.pinned_vec_len = 0; } + + unsafe fn ptr_iter_unchecked(&self, range: Range) -> impl Iterator { + core::iter::empty() + } } diff --git a/src/concurrent_pinned_vec/mod.rs b/src/concurrent_pinned_vec/mod.rs new file mode 100644 index 0000000..3b8edc3 --- /dev/null +++ b/src/concurrent_pinned_vec/mod.rs @@ -0,0 +1,3 @@ +mod con_pinvec; + +pub use con_pinvec::ConcurrentSplitVec; From 03d308854e33f7579454714aad3ac9eb19ef044a Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 20 Sep 2025 22:34:05 +0200 Subject: [PATCH 02/18] define SplitIndex --- src/idx.rs | 41 +++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 2 files changed, 42 insertions(+) create mode 100644 src/idx.rs diff --git a/src/idx.rs b/src/idx.rs new file mode 100644 index 0000000..3515c26 --- /dev/null +++ b/src/idx.rs @@ -0,0 +1,41 @@ +use core::cmp::Ordering; + +/// Index of an element in a jagged array. +#[derive(Default, PartialEq, Debug, Clone)] +pub struct SplitIndex { + /// Index of the array containing the element. + pub f: usize, + /// Index of the element within the array containing it. + pub i: usize, +} + +impl From<(usize, usize)> for SplitIndex { + fn from((f, i): (usize, usize)) -> Self { + Self::new(f, i) + } +} + +impl From<[usize; 2]> for SplitIndex { + fn from([f, i]: [usize; 2]) -> Self { + Self::new(f, i) + } +} + +impl SplitIndex { + /// Creates a new jagged index: + /// + /// * `f`: index of the array containing the element. + /// * `i`: index of the element within the array containing it. + pub fn new(f: usize, i: usize) -> Self { + Self { f, i } + } +} + +impl PartialOrd for SplitIndex { + fn partial_cmp(&self, other: &Self) -> Option { + match self.f.partial_cmp(&other.f) { + Some(Ordering::Equal) => self.i.partial_cmp(&other.i), + ord => ord, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 9677f12..982d955 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,7 @@ mod concurrent_iter; mod concurrent_pinned_vec; mod fragment; mod growth; +mod idx; mod into_concurrent_pinned_vec; mod new_split_vec; mod pinned_vec; From faca75ef10e8ddd0dfe6f8fc81243c71b65ae46f Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 20 Sep 2025 22:42:19 +0200 Subject: [PATCH 03/18] impl IterPtrOfConSlices --- src/concurrent_pinned_vec/iter_ptr_slices.rs | 84 ++++++++++++++++++++ src/concurrent_pinned_vec/mod.rs | 1 + src/idx.rs | 3 + 3 files changed, 88 insertions(+) create mode 100644 src/concurrent_pinned_vec/iter_ptr_slices.rs diff --git a/src/concurrent_pinned_vec/iter_ptr_slices.rs b/src/concurrent_pinned_vec/iter_ptr_slices.rs new file mode 100644 index 0000000..428b356 --- /dev/null +++ b/src/concurrent_pinned_vec/iter_ptr_slices.rs @@ -0,0 +1,84 @@ +use crate::GrowthWithConstantTimeAccess; +use core::{cell::UnsafeCell, iter::FusedIterator}; + +pub struct IterPtrOfConSlices<'a, T, G> +where + G: GrowthWithConstantTimeAccess, +{ + fragments: &'a [UnsafeCell<*mut T>], + growth: G, + sf: usize, + si: usize, + si_end: usize, + ef: usize, + ei: usize, + f: usize, +} + +impl<'a, T, G> IterPtrOfConSlices<'a, T, G> +where + G: GrowthWithConstantTimeAccess, +{ + #[inline(always)] + fn remaining_len(&self) -> usize { + (1 + self.ef).saturating_sub(self.f) + } + + #[inline(always)] + fn get_ptr_fi(&self, f: usize, i: usize) -> *mut T { + let p = unsafe { *self.fragments[f].get() }; + unsafe { p.add(i) } + } + + #[inline(always)] + fn capacity_of(&self, f: usize) -> usize { + self.growth.fragment_capacity_of(f) + } +} + +impl<'a, T, G> Iterator for IterPtrOfConSlices<'a, T, G> +where + G: GrowthWithConstantTimeAccess, +{ + type Item = (*mut T, usize); + + fn next(&mut self) -> Option { + match self.f { + f if f == self.sf => { + self.f += 1; + let len = self.si_end - self.si; + let p = self.get_ptr_fi(self.sf, self.si); + Some((p, len)) + } + f if f < self.ef => { + self.f += 1; + let len = self.capacity_of(f); + let p = self.get_ptr_fi(f, 0); + Some((p, len)) + } + f if f == self.ef => { + self.f += 1; + let len = self.ei + 1; + let p = self.get_ptr_fi(self.ef, 0); + Some((p, len)) + } + _ => None, + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.remaining_len(); + (len, Some(len)) + } +} + +impl<'a, T, G> FusedIterator for IterPtrOfConSlices<'a, T, G> where G: GrowthWithConstantTimeAccess {} + +impl<'a, T, G> ExactSizeIterator for IterPtrOfConSlices<'a, T, G> +where + G: GrowthWithConstantTimeAccess, +{ + fn len(&self) -> usize { + self.remaining_len() + } +} diff --git a/src/concurrent_pinned_vec/mod.rs b/src/concurrent_pinned_vec/mod.rs index 3b8edc3..d8af268 100644 --- a/src/concurrent_pinned_vec/mod.rs +++ b/src/concurrent_pinned_vec/mod.rs @@ -1,3 +1,4 @@ mod con_pinvec; +mod iter_ptr_slices; pub use con_pinvec::ConcurrentSplitVec; diff --git a/src/idx.rs b/src/idx.rs index 3515c26..584f411 100644 --- a/src/idx.rs +++ b/src/idx.rs @@ -10,12 +10,14 @@ pub struct SplitIndex { } impl From<(usize, usize)> for SplitIndex { + #[inline(always)] fn from((f, i): (usize, usize)) -> Self { Self::new(f, i) } } impl From<[usize; 2]> for SplitIndex { + #[inline(always)] fn from([f, i]: [usize; 2]) -> Self { Self::new(f, i) } @@ -26,6 +28,7 @@ impl SplitIndex { /// /// * `f`: index of the array containing the element. /// * `i`: index of the element within the array containing it. + #[inline(always)] pub fn new(f: usize, i: usize) -> Self { Self { f, i } } From 7d258868f2224530aa6277889996c1f25ec5f653 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 20 Sep 2025 22:48:21 +0200 Subject: [PATCH 04/18] IterPtrOfCon is implemented --- src/concurrent_pinned_vec/iter_ptr.rs | 85 +++++++++++++++++++++++++++ src/concurrent_pinned_vec/mod.rs | 1 + 2 files changed, 86 insertions(+) create mode 100644 src/concurrent_pinned_vec/iter_ptr.rs diff --git a/src/concurrent_pinned_vec/iter_ptr.rs b/src/concurrent_pinned_vec/iter_ptr.rs new file mode 100644 index 0000000..c144d2c --- /dev/null +++ b/src/concurrent_pinned_vec/iter_ptr.rs @@ -0,0 +1,85 @@ +use crate::{ + GrowthWithConstantTimeAccess, concurrent_pinned_vec::iter_ptr_slices::IterPtrOfConSlices, +}; + +pub struct IterPtrOfCon<'a, T, G> +where + G: GrowthWithConstantTimeAccess, +{ + slices: IterPtrOfConSlices<'a, T, G>, + len_of_remaining_slices: usize, + current_ptr: *const T, + current_last: *const T, +} + +impl<'a, T, G> IterPtrOfCon<'a, T, G> +where + G: GrowthWithConstantTimeAccess, +{ + fn remaining(&self) -> usize { + let remaining_current = match self.current_ptr.is_null() { + true => 0, + // SAFETY: whenever current_ptr is not null, we know that current_last is also not + // null which is >= current_ptr. + false => unsafe { self.current_last.offset_from(self.current_ptr) as usize + 1 }, + }; + + self.len_of_remaining_slices + remaining_current + } + + fn next_slice(&mut self) -> Option<*mut T> { + match self.slices.next() { + Some((ptr, len)) => { + debug_assert!(len > 0); + self.len_of_remaining_slices -= len; + // SAFETY: pointers are not null since slice is not empty + self.current_ptr = ptr; + self.current_last = unsafe { ptr.add(len - 1) }; + self.next() + } + None => None, + } + } +} + +impl<'a, T, G> Iterator for IterPtrOfCon<'a, T, G> +where + G: GrowthWithConstantTimeAccess, +{ + type Item = *mut T; + + fn next(&mut self) -> Option { + match self.current_ptr.is_null() { + false => { + let is_last_of_slice = self.current_ptr == self.current_last; + + let ptr = self.current_ptr as *mut T; + + self.current_ptr = match is_last_of_slice { + // SAFETY: current_ptr is not the last element, hance current_ptr+1 is in bounds + false => unsafe { self.current_ptr.add(1) }, + true => core::ptr::null_mut(), + }; + + // SAFETY: ptr is valid and its value can be taken. + // Drop will skip this position which is now uninitialized. + Some(ptr) + } + true => self.next_slice(), + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.remaining(); + (len, Some(len)) + } +} + +impl<'a, T, G> ExactSizeIterator for IterPtrOfCon<'a, T, G> +where + G: GrowthWithConstantTimeAccess, +{ + fn len(&self) -> usize { + self.remaining() + } +} diff --git a/src/concurrent_pinned_vec/mod.rs b/src/concurrent_pinned_vec/mod.rs index d8af268..134f191 100644 --- a/src/concurrent_pinned_vec/mod.rs +++ b/src/concurrent_pinned_vec/mod.rs @@ -1,4 +1,5 @@ mod con_pinvec; +mod iter_ptr; mod iter_ptr_slices; pub use con_pinvec::ConcurrentSplitVec; From 715c29e60f78afbc94e706660cb37182e6c7c02b Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 20 Sep 2025 22:55:25 +0200 Subject: [PATCH 05/18] impl IterPtrOfCon --- src/concurrent_pinned_vec/iter_ptr.rs | 17 +++++ src/concurrent_pinned_vec/iter_ptr_slices.rs | 77 +++++++++++++++++++- 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/concurrent_pinned_vec/iter_ptr.rs b/src/concurrent_pinned_vec/iter_ptr.rs index c144d2c..73d96f9 100644 --- a/src/concurrent_pinned_vec/iter_ptr.rs +++ b/src/concurrent_pinned_vec/iter_ptr.rs @@ -1,6 +1,7 @@ use crate::{ GrowthWithConstantTimeAccess, concurrent_pinned_vec::iter_ptr_slices::IterPtrOfConSlices, }; +use core::{cell::UnsafeCell, ops::Range}; pub struct IterPtrOfCon<'a, T, G> where @@ -16,6 +17,22 @@ impl<'a, T, G> IterPtrOfCon<'a, T, G> where G: GrowthWithConstantTimeAccess, { + pub fn new( + capacity: usize, + fragments: &'a [UnsafeCell<*mut T>], + growth: G, + range: Range, + ) -> Self { + let len_of_remaining_slices = range.len(); + let slices = IterPtrOfConSlices::new(capacity, fragments, growth, range); + Self { + slices, + len_of_remaining_slices, + current_ptr: core::ptr::null(), + current_last: core::ptr::null(), + } + } + fn remaining(&self) -> usize { let remaining_current = match self.current_ptr.is_null() { true => 0, diff --git a/src/concurrent_pinned_vec/iter_ptr_slices.rs b/src/concurrent_pinned_vec/iter_ptr_slices.rs index 428b356..f956bc4 100644 --- a/src/concurrent_pinned_vec/iter_ptr_slices.rs +++ b/src/concurrent_pinned_vec/iter_ptr_slices.rs @@ -1,5 +1,9 @@ -use crate::GrowthWithConstantTimeAccess; -use core::{cell::UnsafeCell, iter::FusedIterator}; +use crate::{ + GrowthWithConstantTimeAccess, + range_helpers::{range_end, range_start}, +}; +use core::cmp::min; +use core::{cell::UnsafeCell, iter::FusedIterator, ops::Range}; pub struct IterPtrOfConSlices<'a, T, G> where @@ -19,6 +23,75 @@ impl<'a, T, G> IterPtrOfConSlices<'a, T, G> where G: GrowthWithConstantTimeAccess, { + fn empty() -> Self { + Self { + fragments: &[], + growth: G::pseudo_default(), + sf: 0, + si: 0, + si_end: 0, + ef: 0, + ei: 0, + f: 1, + } + } + + fn single_slice( + fragments: &'a [UnsafeCell<*mut T>], + growth: G, + f: usize, + begin: usize, + end: usize, + ) -> Self { + Self { + fragments, + growth, + sf: f, + si: begin, + si_end: end, + ef: f, + ei: 0, + f, + } + } + + pub fn new( + capacity: usize, + fragments: &'a [UnsafeCell<*mut T>], + growth: G, + range: Range, + ) -> Self { + let fragment_and_inner_indices = |i| growth.get_fragment_and_inner_indices_unchecked(i); + + let a = range_start(&range); + let b = min(capacity, range_end(&range, capacity)); + + match b.saturating_sub(a) { + 0 => Self::empty(), + _ => { + let (sf, si) = fragment_and_inner_indices(a); + let (ef, ei) = fragment_and_inner_indices(b - 1); + + match sf == ef { + true => Self::single_slice(fragments, growth, sf, si, ei + 1), + false => { + let si_end = growth.fragment_capacity_of(sf); + Self { + fragments, + growth, + sf, + si, + si_end, + ef, + ei, + f: sf, + } + } + } + } + } + } + #[inline(always)] fn remaining_len(&self) -> usize { (1 + self.ef).saturating_sub(self.f) From f487995a0e93967cb5561ca4a733c1d82346f7bc Mon Sep 17 00:00:00 2001 From: orxfun Date: Sat, 20 Sep 2025 22:57:09 +0200 Subject: [PATCH 06/18] impl ptr_iter_unchecked --- src/concurrent_pinned_vec/con_pinvec.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/concurrent_pinned_vec/con_pinvec.rs b/src/concurrent_pinned_vec/con_pinvec.rs index c573c97..2d7fb60 100644 --- a/src/concurrent_pinned_vec/con_pinvec.rs +++ b/src/concurrent_pinned_vec/con_pinvec.rs @@ -1,6 +1,7 @@ use crate::{ Doubling, Fragment, GrowthWithConstantTimeAccess, SplitVec, common_traits::iterator::{IterOfSlicesOfCon, SliceBorrowAsMut, SliceBorrowAsRef}, + concurrent_pinned_vec::iter_ptr::IterPtrOfCon, fragment::transformations::{fragment_from_raw, fragment_into_raw}, }; use alloc::vec::Vec; @@ -426,6 +427,6 @@ impl ConcurrentPinnedVec for ConcurrentSp } unsafe fn ptr_iter_unchecked(&self, range: Range) -> impl Iterator { - core::iter::empty() + IterPtrOfCon::new(self.capacity(), &self.data, self.growth.clone(), range) } } From bc03e71ac00a68cc5e8487211e6509bea2616707 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sun, 21 Sep 2025 15:58:08 +0200 Subject: [PATCH 07/18] ptr_iter_unchecked returns exact size iterator --- src/concurrent_pinned_vec/con_pinvec.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/concurrent_pinned_vec/con_pinvec.rs b/src/concurrent_pinned_vec/con_pinvec.rs index 2d7fb60..b8d8d25 100644 --- a/src/concurrent_pinned_vec/con_pinvec.rs +++ b/src/concurrent_pinned_vec/con_pinvec.rs @@ -426,7 +426,10 @@ impl ConcurrentPinnedVec for ConcurrentSp self.pinned_vec_len = 0; } - unsafe fn ptr_iter_unchecked(&self, range: Range) -> impl Iterator { + unsafe fn ptr_iter_unchecked( + &self, + range: Range, + ) -> impl ExactSizeIterator { IterPtrOfCon::new(self.capacity(), &self.data, self.growth.clone(), range) } } From 7ed000ed1a49d5947b485edaafdd6078dec511b9 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sun, 21 Sep 2025 20:07:19 +0200 Subject: [PATCH 08/18] update pinned vec dependency --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 308fa82..c6ec23f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["data-structures", "rust-patterns", "no-std"] [dependencies] orx-iterable = { version = "1.3.0", default-features = false } orx-pseudo-default = { version = "2.1.0", default-features = false } -orx-pinned-vec = { path = "../orx-pinned-vec" } +orx-pinned-vec = { git = "https://github.com/orxfun/orx-pinned-vec/", branch = "concurrent-queue-support" } orx-concurrent-iter = { version = "3.1.0", default-features = false } [[bench]] @@ -24,4 +24,4 @@ criterion = "0.7.0" rand = { version = "0.9.2", default-features = false } rand_chacha = { version = "0.9", default-features = false } test-case = "3.3.1" -orx-concurrent-bag = "3.0.0" +orx-concurrent-bag = "3.1.0" From 4314608b3e5cf6a783e07b29f0f18d4e4ad27664 Mon Sep 17 00:00:00 2001 From: orxfun Date: Sun, 21 Sep 2025 20:08:31 +0200 Subject: [PATCH 09/18] clean up --- src/idx.rs | 44 -------------------------------------------- src/lib.rs | 1 - 2 files changed, 45 deletions(-) delete mode 100644 src/idx.rs diff --git a/src/idx.rs b/src/idx.rs deleted file mode 100644 index 584f411..0000000 --- a/src/idx.rs +++ /dev/null @@ -1,44 +0,0 @@ -use core::cmp::Ordering; - -/// Index of an element in a jagged array. -#[derive(Default, PartialEq, Debug, Clone)] -pub struct SplitIndex { - /// Index of the array containing the element. - pub f: usize, - /// Index of the element within the array containing it. - pub i: usize, -} - -impl From<(usize, usize)> for SplitIndex { - #[inline(always)] - fn from((f, i): (usize, usize)) -> Self { - Self::new(f, i) - } -} - -impl From<[usize; 2]> for SplitIndex { - #[inline(always)] - fn from([f, i]: [usize; 2]) -> Self { - Self::new(f, i) - } -} - -impl SplitIndex { - /// Creates a new jagged index: - /// - /// * `f`: index of the array containing the element. - /// * `i`: index of the element within the array containing it. - #[inline(always)] - pub fn new(f: usize, i: usize) -> Self { - Self { f, i } - } -} - -impl PartialOrd for SplitIndex { - fn partial_cmp(&self, other: &Self) -> Option { - match self.f.partial_cmp(&other.f) { - Some(Ordering::Equal) => self.i.partial_cmp(&other.i), - ord => ord, - } - } -} diff --git a/src/lib.rs b/src/lib.rs index 982d955..9677f12 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,6 @@ mod concurrent_iter; mod concurrent_pinned_vec; mod fragment; mod growth; -mod idx; mod into_concurrent_pinned_vec; mod new_split_vec; mod pinned_vec; From 90bfbad76161f66026640b70e183a89537675ab3 Mon Sep 17 00:00:00 2001 From: orxfun Date: Thu, 25 Sep 2025 10:21:52 +0200 Subject: [PATCH 10/18] map --- src/concurrent_pinned_vec/iter_ptr.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/concurrent_pinned_vec/iter_ptr.rs b/src/concurrent_pinned_vec/iter_ptr.rs index 73d96f9..42989d3 100644 --- a/src/concurrent_pinned_vec/iter_ptr.rs +++ b/src/concurrent_pinned_vec/iter_ptr.rs @@ -45,17 +45,14 @@ where } fn next_slice(&mut self) -> Option<*mut T> { - match self.slices.next() { - Some((ptr, len)) => { - debug_assert!(len > 0); - self.len_of_remaining_slices -= len; - // SAFETY: pointers are not null since slice is not empty - self.current_ptr = ptr; - self.current_last = unsafe { ptr.add(len - 1) }; - self.next() - } - None => None, - } + self.slices.next().and_then(|(ptr, len)| { + debug_assert!(len > 0); + self.len_of_remaining_slices -= len; + // SAFETY: pointers are not null since slice is not empty + self.current_ptr = ptr; + self.current_last = unsafe { ptr.add(len - 1) }; + self.next() + }) } } From 16115571728c994ddb4af31a716a390a67dc5047 Mon Sep 17 00:00:00 2001 From: orxfun Date: Thu, 25 Sep 2025 10:27:11 +0200 Subject: [PATCH 11/18] minor refactoring in IterPtrOfCon next implementation --- src/concurrent_pinned_vec/iter_ptr.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/concurrent_pinned_vec/iter_ptr.rs b/src/concurrent_pinned_vec/iter_ptr.rs index 42989d3..eb84fb3 100644 --- a/src/concurrent_pinned_vec/iter_ptr.rs +++ b/src/concurrent_pinned_vec/iter_ptr.rs @@ -63,23 +63,20 @@ where type Item = *mut T; fn next(&mut self) -> Option { - match self.current_ptr.is_null() { - false => { - let is_last_of_slice = self.current_ptr == self.current_last; - - let ptr = self.current_ptr as *mut T; - - self.current_ptr = match is_last_of_slice { - // SAFETY: current_ptr is not the last element, hance current_ptr+1 is in bounds - false => unsafe { self.current_ptr.add(1) }, - true => core::ptr::null_mut(), - }; + match self.current_ptr { + ptr if ptr.is_null() => self.next_slice(), + ptr if ptr == self.current_last => { + self.current_ptr = core::ptr::null_mut(); + Some(ptr as *mut T) + } + ptr => { + // SAFETY: current_ptr is not the last element, hance current_ptr+1 is in bounds + self.current_ptr = unsafe { self.current_ptr.add(1) }; // SAFETY: ptr is valid and its value can be taken. // Drop will skip this position which is now uninitialized. - Some(ptr) + Some(ptr as *mut T) } - true => self.next_slice(), } } From 400813846775f8fcce6eba45ca90e21bf45bf481 Mon Sep 17 00:00:00 2001 From: orxfun Date: Fri, 26 Sep 2025 10:57:01 +0200 Subject: [PATCH 12/18] ptr iter type is made explicit --- src/concurrent_pinned_vec/con_pinvec.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/concurrent_pinned_vec/con_pinvec.rs b/src/concurrent_pinned_vec/con_pinvec.rs index b8d8d25..4e31272 100644 --- a/src/concurrent_pinned_vec/con_pinvec.rs +++ b/src/concurrent_pinned_vec/con_pinvec.rs @@ -190,6 +190,11 @@ impl ConcurrentPinnedVec for ConcurrentSp where Self: 'a; + type PtrIter<'a> + = IterPtrOfCon<'a, T, G> + where + Self: 'a; + unsafe fn into_inner(mut self, len: usize) -> Self::P { let mut fragments = Vec::with_capacity(self.max_num_fragments); let mut take_fragment = |fragment| fragments.push(fragment); @@ -426,10 +431,7 @@ impl ConcurrentPinnedVec for ConcurrentSp self.pinned_vec_len = 0; } - unsafe fn ptr_iter_unchecked( - &self, - range: Range, - ) -> impl ExactSizeIterator { + unsafe fn ptr_iter_unchecked(&self, range: Range) -> Self::PtrIter<'_> { IterPtrOfCon::new(self.capacity(), &self.data, self.growth.clone(), range) } } From 45bbc65ae55c5b0ceed68121c124f4f85eeac733 Mon Sep 17 00:00:00 2001 From: orxfun Date: Fri, 26 Sep 2025 13:50:21 +0200 Subject: [PATCH 13/18] do not re-export pseudo default --- README.md | 1 + src/lib.rs | 1 - src/new_split_vec/new.rs | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f57dd2..8968814 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,7 @@ Naturally, it has certain specific differences and operations. For instance, we ```rust use orx_split_vec::*; +use orx_pseudo_default::PseudoDefault; #[derive(Clone)] struct MyCustomGrowth; diff --git a/src/lib.rs b/src/lib.rs index 9677f12..51fd295 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,5 @@ pub use orx_iterable::{Collection, CollectionMut, Iterable}; pub use orx_pinned_vec::{ ConcurrentPinnedVec, IntoConcurrentPinnedVec, PinnedVec, PinnedVecGrowthError, }; -pub use orx_pseudo_default::PseudoDefault; pub use slice::SplitVecSlice; pub use split_vec::SplitVec; diff --git a/src/new_split_vec/new.rs b/src/new_split_vec/new.rs index f64a780..6360f37 100644 --- a/src/new_split_vec/new.rs +++ b/src/new_split_vec/new.rs @@ -32,6 +32,7 @@ where /// /// ``` /// use orx_split_vec::*; + /// use orx_pseudo_default::PseudoDefault; /// /// #[derive(Clone)] /// pub struct DoubleEverySecondFragment(usize); // any custom growth strategy From 5a5d4db3641a80c378fabbe937cdcc89a9f90e88 Mon Sep 17 00:00:00 2001 From: orxfun Date: Fri, 26 Sep 2025 19:06:01 +0200 Subject: [PATCH 14/18] increment version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c6ec23f..1e22215 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "orx-split-vec" -version = "3.19.0" +version = "3.20.0" edition = "2024" authors = ["orxfun "] description = "An efficient dynamic capacity vector with pinned element guarantees." From ec1c73684b807009518ace64ba6201f0dacf17ff Mon Sep 17 00:00:00 2001 From: Ugur Arikan Date: Fri, 26 Sep 2025 19:21:00 +0200 Subject: [PATCH 15/18] Update ci.yml --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e6be86..3406a39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,13 +18,15 @@ jobs: toolchain: ["stable"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Install toolchain - uses: dtolnay/rust-toolchain@master + uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ matrix.toolchain }} + - name: Install clippy + run: rustup component add clippy - name: Install 32bit target run: rustup target add i686-unknown-linux-musl - name: Install wasm target From a547449580cc6d22bbb3fd83f51d34981a9046e6 Mon Sep 17 00:00:00 2001 From: orxfun Date: Fri, 26 Sep 2025 19:22:33 +0200 Subject: [PATCH 16/18] upgrade pinned vec dep --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1e22215..d8aa19b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["data-structures", "rust-patterns", "no-std"] [dependencies] orx-iterable = { version = "1.3.0", default-features = false } orx-pseudo-default = { version = "2.1.0", default-features = false } -orx-pinned-vec = { git = "https://github.com/orxfun/orx-pinned-vec/", branch = "concurrent-queue-support" } +orx-pinned-vec = { version = "3.18.0", default-features = false } orx-concurrent-iter = { version = "3.1.0", default-features = false } [[bench]] From 98dab7f640c20a0a9947625881ab91fb7e5c6c93 Mon Sep 17 00:00:00 2001 From: orxfun Date: Fri, 26 Sep 2025 19:38:09 +0200 Subject: [PATCH 17/18] temp fix --- Cargo.toml | 2 +- src/concurrent_iter/tests/con_iter_owned/mod.rs | 4 ++-- src/concurrent_iter/tests/con_iter_ref/mod.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d8aa19b..a5b628c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,4 +24,4 @@ criterion = "0.7.0" rand = { version = "0.9.2", default-features = false } rand_chacha = { version = "0.9", default-features = false } test-case = "3.3.1" -orx-concurrent-bag = "3.1.0" +# orx-concurrent-bag = "3.1.0" diff --git a/src/concurrent_iter/tests/con_iter_owned/mod.rs b/src/concurrent_iter/tests/con_iter_owned/mod.rs index bc15087..cd80447 100644 --- a/src/concurrent_iter/tests/con_iter_owned/mod.rs +++ b/src/concurrent_iter/tests/con_iter_owned/mod.rs @@ -1,4 +1,4 @@ -mod con_iter; -mod into; +// mod con_iter; +// mod into; mod par; mod transformations; diff --git a/src/concurrent_iter/tests/con_iter_ref/mod.rs b/src/concurrent_iter/tests/con_iter_ref/mod.rs index bc15087..cd80447 100644 --- a/src/concurrent_iter/tests/con_iter_ref/mod.rs +++ b/src/concurrent_iter/tests/con_iter_ref/mod.rs @@ -1,4 +1,4 @@ -mod con_iter; -mod into; +// mod con_iter; +// mod into; mod par; mod transformations; From b7d92a43499f0f699715c42c68a59f69bc356a6d Mon Sep 17 00:00:00 2001 From: orxfun Date: Fri, 26 Sep 2025 19:42:05 +0200 Subject: [PATCH 18/18] pseudo default back into default exports --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 51fd295..9677f12 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,5 +53,6 @@ pub use orx_iterable::{Collection, CollectionMut, Iterable}; pub use orx_pinned_vec::{ ConcurrentPinnedVec, IntoConcurrentPinnedVec, PinnedVec, PinnedVecGrowthError, }; +pub use orx_pseudo_default::PseudoDefault; pub use slice::SplitVecSlice; pub use split_vec::SplitVec;