use crate::{Quota, QuotaId, QuotaPool, QuotaRef};
use std::hash::Hash;
pub struct OccupiedQuotaPoolEntry<'a, K: Eq + Hash> {
pub(crate) key: K,
pub(crate) id: QuotaId,
pub(crate) pool: &'a mut QuotaPool<K>,
}
pub struct VacantQuotaPoolEntry<'a, K: Eq + Hash> {
pub(crate) key: K,
pub(crate) pool: &'a mut QuotaPool<K>,
}
pub enum QuotaEntry<'a, K: Eq + Hash> {
Occupied(OccupiedQuotaPoolEntry<'a, K>),
Vacant(VacantQuotaPoolEntry<'a, K>),
}
impl<'a, K: Eq + Hash> QuotaEntry<'a, K> {
#[inline]
pub fn or_insert(self, default: Quota) -> QuotaRef<'a> {
match self {
Self::Occupied(entry) => entry.into_mut(),
Self::Vacant(entry) => entry.insert(default),
}
}
#[inline]
pub fn or_insert_with<F>(self, default: F) -> QuotaRef<'a>
where
F: FnOnce() -> Quota,
{
match self {
Self::Occupied(entry) => entry.into_mut(),
Self::Vacant(entry) => entry.insert(default()),
}
}
#[inline]
pub fn or_insert_with_key<F>(self, default: F) -> QuotaRef<'a>
where
F: FnOnce(&K) -> Quota,
{
match self {
Self::Occupied(entry) => entry.into_mut(),
Self::Vacant(entry) => {
let quota = default(entry.key());
entry.insert(quota)
}
}
}
#[inline]
pub fn or_default(self) -> QuotaRef<'a> {
self.or_insert_with(Quota::new)
}
#[inline]
pub fn key(&self) -> &K {
match self {
Self::Occupied(entry) => entry.key(),
Self::Vacant(entry) => entry.key(),
}
}
#[inline]
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(QuotaRef<'_>),
{
match self {
Self::Occupied(entry) => {
f(entry.get());
Self::Occupied(entry)
}
Self::Vacant(entry) => Self::Vacant(entry),
}
}
#[inline]
pub fn insert_entry(self, value: Quota) -> OccupiedQuotaPoolEntry<'a, K>
where
K: Clone,
{
match self {
Self::Occupied(mut entry) => {
entry.insert(value);
entry
}
Self::Vacant(entry) => entry.insert_entry(value),
}
}
}
impl<'a, K: Eq + Hash> OccupiedQuotaPoolEntry<'a, K> {
#[inline]
pub fn key(&self) -> &K {
&self.key
}
#[inline]
pub fn remove_entry(self) -> (K, Quota) {
let Self { pool, key, id } = self;
let (key, removed_id) = pool
.key_map
.remove_entry(&key)
.expect("QuotaPool occupied entry key was missing from the key map");
debug_assert_eq!(removed_id, id);
let quota = pool
.buffer
.take(id)
.expect("QuotaPool key map pointed at a stale QuotaId");
(key, quota)
}
#[inline]
pub fn get(&self) -> QuotaRef<'_> {
QuotaRef::new(&self.pool.buffer, self.id)
}
#[inline]
pub fn get_mut(&mut self) -> QuotaRef<'_> {
QuotaRef::new(&self.pool.buffer, self.id)
}
#[inline]
pub fn into_mut(self) -> QuotaRef<'a> {
let Self { pool, id, .. } = self;
QuotaRef::new(&pool.buffer, id)
}
#[inline]
pub fn insert(&mut self, value: Quota) -> Quota {
self.pool
.buffer
.replace(self.id, value)
.expect("QuotaPool key map pointed at a stale QuotaId")
}
#[inline]
pub fn remove(self) -> Quota {
self.remove_entry().1
}
}
impl<'a, K: Eq + Hash> VacantQuotaPoolEntry<'a, K> {
#[inline]
pub fn key(&self) -> &K {
&self.key
}
#[inline]
pub fn into_key(self) -> K {
self.key
}
#[inline]
pub fn insert(self, value: Quota) -> QuotaRef<'a> {
let id = self.pool.buffer.push(value);
let old_id = self.pool.key_map.insert(self.key, id);
debug_assert!(old_id.is_none());
QuotaRef::new(&self.pool.buffer, id)
}
#[inline]
pub fn insert_entry(self, value: Quota) -> OccupiedQuotaPoolEntry<'a, K>
where
K: Clone,
{
let key = self.key.clone();
let id = self.pool.buffer.push(value);
let old_id = self.pool.key_map.insert(self.key, id);
debug_assert!(old_id.is_none());
OccupiedQuotaPoolEntry {
pool: self.pool,
key,
id,
}
}
}