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}