1use std::{
2 mem,
3 sync::{Arc, Once, RwLock, RwLockReadGuard, RwLockWriteGuard},
4};
5
6use super::HandyRwLock;
7use crate::{
8 btree::page_cache::PageCache,
9 concurrent_status::ConcurrentStatus, tx_log::LogManager,
10 types::Pod, Catalog,
11};
12
13pub struct Unique {
24 buffer_pool: Pod<PageCache>,
25 catalog: Pod<Catalog>,
26 concurrent_status: ConcurrentStatus,
27 log_file: Pod<LogManager>,
28}
29
30impl Unique {
31 fn new() -> Self {
32 Self {
33 buffer_pool: Arc::new(RwLock::new(PageCache::new())),
34 concurrent_status: ConcurrentStatus::new(),
35 catalog: Arc::new(RwLock::new(Catalog::new())),
36 log_file: Arc::new(RwLock::new(LogManager::new(
37 "wal.log",
38 ))),
39 }
40 }
41
42 pub fn mut_page_cache() -> RwLockWriteGuard<'static, PageCache> {
47 Self::global().buffer_pool.wl()
48 }
49
50 pub fn buffer_pool_pod() -> Arc<RwLock<PageCache>> {
51 Self::global().buffer_pool.clone()
52 }
53
54 pub fn concurrent_status() -> &'static ConcurrentStatus {
59 &Self::global().concurrent_status
60 }
61
62 pub fn catalog() -> RwLockReadGuard<'static, Catalog> {
63 Self::global().catalog.rl()
64 }
65
66 pub fn mut_catalog() -> RwLockWriteGuard<'static, Catalog> {
67 Self::global().catalog.wl()
68 }
69
70 pub fn log_file() -> RwLockReadGuard<'static, LogManager> {
71 Self::global().log_file.rl()
72 }
73
74 pub fn mut_log_manager() -> RwLockWriteGuard<'static, LogManager>
75 {
76 Self::global().log_file.wl()
77 }
78
79 pub fn log_file_pod() -> Arc<RwLock<LogManager>> {
80 Self::global().log_file.clone()
81 }
82
83 pub fn global() -> &'static Self {
84 static mut SINGLETON: *mut Unique = 0 as *mut Unique;
86 static ONCE: Once = Once::new();
87
88 ONCE.call_once(|| {
89 let singleton = Self::new();
91
92 unsafe {
93 SINGLETON = mem::transmute(Box::new(singleton));
95 }
96 });
97
98 unsafe {
99 SINGLETON.as_ref().unwrap()
102 }
103 }
104}