use parking_lot::Mutex;
use serde::{Deserializer, Serialize, Serializer};
use std::borrow::Borrow;
use std::cell::UnsafeCell;
use std::collections::{
btree_map::IntoIter as MapIntoIter, btree_map::Iter as MapIter,
btree_map::IterMut as MapIterMut, BTreeMap,
};
use std::fmt::{Debug, Display, Formatter};
use std::hash::Hash;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Index};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use super::{ReadGuard, ReadMapGuard, WriteGuard, WriteLock};
pub type BtreeMapGet<'a, V> = ReadGuard<'a, V>;
pub struct BtreeMapRefMut<'a, K, V> {
inner: WriteGuard<'a, V>,
_k: PhantomData<&'a K>,
}
impl<'a, K, V> BtreeMapRefMut<'a, K, V> {
#[inline]
pub(crate) fn new(inner: WriteGuard<'a, V>) -> Self {
BtreeMapRefMut {
inner,
_k: PhantomData,
}
}
}
impl<'a, K, V> Deref for BtreeMapRefMut<'a, K, V> {
type Target = V;
#[inline]
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'a, K, V> DerefMut for BtreeMapRefMut<'a, K, V> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<'a, K, V: Debug> Debug for BtreeMapRefMut<'a, K, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&*self.inner, f)
}
}
impl<'a, K, V: Display> Display for BtreeMapRefMut<'a, K, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(&*self.inner, f)
}
}
impl<'a, K, V: PartialEq> PartialEq for BtreeMapRefMut<'a, K, V> {
fn eq(&self, other: &Self) -> bool {
*self.inner == *other.inner
}
}
impl<'a, K, V: Eq> Eq for BtreeMapRefMut<'a, K, V> {}
pub struct BtreeMapIter<'a, K, V> {
count: &'a AtomicUsize,
inner: MapIter<'a, K, V>,
_not_send: PhantomData<*const ()>,
}
impl<'a, K, V> Drop for BtreeMapIter<'a, K, V> {
fn drop(&mut self) {
self.count.fetch_sub(1, Ordering::Release);
}
}
impl<'a, K, V> Iterator for BtreeMapIter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
pub struct BtreeMapIterMut<'a, K, V> {
_w: WriteLock<'a>,
inner: MapIterMut<'a, K, V>,
}
impl<'a, K, V> Deref for BtreeMapIterMut<'a, K, V> {
type Target = MapIterMut<'a, K, V>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'a, K, V> DerefMut for BtreeMapIterMut<'a, K, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<'a, K, V> Iterator for BtreeMapIterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
pub struct SyncBtreeMap<K: Eq + Hash, V> {
dirty: UnsafeCell<BTreeMap<K, V>>,
write: Mutex<()>,
id: usize,
writing: AtomicBool,
registry: Mutex<Vec<std::boxed::Box<AtomicUsize>>>,
}
unsafe impl<K: Eq + Hash, V: Send> Send for SyncBtreeMap<K, V> {}
unsafe impl<K: Eq + Hash, V: Sync> Sync for SyncBtreeMap<K, V> {}
impl<K, V> SyncBtreeMap<K, V>
where
K: Eq + Hash,
{
#[inline]
fn begin_read(&self) -> &AtomicUsize {
let count = super::reader_count_for(self.id, &self.registry);
loop {
count.fetch_add(1, Ordering::SeqCst);
if !self.writing.load(Ordering::SeqCst) {
return count;
}
count.fetch_sub(1, Ordering::SeqCst);
std::thread::yield_now();
}
}
#[inline]
fn begin_write(&self) -> WriteLock<'_> {
let lock = self.write.lock();
self.writing.store(true, Ordering::SeqCst);
loop {
let registry = self.registry.lock();
let all_zero = registry.iter().all(|c| c.load(Ordering::SeqCst) == 0);
if all_zero {
break;
}
drop(registry);
std::thread::yield_now();
}
WriteLock::new(lock, &self.writing)
}
pub fn new_arc() -> Arc<Self> {
Arc::new(Self::new())
}
pub fn new() -> Self {
Self {
dirty: UnsafeCell::new(BTreeMap::new()),
write: Mutex::new(()),
id: super::CONTAINER_ID.fetch_add(1, Ordering::Relaxed),
writing: AtomicBool::new(false),
registry: Mutex::new(Vec::new()),
}
}
pub fn with_capacity(_capacity: usize) -> Self {
Self::new()
}
pub fn with_map(map: BTreeMap<K, V>) -> Self
where
K: Ord,
{
Self {
dirty: UnsafeCell::new(map),
write: Mutex::new(()),
id: super::CONTAINER_ID.fetch_add(1, Ordering::Relaxed),
writing: AtomicBool::new(false),
registry: Mutex::new(Vec::new()),
}
}
pub fn insert(&self, k: K, v: V) -> Option<V>
where
K: Ord,
{
let _w = self.begin_write();
unsafe { &mut *self.dirty.get() }.insert(k, v)
}
pub fn insert_mut(&mut self, k: K, v: V) -> Option<V>
where
K: Ord,
{
unsafe { &mut *self.dirty.get() }.insert(k, v)
}
pub fn remove(&self, k: &K) -> Option<V>
where
K: Ord,
{
let _w = self.begin_write();
unsafe { &mut *self.dirty.get() }.remove(k)
}
pub fn remove_mut(&mut self, k: &K) -> Option<V>
where
K: Ord,
{
unsafe { &mut *self.dirty.get() }.remove(k)
}
pub fn len(&self) -> usize {
let count = self.begin_read();
let n = unsafe { &*self.dirty.get() }.len();
count.fetch_sub(1, Ordering::Release);
n
}
pub fn is_empty(&self) -> bool {
let count = self.begin_read();
let b = unsafe { &*self.dirty.get() }.is_empty();
count.fetch_sub(1, Ordering::Release);
b
}
pub fn clear(&self) {
let _w = self.begin_write();
unsafe { &mut *self.dirty.get() }.clear();
}
pub fn clear_mut(&mut self) {
unsafe { &mut *self.dirty.get() }.clear();
}
pub fn shrink_to_fit(&self) {}
pub fn shrink_to_fit_mut(&mut self) {}
pub fn from(map: BTreeMap<K, V>) -> Self
where
K: Eq + Hash + Ord,
{
Self::with_map(map)
}
#[inline]
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<BtreeMapGet<'_, V>>
where
K: Borrow<Q> + Ord,
Q: Ord,
{
let count = self.begin_read();
let m = unsafe { &*self.dirty.get() };
match m.get(k) {
Some(v) => Some(ReadGuard::new(count, v)),
None => {
count.fetch_sub(1, Ordering::Release);
None
}
}
}
#[inline]
pub fn get_mut(&self, k: &K) -> Option<BtreeMapRefMut<'_, K, V>>
where
K: Ord,
{
let w = self.begin_write();
let m = unsafe { &mut *self.dirty.get() };
match m.get_mut(k) {
Some(v) => Some(BtreeMapRefMut::new(WriteGuard::new(w, v))),
None => None,
}
}
#[inline]
pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
where
K: Borrow<Q> + Ord,
Q: Ord,
{
let count = self.begin_read();
let b = unsafe { &*self.dirty.get() }.contains_key(k);
count.fetch_sub(1, Ordering::Release);
b
}
pub fn iter(&self) -> BtreeMapIter<'_, K, V> {
let count = self.begin_read();
let m = unsafe { &*self.dirty.get() };
BtreeMapIter {
count,
inner: m.iter(),
_not_send: PhantomData,
}
}
pub fn iter_mut(&self) -> BtreeMapIterMut<'_, K, V> {
let w = self.begin_write();
let m = unsafe { &mut *self.dirty.get() };
BtreeMapIterMut {
_w: w,
inner: m.iter_mut(),
}
}
pub fn into_iter(self) -> MapIntoIter<K, V>
where
K: Ord,
{
self.into_inner().into_iter()
}
pub fn dirty_ref(&self) -> ReadMapGuard<'_, BTreeMap<K, V>> {
let count = self.begin_read();
let m = unsafe { &*self.dirty.get() };
ReadMapGuard::new(count, m)
}
pub fn into_inner(self) -> BTreeMap<K, V>
where
K: Ord,
{
self.dirty.into_inner()
}
}
impl<K: Eq + Hash + Ord, V> IntoIterator for SyncBtreeMap<K, V> {
type Item = (K, V);
type IntoIter = MapIntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.into_iter()
}
}
impl<'a, K: Eq + Hash, V> IntoIterator for &'a SyncBtreeMap<K, V> {
type Item = (&'a K, &'a V);
type IntoIter = BtreeMapIter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<K, V> Index<&K> for SyncBtreeMap<K, V>
where
K: Eq + Hash + Ord,
{
type Output = V;
fn index(&self, index: &K) -> &Self::Output {
unsafe { &(&*self.dirty.get())[index] }
}
}
impl<K: Eq + Hash + Ord, V> From<BTreeMap<K, V>> for SyncBtreeMap<K, V> {
fn from(arg: BTreeMap<K, V>) -> Self {
Self::from(arg)
}
}
impl<K, V> serde::Serialize for SyncBtreeMap<K, V>
where
K: Eq + Hash + Serialize + Ord,
V: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.dirty_ref().serialize(serializer)
}
}
impl<'de, K, V> serde::Deserialize<'de> for SyncBtreeMap<K, V>
where
K: Eq + Hash + Ord + serde::Deserialize<'de>,
V: serde::Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let m = BTreeMap::deserialize(deserializer)?;
Ok(Self::from(m))
}
}
impl<K, V> Debug for SyncBtreeMap<K, V>
where
K: Eq + Hash + Debug,
V: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&*self.dirty_ref(), f)
}
}
impl<K, V> Display for SyncBtreeMap<K, V>
where
K: Eq + Hash + Debug,
V: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&*self.dirty_ref(), f)
}
}
impl<K: Clone + Eq + Hash + Ord, V: Clone> Clone for SyncBtreeMap<K, V> {
fn clone(&self) -> Self {
let c = (*self.dirty_ref()).clone();
SyncBtreeMap::from(c)
}
}
impl<K: Eq + Hash, V> Default for SyncBtreeMap<K, V> {
fn default() -> Self {
SyncBtreeMap::new()
}
}