orx_concurrent_vec/exclusive.rs
1use crate::{ConcurrentVec, elem::ConcurrentElement};
2use core::sync::atomic::Ordering;
3use orx_pinned_vec::IntoConcurrentPinnedVec;
4
5impl<T, P> ConcurrentVec<T, P>
6where
7 P: IntoConcurrentPinnedVec<ConcurrentElement<T>>,
8{
9 /// Clears the concurrent bag.
10 pub fn clear(&mut self) {
11 unsafe { self.core.clear(self.core.state().len()) };
12 }
13
14 /// Removes the last element from the vector and returns it, or `None` if it is empty.
15 ///
16 /// # Examples
17 ///
18 /// ```rust
19 /// use orx_concurrent_vec::*;
20 ///
21 /// let mut vec = ConcurrentVec::new();
22 /// vec.push('a');
23 /// vec.push('b');
24 ///
25 /// assert_eq!(vec.pop(), Some('b'));
26 /// assert_eq!(vec.pop(), Some('a'));
27 /// assert_eq!(vec.pop(), None);
28 /// ```
29 pub fn pop(&mut self) -> Option<T> {
30 let len = self.len();
31 match len {
32 0 => None,
33 n => {
34 let last_idx = n - 1;
35 // SAFETY: the element exists and we have &mut reference to vec
36 let elem = unsafe { self.core.get_mut(last_idx) }?;
37 let value = elem.0.exclusive_take();
38
39 self.len_written().store(last_idx, Ordering::Relaxed);
40 self.len_reserved().store(last_idx, Ordering::Relaxed);
41
42 value
43 }
44 }
45 }
46
47 /// Note that [`ConcurrentVec::maximum_capacity`] returns the maximum possible number of elements that the underlying pinned vector can grow to without reserving maximum capacity.
48 ///
49 /// In other words, the pinned vector can automatically grow up to the [`ConcurrentVec::maximum_capacity`] with `write` and `write_n_items` methods, using only a shared reference.
50 ///
51 /// When required, this maximum capacity can be attempted to increase by this method with a mutable reference.
52 ///
53 /// Importantly note that maximum capacity does not correspond to the allocated memory.
54 ///
55 /// Among the common pinned vector implementations:
56 /// * `SplitVec<_, Doubling>`: supports this method; however, it does not require for any practical size.
57 /// * `SplitVec<_, Linear>`: is guaranteed to succeed and increase its maximum capacity to the required value.
58 /// * `FixedVec<_>`: is the most strict pinned vector which cannot grow even in a single-threaded setting. Currently, it will always return an error to this call.
59 ///
60 /// # Safety
61 /// This method is unsafe since the concurrent pinned vector might contain gaps. The vector must be gap-free while increasing the maximum capacity.
62 ///
63 /// This method can safely be called if entries in all positions 0..len are written.
64 pub fn reserve_maximum_capacity(&mut self, new_maximum_capacity: usize) -> usize {
65 unsafe {
66 self.core
67 .reserve_maximum_capacity(self.core.state().len(), new_maximum_capacity)
68 }
69 }
70}