Skip to content

Commit

Permalink
feat(Judger): ✨ finish inode and file handle table
Browse files Browse the repository at this point in the history
  • Loading branch information
Eason0729 committed May 2, 2024
1 parent a2d8904 commit 6abdd30
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 34 deletions.
27 changes: 12 additions & 15 deletions judger/src/filesystem/table/handle.rs
Original file line number Diff line number Diff line change
@@ -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<F>
where
F: AsyncRead + AsyncSeek + Unpin + 'static,
{
pub struct HandleTable<E: Clone> {
handle_generator: AtomicU64,
table: RwLock<BTreeMap<u64, ArcEntry<F>>>,
table: RwLock<BTreeMap<u64, E>>,
}

impl<F> HandleTable<F>
where
F: AsyncRead + AsyncSeek + Unpin + 'static,
{
pub fn new_handle(&self, entry: ArcEntry<F>) -> u64 {
impl<E: Clone> HandleTable<E> {
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<ArcEntry<F>> {
pub fn get(&self, handle: u64) -> Option<E> {
self.table.read().get(&handle).cloned()
}
pub fn remove_entry(&self, handle: u64) -> Option<ArcEntry<F>> {
pub fn remove(&self, handle: u64) -> Option<E> {
self.table.write().remove(&handle)
}
}
68 changes: 50 additions & 18 deletions judger/src/filesystem/table/inode.rs
Original file line number Diff line number Diff line change
@@ -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<F>
where
F: AsyncRead + AsyncSeek + Unpin + 'static,
{
semaphore: Arc<Semaphore>,
table: RwLock<BTreeMap<u64, ArcEntry<F>>>,
handle_generator: AtomicU64,
pub trait Identified {
fn get_id(&self) -> usize;
}

impl<F> INodeTable<F>
where
F: AsyncRead + AsyncSeek + Unpin + 'static,
{
pub async fn new_inode(&self, entry: ArcEntry<F>) {
let handle = self
.handle_generator
pub struct INodeTable<E: Clone + Identified> {
inode: RwLock<BTreeMap<u64, E>>,
id: RwLock<BTreeMap<usize, u64>>,
inode_generator: AtomicU64,
}

impl<E: Clone + Identified> INodeTable<E> {
pub fn new() -> Self {
Self {
inode: RwLock::new(BTreeMap::new()),
id: RwLock::new(BTreeMap::new()),
inode_generator: AtomicU64::new(1),
}
}
pub fn allocate<F>(&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<E> {
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)
}
}
2 changes: 1 addition & 1 deletion judger/src/filesystem/table/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ mod handle;
mod inode;

pub use handle::HandleTable;
pub use inode::INodeTable;
pub use inode::{INodeTable, Identified};

0 comments on commit 6abdd30

Please sign in to comment.