pub use super::bucket::{Node, NodeStatus, InsertResult, AppliedPending, K_VALUE};
pub use super::key::*;
use super::*;
pub struct EntryRefView<'a, TPeerId, TVal> {
pub node: NodeRefView<'a, TPeerId, TVal>,
pub status: NodeStatus
}
pub struct NodeRefView<'a, TKey, TVal> {
pub key: &'a TKey,
pub value: &'a TVal
}
impl<TKey, TVal> EntryRefView<'_, TKey, TVal> {
pub fn to_owned(&self) -> EntryView<TKey, TVal>
where
TKey: Clone,
TVal: Clone
{
EntryView {
node: Node {
key: self.node.key.clone(),
value: self.node.value.clone()
},
status: self.status
}
}
}
#[derive(Clone, Debug)]
pub struct EntryView<TKey, TVal> {
pub node: Node<TKey, TVal>,
pub status: NodeStatus
}
impl<TKey: AsRef<KeyBytes>, TVal> AsRef<KeyBytes> for EntryView<TKey, TVal> {
fn as_ref(&self) -> &KeyBytes {
self.node.key.as_ref()
}
}
#[derive(Debug)]
pub enum Entry<'a, TPeerId, TVal> {
Present(PresentEntry<'a, TPeerId, TVal>, NodeStatus),
Pending(PendingEntry<'a, TPeerId, TVal>, NodeStatus),
Absent(AbsentEntry<'a, TPeerId, TVal>),
SelfEntry,
}
#[derive(Debug)]
struct EntryRef<'a, TKey, TVal> {
bucket: &'a mut KBucket<TKey, TVal>,
key: &'a TKey,
}
impl<'a, TKey, TVal> Entry<'a, TKey, TVal>
where
TKey: Clone + AsRef<KeyBytes>,
TVal: Clone
{
pub(super) fn new(bucket: &'a mut KBucket<TKey, TVal>, key: &'a TKey) -> Self {
if let Some(pos) = bucket.position(key) {
let status = bucket.status(pos);
Entry::Present(PresentEntry::new(bucket, key), status)
} else if let Some(pending) = bucket.as_pending(key) {
let status = pending.status();
Entry::Pending(PendingEntry::new(bucket, key), status)
} else {
Entry::Absent(AbsentEntry::new(bucket, key))
}
}
pub fn view(&'a mut self) -> Option<EntryRefView<'a, TKey, TVal>> {
match self {
Entry::Present(entry, status) => Some(EntryRefView {
node: NodeRefView {
key: entry.0.key,
value: entry.value()
},
status: *status
}),
Entry::Pending(entry, status) => Some(EntryRefView {
node: NodeRefView {
key: entry.0.key,
value: entry.value()
},
status: *status
}),
_ => None
}
}
pub fn key(&self) -> Option<&TKey> {
match self {
Entry::Present(entry, _) => Some(entry.key()),
Entry::Pending(entry, _) => Some(entry.key()),
Entry::Absent(entry) => Some(entry.key()),
Entry::SelfEntry => None,
}
}
pub fn value(&mut self) -> Option<&mut TVal> {
match self {
Entry::Present(entry, _) => Some(entry.value()),
Entry::Pending(entry, _) => Some(entry.value()),
Entry::Absent(_) => None,
Entry::SelfEntry => None,
}
}
}
#[derive(Debug)]
pub struct PresentEntry<'a, TKey, TVal>(EntryRef<'a, TKey, TVal>);
impl<'a, TKey, TVal> PresentEntry<'a, TKey, TVal>
where
TKey: Clone + AsRef<KeyBytes>,
TVal: Clone
{
fn new(bucket: &'a mut KBucket<TKey, TVal>, key: &'a TKey) -> Self {
PresentEntry(EntryRef { bucket, key })
}
pub fn key(&self) -> &TKey {
self.0.key
}
pub fn value(&mut self) -> &mut TVal {
&mut self.0.bucket
.get_mut(self.0.key)
.expect("We can only build a PresentEntry if the entry is in the bucket; QED")
.value
}
pub fn update(self, status: NodeStatus) -> Self {
self.0.bucket.update(self.0.key, status);
Self::new(self.0.bucket, self.0.key)
}
pub fn remove(self) -> EntryView<TKey, TVal> {
let (node, status, _pos) = self.0.bucket
.remove(&self.0.key)
.expect("We can only build a PresentEntry if the entry is in the bucket; QED");
EntryView { node, status }
}
}
#[derive(Debug)]
pub struct PendingEntry<'a, TKey, TVal>(EntryRef<'a, TKey, TVal>);
impl<'a, TKey, TVal> PendingEntry<'a, TKey, TVal>
where
TKey: Clone + AsRef<KeyBytes>,
TVal: Clone
{
fn new(bucket: &'a mut KBucket<TKey, TVal>, key: &'a TKey) -> Self {
PendingEntry(EntryRef { bucket, key })
}
pub fn key(&self) -> &TKey {
self.0.key
}
pub fn value(&mut self) -> &mut TVal {
self.0.bucket
.pending_mut()
.expect("We can only build a ConnectedPendingEntry if the entry is pending; QED")
.value_mut()
}
pub fn update(self, status: NodeStatus) -> PendingEntry<'a, TKey, TVal> {
self.0.bucket.update_pending(status);
PendingEntry::new(self.0.bucket, self.0.key)
}
pub fn remove(self) -> EntryView<TKey, TVal> {
let pending = self.0.bucket
.remove_pending()
.expect("We can only build a PendingEntry if the entry is pending insertion
into the bucket; QED");
let status = pending.status();
let node = pending.into_node();
EntryView { node, status }
}
}
#[derive(Debug)]
pub struct AbsentEntry<'a, TKey, TVal>(EntryRef<'a, TKey, TVal>);
impl<'a, TKey, TVal> AbsentEntry<'a, TKey, TVal>
where
TKey: Clone + AsRef<KeyBytes>,
TVal: Clone
{
fn new(bucket: &'a mut KBucket<TKey, TVal>, key: &'a TKey) -> Self {
AbsentEntry(EntryRef { bucket, key })
}
pub fn key(&self) -> &TKey {
self.0.key
}
pub fn insert(self, value: TVal, status: NodeStatus) -> InsertResult<TKey> {
self.0.bucket.insert(Node {
key: self.0.key.clone(),
value
}, status)
}
}