1use std::{fmt, mem, ops::Deref};
2
3use crate::{
4 config::Config,
5 key::Key,
6 page::{self, Page},
7 slot::Slot,
8 EbrGuard,
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]
94 pub fn to_owned(self) -> Option<OwnedEntry<T>> {
95 self.0.get_shared().map(OwnedEntry)
96 }
97}
98
99impl<T> Copy for BorrowedEntry<'_, T> {}
100
101impl<T> Clone for BorrowedEntry<'_, T> {
102 #[inline]
103 fn clone(&self) -> Self {
104 *self
105 }
106}
107
108impl<T> Deref for BorrowedEntry<'_, T> {
109 type Target = T;
110
111 #[inline]
112 fn deref(&self) -> &Self::Target {
113 let maybe_ref = self.0.as_ref();
114
115 unsafe { maybe_ref.unwrap_unchecked() }
117 }
118}
119
120impl<T: fmt::Debug> fmt::Debug for BorrowedEntry<'_, T> {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 fmt::Debug::fmt(&**self, f)
123 }
124}
125
126impl<T: PartialEq<T>> PartialEq<T> for BorrowedEntry<'_, T> {
127 #[inline]
128 fn eq(&self, other: &T) -> bool {
129 (**self).eq(other)
130 }
131}
132
133#[must_use]
141pub struct OwnedEntry<T>(sdd::Shared<T>);
142
143impl<T> Clone for OwnedEntry<T> {
144 #[inline]
145 fn clone(&self) -> Self {
146 Self(self.0.clone())
147 }
148}
149
150impl<T> Deref for OwnedEntry<T> {
151 type Target = T;
152
153 #[inline]
154 fn deref(&self) -> &Self::Target {
155 &self.0
156 }
157}
158
159impl<T: fmt::Debug> fmt::Debug for OwnedEntry<T> {
160 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 fmt::Debug::fmt(&*self.0, f)
162 }
163}
164
165impl<T: PartialEq<T>> PartialEq<T> for OwnedEntry<T> {
166 #[inline]
167 fn eq(&self, other: &T) -> bool {
168 self.0.eq(other)
169 }
170}
171
172#[must_use]
180pub struct Iter<'g, 's, T, C> {
181 pages: &'s [Page<T, C>],
182 slots: Option<page::Iter<'g, 's, T, C>>,
183 guard: &'g EbrGuard,
184}
185
186impl<'g, 's, T: 'static, C: Config> Iter<'g, 's, T, C> {
187 pub(crate) fn new(pages: &'s [Page<T, C>], guard: &'g EbrGuard) -> Self {
188 let (first, rest) = pages.split_first().expect("invalid MAX_PAGES");
189
190 Self {
191 pages: rest,
192 slots: first.iter(guard),
193 guard,
194 }
195 }
196}
197
198impl<'g, T: 'static, C: Config> Iterator for Iter<'g, '_, T, C> {
199 type Item = (Key, BorrowedEntry<'g, T>);
200
201 fn next(&mut self) -> Option<Self::Item> {
202 loop {
203 let slots = self.slots.as_mut()?;
204
205 if let Some(pair) = slots.next() {
206 return Some(pair);
207 }
208
209 let (slots, rest) = self
210 .pages
211 .split_first()
212 .map(|(next, rest)| (next.iter(self.guard), rest))
213 .unwrap_or_default();
214
215 self.pages = rest;
216 self.slots = slots;
217 }
218 }
219}
220
221impl<T: 'static, C: Config> std::iter::FusedIterator for Iter<'_, '_, T, C> {}
222
223impl<T, C> fmt::Debug for Iter<'_, '_, T, C> {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 f.debug_struct("Iter").finish_non_exhaustive()
226 }
227}