omega_cache/core/entry_ref.rs
1use crate::core::entry::Entry;
2use crossbeam::epoch::Guard;
3use std::hash::Hash;
4use std::ops::Deref;
5use std::ptr::NonNull;
6
7/// A guarded pointer to a cache [Entry].
8///
9/// `EntryRef` provides safe access to an entry stored in the Clock cache.
10/// It binds the entry's memory location to an epoch [Guard], ensuring the
11/// entry is not reclaimed by the cache's eviction policy while this
12/// handle exists.
13///
14/// Because it acts as a smart pointer to the [Entry] container rather than
15/// the value itself, it provides methods to access both the key and the value.
16#[derive(Debug)]
17pub struct Ref<K, V>
18where
19 K: Eq + Hash,
20{
21 ptr: NonNull<Entry<K, V>>,
22 /// This guard ensures the entry remains valid for the lifetime of this struct.
23 _guard: Guard,
24}
25
26impl<K, V> Ref<K, V>
27where
28 K: Eq + Hash,
29{
30 /// Creates a new `EntryRef`.
31 ///
32 /// # Safety
33 /// The `ptr` must be valid and must have been pinned by the provided `guard`.
34 #[inline]
35 pub(crate) fn new(ptr: NonNull<Entry<K, V>>, guard: Guard) -> Self {
36 Self { ptr, _guard: guard }
37 }
38
39 /// Access the underlying entry.
40 /// Using a private method helps centralize the unsafe dereference.
41 #[inline]
42 fn as_entry(&self) -> &Entry<K, V> {
43 // SAFETY: The existence of _guard ensures the epoch is pinned,
44 // preventing the cache from reclaiming this Entry.
45 unsafe { self.ptr.as_ref() }
46 }
47
48 /// Returns a shared reference to the entry's key.
49 #[inline]
50 pub fn key(&self) -> &K {
51 self.as_entry().key()
52 }
53
54 /// Returns a shared reference to the entry's value.
55 #[inline]
56 pub fn value(&self) -> &V {
57 self.as_entry().value()
58 }
59
60 /// Returns `true` if the underlying entry has passed its expiration deadline.
61 #[inline]
62 pub fn is_expired(&self) -> bool {
63 self.as_entry().is_expired()
64 }
65}
66
67impl<K, V> Deref for Ref<K, V>
68where
69 K: Eq + Hash,
70{
71 type Target = Entry<K, V>;
72
73 fn deref(&self) -> &Self::Target {
74 unsafe { self.ptr.as_ref() }
75 }
76}