1use crate::node::Node;
2use crate::{CoreCol, MemoryPolicy, MemoryState, NodeIdx, NodeIdxError, NodePtr, Variant};
3use core::ops::{Deref, DerefMut};
4use orx_pinned_vec::PinnedVec;
5
6pub struct SelfRefCol<V, M, P>
8where
9 V: Variant,
10 M: MemoryPolicy<V>,
11 P: PinnedVec<Node<V>>,
12{
13 core: CoreCol<V, P>,
14 policy: M,
15 state: MemoryState,
16}
17
18impl<V, M, P> Default for SelfRefCol<V, M, P>
19where
20 V: Variant,
21 M: MemoryPolicy<V>,
22 P: PinnedVec<Node<V>> + Default,
23{
24 fn default() -> Self {
25 Self::new()
26 }
27}
28
29impl<V, M, P> Deref for SelfRefCol<V, M, P>
30where
31 V: Variant,
32 M: MemoryPolicy<V>,
33 P: PinnedVec<Node<V>>,
34{
35 type Target = CoreCol<V, P>;
36
37 fn deref(&self) -> &Self::Target {
38 &self.core
39 }
40}
41
42impl<V, M, P> DerefMut for SelfRefCol<V, M, P>
43where
44 V: Variant,
45 M: MemoryPolicy<V>,
46 P: PinnedVec<Node<V>>,
47{
48 fn deref_mut(&mut self) -> &mut Self::Target {
49 &mut self.core
50 }
51}
52
53impl<V, M, P> SelfRefCol<V, M, P>
54where
55 V: Variant,
56 M: MemoryPolicy<V>,
57 P: PinnedVec<Node<V>>,
58{
59 pub fn new() -> Self
61 where
62 P: Default,
63 {
64 Self {
65 core: CoreCol::new(),
66 policy: M::default(),
67 state: MemoryState::default(),
68 }
69 }
70
71 pub fn into_inner(self) -> (CoreCol<V, P>, MemoryState) {
73 let state = self.memory_state();
74 (self.core, state)
75 }
76
77 pub(crate) fn from_raw_parts(core: CoreCol<V, P>, policy: M, state: MemoryState) -> Self {
78 Self {
79 core,
80 policy,
81 state,
82 }
83 }
84
85 pub(crate) fn with_active_nodes(nodes: P) -> Self {
86 Self {
87 core: CoreCol::with_active_nodes(nodes),
88 policy: M::default(),
89 state: MemoryState::default(),
90 }
91 }
92
93 pub fn memory_state(&self) -> MemoryState {
97 self.state
98 }
99
100 pub fn memory(&self) -> &M {
102 &self.policy
103 }
104
105 pub fn close_and_reclaim(&mut self, node_ptr: NodePtr<V>) -> V::Item {
108 let data = self.core.close(node_ptr);
109
110 let state_changed = M::reclaim_closed_nodes(self, node_ptr);
111 self.update_state(state_changed);
112
113 data
114 }
115
116 pub fn reclaim_from_closed_node(&mut self, node_ptr: NodePtr<V>) -> bool {
121 let state_changed = M::reclaim_closed_nodes(self, node_ptr);
122 self.update_state(state_changed);
123 state_changed
124 }
125
126 #[inline(always)]
128 pub fn update_state(&mut self, state_changed: bool) {
129 if state_changed {
130 self.state = self.state.successor_state();
131 }
132 }
133
134 #[inline(always)]
137 pub fn node_from_idx(&self, idx: NodeIdx<V>) -> Option<&Node<V>> {
138 match idx.is_in_state(self.state) && self.nodes().contains_ptr(unsafe { idx.ptr() }) {
140 true => Some(unsafe { &*idx.ptr() }),
142 false => None,
143 }
144 }
145
146 #[inline(always)]
149 pub fn try_node_from_idx(&self, idx: NodeIdx<V>) -> Result<&Node<V>, NodeIdxError> {
150 match self.nodes().contains_ptr(unsafe { idx.ptr() }) {
152 true => match idx.is_in_state(self.state) {
153 true => Ok(unsafe { &*idx.ptr() }),
155 false => Err(NodeIdxError::ReorganizedCollection),
156 },
157 false => Err(NodeIdxError::OutOfBounds),
158 }
159 }
160
161 #[inline(always)]
164 pub fn node_idx_error(&self, idx: NodeIdx<V>) -> Option<NodeIdxError> {
165 match self.try_node_from_idx(idx) {
166 Ok(node) => match node.is_active() {
167 true => None,
168 false => Some(NodeIdxError::RemovedNode),
169 },
170 Err(err) => Some(err),
171 }
172 }
173
174 #[inline(always)]
177 pub fn try_get_ptr(&self, idx: NodeIdx<V>) -> Result<NodePtr<V>, NodeIdxError> {
178 match self.nodes().contains_ptr(unsafe { idx.ptr() }) {
180 true => match idx.is_in_state(self.state) {
181 true => {
182 let ptr = unsafe { idx.ptr() };
184 match unsafe { &*ptr }.is_active() {
185 true => Ok(NodePtr::new(ptr)),
186 false => Err(NodeIdxError::RemovedNode),
187 }
188 }
189 false => Err(NodeIdxError::ReorganizedCollection),
190 },
191 false => Err(NodeIdxError::OutOfBounds),
192 }
193 }
194
195 #[inline(always)]
198 pub fn get_ptr(&self, idx: NodeIdx<V>) -> Option<NodePtr<V>> {
199 match self.nodes().contains_ptr(unsafe { idx.ptr() }) {
201 true => match idx.is_in_state(self.state) {
202 true => {
203 let ptr = unsafe { idx.ptr() };
205 match unsafe { &*ptr }.is_active() {
206 true => Some(NodePtr::new(ptr)),
207 false => None,
208 }
209 }
210 false => None,
211 },
212 false => None,
213 }
214 }
215
216 pub fn clear(&mut self) {
220 self.core.clear_core();
221 self.state = self.state.successor_state();
222 }
223
224 #[inline(always)]
227 pub fn node_mut_from_idx(&mut self, idx: NodeIdx<V>) -> Option<&mut Node<V>> {
228 match idx.is_in_state(self.state) && self.nodes().contains_ptr(unsafe { idx.ptr() }) {
230 true => Some(unsafe { &mut *idx.ptr_mut() }),
231 false => None,
232 }
233 }
234
235 #[inline(always)]
238 pub fn try_node_mut_from_idx(&mut self, idx: NodeIdx<V>) -> Result<&mut Node<V>, NodeIdxError> {
239 match self.nodes().contains_ptr(unsafe { idx.ptr() }) {
241 true => match idx.is_in_state(self.state) {
242 true => Ok(unsafe { &mut *idx.ptr_mut() }),
243 false => Err(NodeIdxError::ReorganizedCollection),
244 },
245 false => Err(NodeIdxError::OutOfBounds),
246 }
247 }
248
249 pub fn push_get_idx(&mut self, data: V::Item) -> NodeIdx<V> {
251 let node_ptr = self.push(data);
252 NodeIdx::new(self.memory_state(), node_ptr)
253 }
254}