use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::sync::atomic::{AtomicBool, Ordering};
use writium::prelude::*;
const ERR_POISONED_THREAD: &str = "Current thread is poisoned.";
pub struct CacheItem<T: 'static> {
id: String,
data: RwLock<T>,
is_dirty: AtomicBool,
}
impl<T: 'static> CacheItem<T> {
pub fn new(id: &str, data: T) -> CacheItem<T> {
CacheItem {
id: id.to_owned(),
data: RwLock::new(data),
is_dirty: AtomicBool::new(false),
}
}
pub fn id(&self) -> &str {
&self.id
}
pub fn read<'guard, 'lock: 'guard>(&'lock self) -> Result<RwLockReadGuard<'guard, T>> {
self.data.read()
.map_err(|_| Error::internal(ERR_POISONED_THREAD))
}
pub fn write<'guard, 'lock: 'guard>(&'lock self) -> Result<RwLockWriteGuard<'guard, T>> {
self.set_dirty();
self.data.write()
.map_err(|_| Error::internal(ERR_POISONED_THREAD))
}
pub fn is_dirty(&self) -> bool {
self.is_dirty.load(Ordering::Acquire)
}
pub(crate) fn set_dirty(&self) {
self.is_dirty.store(true, Ordering::Release)
}
}