pub mod iter;
use std::{
fmt::Display,
ops::{Deref, DerefMut},
sync::{RwLock, RwLockReadGuard, RwLockWriteGuard},
};
use iter::{Iter, IterMut};
fn write<T>(rwl: &RwLock<T>) -> RwLockWriteGuard<T> {
match rwl.write() {
Ok(g) => g,
Err(g) => g.into_inner(),
}
}
fn read<T>(rwl: &RwLock<T>) -> RwLockReadGuard<T> {
match rwl.read() {
Ok(g) => g,
Err(g) => g.into_inner(),
}
}
#[derive(Debug, Clone)]
pub enum Entry<T> {
Empty,
Owned(T),
Moved(usize),
}
impl<T> Entry<T> {
fn owned(&self) -> Option<&T> {
if let Entry::Owned(t) = self {
Some(t)
} else {
None
}
}
fn owned_mut(&mut self) -> Option<&mut T> {
if let Entry::Owned(t) = self {
Some(t)
} else {
None
}
}
}
impl<T: Display> Display for Entry<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Entry::Empty => "Empty".fmt(f),
Entry::Owned(t) => write!(f, "Owned({})", t),
Entry::Moved(e) => write!(f, "Moved({})", e),
}
}
}
pub struct Lease<'v, T> {
entry: usize,
tenant: &'v RentVec<T>,
}
impl<'v, T> Lease<'v, T> {
pub fn guard(&mut self) -> LeaseGuard<'_, T> {
let guard = read(&self.tenant.lock);
let item = guard.items.get(self.entry).and_then(|mut item| loop {
match item {
Entry::Empty => None?,
Entry::Owned(t) => unsafe { break (t as *const T as *mut T).as_mut() },
Entry::Moved(e) => {
unsafe {
let item = item as *const Entry<T> as *mut Entry<T>;
*item = Entry::Empty
};
self.entry = *e;
item = guard.items.get(self.entry)?;
}
}
}).unwrap();
LeaseGuard {
item,
_guard: guard,
}
}
pub fn remove(self) {
self.tenant.remove(self.entry);
}
}
pub struct LeaseGuard<'l, T> {
item: &'l mut T,
_guard: RwLockReadGuard<'l, InnerRentVec<T>>,
}
impl<'l, T> Deref for LeaseGuard<'l, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.item
}
}
impl<'l, T> DerefMut for LeaseGuard<'l, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.item
}
}
#[derive(Debug)]
struct InnerRentVec<T> {
tail: usize,
items: Vec<Entry<T>>,
}
impl<T> Default for InnerRentVec<T> {
fn default() -> Self {
Self {
tail: 0,
items: Vec::default(),
}
}
}
#[derive(Debug)]
pub struct RentVec<T> {
lock: RwLock<InnerRentVec<T>>,
}
impl<T> Default for RentVec<T> {
fn default() -> Self {
Self {
lock: RwLock::default(),
}
}
}
impl<T> RentVec<T> {
pub fn new() -> Self {
Self::default()
}
fn remove(&self, entry: usize) -> Option<usize> {
let mut guard = write(&self.lock);
let mut replace = guard.tail - 1;
let items = &mut guard.items;
if entry == replace {
items[entry] = Entry::Empty;
guard.tail -= 1;
return None;
};
loop {
let item = &mut items[replace];
match item {
Entry::Empty | Entry::Moved(_) => {
replace -= 1
}
Entry::Owned(_) => {
let item = std::mem::replace(item, Entry::Moved(entry));
items[entry] = item;
guard.tail = guard.tail.min(replace);
break Some(replace);
}
}
}
}
pub fn push(&self, item: T) -> Lease<'_, T> {
let mut guard = write(&self.lock);
let mut tail = guard.tail;
let items = &mut guard.items;
let entry = (tail != items.len())
.then(|| {
loop {
let item = &items[tail];
match item {
Entry::Empty => {
break Some(tail);
}
Entry::Owned(_) => break None,
Entry::Moved(_) => {
if tail == items.len() {
break None;
};
tail += 1
}
}
}
})
.flatten();
let entry = match entry {
Some(entry) => {
items[entry] = Entry::Owned(item);
entry
}
None => {
let entry = items.len();
items.push(Entry::Owned(item));
entry
}
};
guard.tail = guard.tail.max(entry + 1);
Lease {
entry,
tenant: self,
}
}
pub fn guard(&self) -> RentVecGuard<'_, T> {
let guard = write(&self.lock);
RentVecGuard { guard }
}
pub fn shrink(&self) {
let mut guard = write(&self.lock);
while let Some(Entry::Empty) = guard.items.last() {
guard.items.pop();
}
guard.items.shrink_to_fit();
guard.tail = guard.tail.min(guard.items.len());
}
}
pub struct RentVecGuard<'a, T> {
guard: RwLockWriteGuard<'a, InnerRentVec<T>>,
}
impl<'a, T> RentVecGuard<'a, T> {
pub fn iter(&self) -> Iter<'_, T> {
Iter::new(&self.guard)
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut::new(&mut self.guard)
}
}