diff --git a/judger/src/filesystem/table/handle.rs b/judger/src/filesystem/table/handle.rs index b0cc3da..ac75b8d 100644 --- a/judger/src/filesystem/table/handle.rs +++ b/judger/src/filesystem/table/handle.rs @@ -1,33 +1,30 @@ use std::{collections::BTreeMap, sync::atomic::AtomicU64}; use spin::RwLock; -use tokio::io::{AsyncRead, AsyncSeek}; -use crate::filesystem::overlay::*; - -pub struct HandleTable -where - F: AsyncRead + AsyncSeek + Unpin + 'static, -{ +pub struct HandleTable { handle_generator: AtomicU64, - table: RwLock>>, + table: RwLock>, } -impl HandleTable -where - F: AsyncRead + AsyncSeek + Unpin + 'static, -{ - pub fn new_handle(&self, entry: ArcEntry) -> u64 { +impl HandleTable { + pub fn new() -> Self { + Self { + handle_generator: AtomicU64::new(0), + table: RwLock::new(BTreeMap::new()), + } + } + pub fn add(&self, entry: E) -> u64 { let handle = self .handle_generator .fetch_add(1, std::sync::atomic::Ordering::AcqRel); self.table.write().insert(handle, entry); handle } - pub fn get_entry(&self, handle: u64) -> Option> { + pub fn get(&self, handle: u64) -> Option { self.table.read().get(&handle).cloned() } - pub fn remove_entry(&self, handle: u64) -> Option> { + pub fn remove(&self, handle: u64) -> Option { self.table.write().remove(&handle) } } diff --git a/judger/src/filesystem/table/inode.rs b/judger/src/filesystem/table/inode.rs index 1ae9e5e..846298c 100644 --- a/judger/src/filesystem/table/inode.rs +++ b/judger/src/filesystem/table/inode.rs @@ -1,30 +1,62 @@ use std::{ collections::BTreeMap, - sync::{atomic::AtomicU64, Arc}, + sync::atomic::{AtomicU64, Ordering}, }; use spin::RwLock; -use tokio::io::{AsyncRead, AsyncSeek}; -use crate::{filesystem::overlay::ArcEntry, semaphore::Semaphore}; +const MAX_INODE: u64 = 1 << 63; -pub struct INodeTable -where - F: AsyncRead + AsyncSeek + Unpin + 'static, -{ - semaphore: Arc, - table: RwLock>>, - handle_generator: AtomicU64, +pub trait Identified { + fn get_id(&self) -> usize; } -impl INodeTable -where - F: AsyncRead + AsyncSeek + Unpin + 'static, -{ - pub async fn new_inode(&self, entry: ArcEntry) { - let handle = self - .handle_generator +pub struct INodeTable { + inode: RwLock>, + id: RwLock>, + inode_generator: AtomicU64, +} + +impl INodeTable { + pub fn new() -> Self { + Self { + inode: RwLock::new(BTreeMap::new()), + id: RwLock::new(BTreeMap::new()), + inode_generator: AtomicU64::new(1), + } + } + pub fn allocate(&self, mut f: F) -> E + where + F: FnMut(u64) -> E, + { + let inode = self + .inode_generator .fetch_add(1, std::sync::atomic::Ordering::AcqRel); - self.table.write().insert(handle, entry); + let entry = f(inode); + match { self.id.read().get(&entry.get_id()) } { + Some(&x) => f(x), + None => { + self.inode.write().insert(inode, entry.clone()); + entry + } + } + } + /// get entry by inode + pub fn get(&self, inode: u64) -> Option { + self.inode.read().get(&inode).cloned() + } + /// deallocate inode + pub fn remove(&self, inode: u64) { + // FIXME: inode should be reused + if let Some(e) = { self.inode.write().remove(&inode) } { + self.id.write().remove(&e.get_id()); + } + } + pub fn get_free_inode(&self) -> u64 { + MAX_INODE - self.get_used_inode() + } + #[inline] + pub fn get_used_inode(&self) -> u64 { + self.inode_generator.load(Ordering::Acquire) } } diff --git a/judger/src/filesystem/table/mod.rs b/judger/src/filesystem/table/mod.rs index 4a8cd64..397faa9 100644 --- a/judger/src/filesystem/table/mod.rs +++ b/judger/src/filesystem/table/mod.rs @@ -2,4 +2,4 @@ mod handle; mod inode; pub use handle::HandleTable; -pub use inode::INodeTable; +pub use inode::{INodeTable, Identified};