#![allow(unused)]
use std::collections::HashMap;
use std::collections::hash_map::{self, Entry};
use std::cell::RefCell;
use std::borrow::Borrow;
use std::hash::Hash;
use crate::xar::{Xar, XarHandle};
pub struct CacheMap<K, V> {
values: Xar<V>,
map: RefCell<HashMap<K, XarHandle<'static, V>>>,
}
impl<K, V> CacheMap<K, V> {
pub fn new() -> Self {
Self {
values: Xar::new(),
map: RefCell::new(HashMap::new()),
}
}
pub fn clear(&mut self) {
self.map.get_mut().drain().for_each(|(_, v)| {
unsafe{
self.values.delete(v);
}
})
}
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut::new(self.map.get_mut().iter_mut())
}
}
impl<K: Hash + Eq, V> CacheMap<K, V> {
pub fn get<Q>(&self, key: &Q) -> Option<&V> where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized,
{
Some(unsafe{self.map.borrow().get(key)?.get_ref()})
}
pub fn try_insert(&self, k: K, v: V) -> Result<(), (K, V)> {
let mut borrow = self.map.borrow_mut();
let borrow = &mut *borrow;
if borrow.get(&k).is_some() {
Err((k, v))
} else {
match borrow.entry(k) {
Entry::Vacant(x) => {
x.insert_entry(unsafe{self.values.insert(v).detach_lifetime()});
Ok(())
}
_ => unreachable!()
}
}
}
}
impl<K: Hash + Eq, V: PartialEq> PartialEq for CacheMap<K, V> {
fn eq(&self, other: &Self) -> bool {
let other = other.map.borrow();
let self_map = self.map.borrow();
for (k, v_0) in self_map.iter() {
match other.get(k) {
None => return false,
Some(v_1) if unsafe{v_0.get_ref() != v_1.get_ref()} => return false,
_ => (),
}
}
for (k, v_0) in other.iter() {
match self_map.get(k) {
None => return false,
Some(v_1) if unsafe{v_0.get_ref() != v_1.get_ref()} => return false,
_ => (),
}
}
true
}
}
impl<K: Hash + Eq, V: Eq> Eq for CacheMap<K, V> {
}
use std::fmt::{Debug, Formatter};
impl<K: Hash + Eq + Debug, V: Debug> Debug for CacheMap<K, V> {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
self.map.borrow().fmt(f)
}
}
impl<K, V> Drop for CacheMap<K, V> {
fn drop(&mut self) {
self.clear()
}
}
pub struct IterMut<'a, K: 'a, V: 'a> {
inner: hash_map::IterMut<'a, K, XarHandle<'static, V>>,
}
impl<'a, K: 'a, V: 'a> IterMut<'a, K, V> {
fn new(inner: hash_map::IterMut<'a, K, XarHandle<'static, V>>) -> Self {
Self {
inner
}
}
}
impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
let (k, v) = self.inner.next()?;
Some((k, unsafe{v.get_mut()}))
}
}