use std::{fmt, mem, ops::Deref};
use crate::{
config::Config,
key::Key,
page::{self, Page},
slot::Slot,
EbrGuard,
};
#[must_use]
pub struct VacantEntry<'s, T: 'static, C: Config> {
page: &'s Page<T, C>,
slot: &'s Slot<T, C>,
key: Key,
}
impl<'s, T: 'static, C: Config> VacantEntry<'s, T, C> {
pub(crate) fn new(page: &'s Page<T, C>, slot: &'s Slot<T, C>, key: Key) -> Self {
Self { page, slot, key }
}
#[must_use]
#[inline]
pub fn key(&self) -> Key {
self.key
}
#[inline]
pub fn insert(self, value: T) {
self.slot.init(value);
mem::forget(self);
}
}
impl<T: 'static, C: Config> Drop for VacantEntry<'_, T, C> {
#[inline]
fn drop(&mut self) {
unsafe { self.page.add_free(self.slot) };
}
}
impl<T, C: Config> fmt::Debug for VacantEntry<'_, T, C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("VacantEntry")
.field("key", &self.key)
.finish_non_exhaustive()
}
}
#[must_use]
pub struct BorrowedEntry<'g, T>(sdd::Ptr<'g, T> );
impl<'g, T> BorrowedEntry<'g, T> {
pub(crate) fn new(ptr: sdd::Ptr<'g, T>) -> Option<Self> {
(!ptr.is_null()).then_some(Self(ptr))
}
#[inline]
pub fn to_owned(self) -> OwnedEntry<T> {
let maybe_shared = self.0.get_shared();
OwnedEntry(unsafe { maybe_shared.unwrap_unchecked() })
}
#[doc(hidden)]
#[deprecated(note = "use `to_owned()` instead")]
#[inline]
pub fn into_owned(self) -> OwnedEntry<T> {
self.to_owned()
}
}
impl<T> Copy for BorrowedEntry<'_, T> {}
impl<T> Clone for BorrowedEntry<'_, T> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<T> Deref for BorrowedEntry<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
let maybe_ref = self.0.as_ref();
unsafe { maybe_ref.unwrap_unchecked() }
}
}
impl<T: fmt::Debug> fmt::Debug for BorrowedEntry<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<T: PartialEq<T>> PartialEq<T> for BorrowedEntry<'_, T> {
#[inline]
fn eq(&self, other: &T) -> bool {
(**self).eq(other)
}
}
#[must_use]
pub struct OwnedEntry<T>(sdd::Shared<T>);
impl<T> Clone for OwnedEntry<T> {
#[inline]
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T> Deref for OwnedEntry<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: fmt::Debug> fmt::Debug for OwnedEntry<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&*self.0, f)
}
}
impl<T: PartialEq<T>> PartialEq<T> for OwnedEntry<T> {
#[inline]
fn eq(&self, other: &T) -> bool {
self.0.eq(other)
}
}
#[must_use]
pub struct Iter<'g, 's, T, C> {
pages: &'s [Page<T, C>],
slots: Option<page::Iter<'g, 's, T, C>>,
guard: &'g EbrGuard,
}
impl<'g, 's, T: 'static, C: Config> Iter<'g, 's, T, C> {
pub(crate) fn new(pages: &'s [Page<T, C>], guard: &'g EbrGuard) -> Self {
let (first, rest) = pages.split_first().expect("invalid MAX_PAGES");
Self {
pages: rest,
slots: first.iter(guard),
guard,
}
}
}
impl<'g, 's, T: 'static, C: Config> Iterator for Iter<'g, 's, T, C> {
type Item = (Key, BorrowedEntry<'g, T>);
fn next(&mut self) -> Option<Self::Item> {
loop {
let slots = self.slots.as_mut()?;
if let Some(pair) = slots.next() {
return Some(pair);
}
let (slots, rest) = self
.pages
.split_first()
.map(|(next, rest)| (next.iter(self.guard), rest))
.unwrap_or_default();
self.pages = rest;
self.slots = slots;
}
}
}
impl<T: 'static, C: Config> std::iter::FusedIterator for Iter<'_, '_, T, C> {}
impl<T, C> fmt::Debug for Iter<'_, '_, T, C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Iter").finish_non_exhaustive()
}
}