1use std::{fmt, mem, ops::Deref};
2
3use crate::{
4 EbrGuard,
5 config::Config,
6 key::Key,
7 page::{self, Page},
8 slot::Slot,
9};
10
11#[must_use]
21pub struct VacantEntry<'s, T: 'static, C: Config> {
22 page: &'s Page<T, C>,
23 slot: &'s Slot<T, C>,
24 key: Key,
25}
26
27impl<'s, T: 'static, C: Config> VacantEntry<'s, T, C> {
28 pub(crate) fn new(page: &'s Page<T, C>, slot: &'s Slot<T, C>, key: Key) -> Self {
29 Self { page, slot, key }
30 }
31
32 #[must_use]
36 #[inline]
37 pub fn key(&self) -> Key {
38 self.key
39 }
40
41 #[inline]
48 pub fn insert(self, value: T) {
49 self.slot.init(value);
50 mem::forget(self);
51 }
52}
53
54impl<T: 'static, C: Config> Drop for VacantEntry<'_, T, C> {
55 #[inline]
56 fn drop(&mut self) {
57 unsafe { self.page.add_free(self.slot) };
59 }
60}
61
62impl<T, C: Config> fmt::Debug for VacantEntry<'_, T, C> {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 f.debug_struct("VacantEntry")
65 .field("key", &self.key)
66 .finish_non_exhaustive()
67 }
68}
69
70#[must_use]
78pub struct BorrowedEntry<'g, T>(sdd::Ptr<'g, T> );
79
80impl<'g, T> BorrowedEntry<'g, T> {
81 pub(crate) fn new(ptr: sdd::Ptr<'g, T>) -> Option<Self> {
82 (!ptr.is_null()).then_some(Self(ptr))
83 }
84
85 #[inline]
95 pub fn to_owned(self) -> Option<OwnedEntry<T>> {
96 self.0.get_shared().map(OwnedEntry)
97 }
98}
99
100impl<T> Copy for BorrowedEntry<'_, T> {}
101
102impl<T> Clone for BorrowedEntry<'_, T> {
103 #[inline]
104 fn clone(&self) -> Self {
105 *self
106 }
107}
108
109impl<T> Deref for BorrowedEntry<'_, T> {
110 type Target = T;
111
112 #[inline]
113 fn deref(&self) -> &Self::Target {
114 let maybe_ref = self.0.as_ref();
115
116 unsafe { maybe_ref.unwrap_unchecked() }
118 }
119}
120
121impl<T: fmt::Debug> fmt::Debug for BorrowedEntry<'_, T> {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 fmt::Debug::fmt(&**self, f)
124 }
125}
126
127impl<T: PartialEq<T>> PartialEq<T> for BorrowedEntry<'_, T> {
128 #[inline]
129 fn eq(&self, other: &T) -> bool {
130 (**self).eq(other)
131 }
132}
133
134#[must_use]
142pub struct OwnedEntry<T>(sdd::Shared<T>);
143
144impl<T> Clone for OwnedEntry<T> {
145 #[inline]
146 fn clone(&self) -> Self {
147 Self(self.0.clone())
148 }
149}
150
151impl<T> Deref for OwnedEntry<T> {
152 type Target = T;
153
154 #[inline]
155 fn deref(&self) -> &Self::Target {
156 &self.0
157 }
158}
159
160impl<T: fmt::Debug> fmt::Debug for OwnedEntry<T> {
161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162 fmt::Debug::fmt(&*self.0, f)
163 }
164}
165
166impl<T: PartialEq<T>> PartialEq<T> for OwnedEntry<T> {
167 #[inline]
168 fn eq(&self, other: &T) -> bool {
169 self.0.eq(other)
170 }
171}
172
173#[must_use]
181pub struct Iter<'g, 's, T, C> {
182 pages: &'s [Page<T, C>],
183 slots: Option<page::Iter<'g, 's, T, C>>,
184 guard: &'g EbrGuard,
185}
186
187impl<'g, 's, T: 'static, C: Config> Iter<'g, 's, T, C> {
188 pub(crate) fn new(pages: &'s [Page<T, C>], guard: &'g EbrGuard) -> Self {
189 let (first, rest) = pages.split_first().expect("invalid MAX_PAGES");
190
191 Self {
192 pages: rest,
193 slots: first.iter(guard),
194 guard,
195 }
196 }
197}
198
199impl<'g, T: 'static, C: Config> Iterator for Iter<'g, '_, T, C> {
200 type Item = (Key, BorrowedEntry<'g, T>);
201
202 fn next(&mut self) -> Option<Self::Item> {
203 loop {
204 let slots = self.slots.as_mut()?;
205
206 if let Some(pair) = slots.next() {
207 return Some(pair);
208 }
209
210 let (slots, rest) = self
211 .pages
212 .split_first()
213 .map(|(next, rest)| (next.iter(self.guard), rest))
214 .unwrap_or_default();
215
216 self.pages = rest;
217 self.slots = slots;
218 }
219 }
220}
221
222impl<T: 'static, C: Config> std::iter::FusedIterator for Iter<'_, '_, T, C> {}
223
224impl<T, C> fmt::Debug for Iter<'_, '_, T, C> {
225 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226 f.debug_struct("Iter").finish_non_exhaustive()
227 }
228}