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