use std::{
mem,
sync::{Arc, Once, RwLock, RwLockReadGuard, RwLockWriteGuard},
};
use super::HandyRwLock;
use crate::{
btree::page_cache::PageCache,
concurrent_status::ConcurrentStatus, tx_log::LogManager,
types::Pod, Catalog,
};
pub struct Unique {
buffer_pool: Pod<PageCache>,
catalog: Pod<Catalog>,
concurrent_status: ConcurrentStatus,
log_file: Pod<LogManager>,
}
impl Unique {
fn new() -> Self {
Self {
buffer_pool: Arc::new(RwLock::new(PageCache::new())),
concurrent_status: ConcurrentStatus::new(),
catalog: Arc::new(RwLock::new(Catalog::new())),
log_file: Arc::new(RwLock::new(LogManager::new(
"wal.log",
))),
}
}
pub fn mut_page_cache() -> RwLockWriteGuard<'static, PageCache> {
Self::global().buffer_pool.wl()
}
pub fn buffer_pool_pod() -> Arc<RwLock<PageCache>> {
Self::global().buffer_pool.clone()
}
pub fn concurrent_status() -> &'static ConcurrentStatus {
&Self::global().concurrent_status
}
pub fn catalog() -> RwLockReadGuard<'static, Catalog> {
Self::global().catalog.rl()
}
pub fn mut_catalog() -> RwLockWriteGuard<'static, Catalog> {
Self::global().catalog.wl()
}
pub fn log_file() -> RwLockReadGuard<'static, LogManager> {
Self::global().log_file.rl()
}
pub fn mut_log_manager() -> RwLockWriteGuard<'static, LogManager>
{
Self::global().log_file.wl()
}
pub fn log_file_pod() -> Arc<RwLock<LogManager>> {
Self::global().log_file.clone()
}
pub fn global() -> &'static Self {
static mut SINGLETON: *mut Unique = 0 as *mut Unique;
static ONCE: Once = Once::new();
ONCE.call_once(|| {
let singleton = Self::new();
unsafe {
SINGLETON = mem::transmute(Box::new(singleton));
}
});
unsafe {
SINGLETON.as_ref().unwrap()
}
}
}