Skip to main content

feophantlib/engine/io/block_layer/
lock_manager.rs

1use 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/// The LockManager is used for cooperative access to pages in the system.
9///
10/// Before accessing the I/O layer you must get a read or write lock on
11/// the page you need to access. Only AFTER you have the lock you should
12/// ask for the page.
13#[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        //todo!("Figure out the new model");
74
75        Ok(())
76    }
77}