lockfree_object_pool/linear_reusable.rs
1use crate::linear_object_pool::LinearObjectPool;
2use crate::page::{Page, PageId};
3use std::ops::{Deref, DerefMut};
4
5/// Wrapper over T used by [`LinearObjectPool`].
6///
7/// Access is allowed with [`std::ops::Deref`] or [`std::ops::DerefMut`]
8/// # Example
9/// ```rust
10/// use lockfree_object_pool::LinearObjectPool;
11///
12/// let pool = LinearObjectPool::<u32>::new(
13/// || Default::default(),
14/// |v| {
15/// *v = 0;
16/// }
17/// );
18/// let mut item = pool.pull();
19///
20/// *item = 5;
21/// let work = *item * 5;
22/// ```
23pub struct LinearReusable<'a, T> {
24 pool: &'a LinearObjectPool<T>,
25 page_id: PageId,
26 page: &'a Page<T>,
27}
28
29impl<'a, T> LinearReusable<'a, T> {
30 /// Create new element
31 ///
32 /// # Arguments
33 /// * `pool` object pool owner
34 /// * `page_id` page id
35 /// * `page` page that contains data
36 /// # Safety
37 /// * `page` has to be a valid pointer to a page in `pool`
38 /// * `pool_id` has to be a valid id for `page`
39 #[inline]
40 pub(crate) unsafe fn new(
41 pool: &'a LinearObjectPool<T>,
42 page_id: PageId,
43 page: &'a Page<T>,
44 ) -> Self {
45 Self {
46 pool,
47 page_id,
48 page,
49 }
50 }
51}
52
53impl<'a, T> DerefMut for LinearReusable<'a, T> {
54 #[inline]
55 fn deref_mut(&mut self) -> &mut Self::Target {
56 unsafe {
57 // SAFETY: there exists only this `LinearReusable` with this page_id
58 self.page.get_mut(&self.page_id)
59 }
60 }
61}
62
63impl<'a, T> Deref for LinearReusable<'a, T> {
64 type Target = T;
65
66 #[inline]
67 fn deref(&self) -> &Self::Target {
68 unsafe {
69 // SAFETY: there exists only this `LinearReusable` with this page_id
70 self.page.get(&self.page_id)
71 }
72 }
73}
74
75impl<'a, T> Drop for LinearReusable<'a, T> {
76 #[inline]
77 fn drop(&mut self) {
78 let page = self.page;
79 (self.pool.get_reset_callback())(unsafe {
80 // SAFETY: there exists only this `LinearReusable` with this page_id
81 page.get_mut(&self.page_id)
82 });
83 page.free(&self.page_id);
84 }
85}