From f8f870cf9f200ffaf6c2c37a4a5daf597bea8e41 Mon Sep 17 00:00:00 2001 From: "Ugur Arikan (DHL Data & Analytics)" Date: Mon, 12 Aug 2024 08:11:12 +0200 Subject: [PATCH] fill-with variants to initialize memory on growth `into_concurrent_filled_with` and `grow_to_and_fill_with` methods are required to enable data structures which always have an initialized and valid state. --- Cargo.toml | 4 ++-- src/concurrent_pinned_vec.rs | 27 +++++++++++++++++++++++++++ src/into_concurrent_pinned_vec.rs | 10 ++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3214864..309f6ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "orx-pinned-vec" -version = "3.2.0" +version = "3.3.0" edition = "2021" authors = ["orxfun "] description = "`PinnedVec` trait defines the interface for vectors which guarantee that elements added to the vector are pinned to their memory locations unless explicitly changed." @@ -10,4 +10,4 @@ keywords = ["vec", "array", "vector", "pinned", "memory"] categories = ["data-structures", "rust-patterns"] [dependencies] -orx-pseudo-default = "1.2.0" +orx-pseudo-default = "1.2" diff --git a/src/concurrent_pinned_vec.rs b/src/concurrent_pinned_vec.rs index c411a87..617381c 100644 --- a/src/concurrent_pinned_vec.rs +++ b/src/concurrent_pinned_vec.rs @@ -65,6 +65,9 @@ pub trait ConcurrentPinnedVec { range: R, ) -> >::SliceMutIter<'_>; + /// Returns an iterator of slices to the elements extending over positions `range` of the vector. + fn slices>(&self, range: R) -> >::SliceIter<'_>; + // capacity /// Returns the maximum possible capacity that the vector can concurrently grow to without requiring a `&mut self` reference. @@ -86,6 +89,30 @@ pub trait ConcurrentPinnedVec { /// Then, `grow_to` will succeed. fn grow_to(&self, new_capacity: usize) -> Result; + /// Tries to concurrently grow the capacity of the vector to at least `new_capacity`. Returns: + /// * Ok of the new capacity if succeeds + /// * Err otherwise. + /// + /// Behavior of this method is deterministic. + /// The method always succeeds (fails) if `new_capacity <= self.max_capacity()` (otherwise). + /// + /// If the method returns an error, `reserve_maximum_concurrent_capacity` method can be used; + /// however, with a `&mut self` reference. + /// Then, `grow_to` will succeed. + /// + /// During growth: + /// + /// * length of the vector is increased to its new capacity; + /// * the elements in the range `len..capacity` are filled with the values + /// obtained by repeatedly calling the function `fill_with`. + fn grow_to_and_fill_with( + &self, + new_capacity: usize, + fill_with: F, + ) -> Result + where + F: Fn() -> T; + /// Increases the `maximum_capacity` to the `new_maximum_capacity`. /// /// # Safety diff --git a/src/into_concurrent_pinned_vec.rs b/src/into_concurrent_pinned_vec.rs index 1ca93d2..7675917 100644 --- a/src/into_concurrent_pinned_vec.rs +++ b/src/into_concurrent_pinned_vec.rs @@ -7,4 +7,14 @@ pub trait IntoConcurrentPinnedVec: PinnedVec { /// Converts the pinned vector into its concurrent wrapper. fn into_concurrent(self) -> Self::ConPinnedVec; + + /// Converts the pinned vector into its concurrent wrapper. + /// During conversion: + /// + /// * length of the vector is increased to its capacity; + /// * the elements in the range `len..capacity` are filled with the values + /// obtained by repeatedly calling the function `fill_with`. + fn into_concurrent_filled_with(self, fill_with: F) -> Self::ConPinnedVec + where + F: Fn() -> T; }