feophantlib/engine/io/block_layer/
lock_manager.rs1use std::sync::Arc;
2
3use crate::engine::io::page_formats::{PageId, PageOffset};
4use moka::future::Cache;
5use thiserror::Error;
6use tokio::sync::{OwnedRwLockReadGuard, OwnedRwLockWriteGuard, RwLock};
7
8#[derive(Clone)]
14pub struct LockManager {
15 locks: Cache<(PageId, PageOffset), Arc<RwLock<(PageId, PageOffset)>>>,
16}
17
18impl LockManager {
19 pub fn new() -> LockManager {
20 LockManager {
21 locks: Cache::new(1000),
22 }
23 }
24
25 async fn get_lock(
26 &self,
27 page_id: PageId,
28 offset: PageOffset,
29 ) -> Arc<RwLock<(PageId, PageOffset)>> {
30 self.locks
31 .get_or_insert_with((page_id, offset), async move {
32 Arc::new(RwLock::const_new((page_id, offset)))
33 })
34 .await
35 }
36
37 pub async fn read(
38 &self,
39 page_id: PageId,
40 offset: PageOffset,
41 ) -> OwnedRwLockReadGuard<(PageId, PageOffset)> {
42 self.get_lock(page_id, offset).await.read_owned().await
43 }
44
45 pub async fn write(
46 &self,
47 page_id: PageId,
48 offset: PageOffset,
49 ) -> OwnedRwLockWriteGuard<(PageId, PageOffset)> {
50 self.get_lock(page_id, offset).await.write_owned().await
51 }
52}
53
54impl Default for LockManager {
55 fn default() -> Self {
56 Self::new()
57 }
58}
59
60#[derive(Debug, Error)]
61pub enum LockManagerError {}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66 use tempfile::TempDir;
67
68 #[test]
69 fn test_locking() -> Result<(), Box<dyn std::error::Error>> {
70 let tmp = TempDir::new()?;
71 let tmp_dir = tmp.path().as_os_str().to_os_string();
72
73 Ok(())
76 }
77}