mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 09:53:24 +00:00
Rename DirEntryVec to SlotVec
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
0fc707d38c
commit
0abe40e0f8
@ -2,9 +2,10 @@ use alloc::string::String;
|
||||
use core::any::Any;
|
||||
use core::time::Duration;
|
||||
use jinux_frame::vm::VmFrame;
|
||||
use jinux_util::slot_vec::SlotVec;
|
||||
|
||||
use crate::fs::utils::{
|
||||
DirEntryVec, DirentVisitor, FileSystem, Inode, InodeMode, InodeType, IoctlCmd, Metadata,
|
||||
DirentVisitor, FileSystem, Inode, InodeMode, InodeType, IoctlCmd, Metadata,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
|
||||
@ -14,7 +15,7 @@ pub struct ProcDir<D: DirOps> {
|
||||
inner: D,
|
||||
this: Weak<ProcDir<D>>,
|
||||
parent: Option<Weak<dyn Inode>>,
|
||||
cached_children: RwLock<DirEntryVec<(String, Arc<dyn Inode>)>>,
|
||||
cached_children: RwLock<SlotVec<(String, Arc<dyn Inode>)>>,
|
||||
info: ProcInodeInfo,
|
||||
}
|
||||
|
||||
@ -38,7 +39,7 @@ impl<D: DirOps> ProcDir<D> {
|
||||
inner: dir,
|
||||
this: weak_self.clone(),
|
||||
parent,
|
||||
cached_children: RwLock::new(DirEntryVec::new()),
|
||||
cached_children: RwLock::new(SlotVec::new()),
|
||||
info,
|
||||
})
|
||||
}
|
||||
@ -51,7 +52,7 @@ impl<D: DirOps> ProcDir<D> {
|
||||
self.parent.as_ref().and_then(|p| p.upgrade())
|
||||
}
|
||||
|
||||
pub fn cached_children(&self) -> &RwLock<DirEntryVec<(String, Arc<dyn Inode>)>> {
|
||||
pub fn cached_children(&self) -> &RwLock<SlotVec<(String, Arc<dyn Inode>)>> {
|
||||
&self.cached_children
|
||||
}
|
||||
}
|
||||
@ -127,7 +128,7 @@ impl<D: DirOps + 'static> Inode for ProcDir<D> {
|
||||
self.inner.populate_children(self.this.clone());
|
||||
let cached_children = self.cached_children.read();
|
||||
for (idx, (name, child)) in cached_children
|
||||
.idxes_and_entries()
|
||||
.idxes_and_items()
|
||||
.map(|(idx, (name, child))| (idx + 2, (name, child)))
|
||||
{
|
||||
if idx < *offset {
|
||||
|
@ -5,12 +5,12 @@ use core::any::Any;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use core::time::Duration;
|
||||
use jinux_frame::vm::VmFrame;
|
||||
use jinux_util::slot_vec::SlotVec;
|
||||
use spin::{RwLock, RwLockWriteGuard};
|
||||
|
||||
use super::*;
|
||||
use crate::fs::utils::{
|
||||
DirEntryVec, DirentVisitor, FileSystem, FsFlags, Inode, InodeMode, InodeType, IoctlCmd,
|
||||
Metadata, SuperBlock,
|
||||
DirentVisitor, FileSystem, FsFlags, Inode, InodeMode, InodeType, IoctlCmd, Metadata, SuperBlock,
|
||||
};
|
||||
|
||||
pub struct RamFS {
|
||||
@ -164,7 +164,7 @@ impl Inner {
|
||||
}
|
||||
|
||||
struct DirEntry {
|
||||
children: DirEntryVec<(Str256, Arc<RamInode>)>,
|
||||
children: SlotVec<(Str256, Arc<RamInode>)>,
|
||||
this: Weak<RamInode>,
|
||||
parent: Weak<RamInode>,
|
||||
}
|
||||
@ -172,7 +172,7 @@ struct DirEntry {
|
||||
impl DirEntry {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
children: DirEntryVec::new(),
|
||||
children: SlotVec::new(),
|
||||
this: Weak::default(),
|
||||
parent: Weak::default(),
|
||||
}
|
||||
@ -205,13 +205,13 @@ impl DirEntry {
|
||||
Some((1, self.parent.upgrade().unwrap()))
|
||||
} else {
|
||||
self.children
|
||||
.idxes_and_entries()
|
||||
.idxes_and_items()
|
||||
.find(|(_, (child, _))| child == &Str256::from(name))
|
||||
.map(|(idx, (_, inode))| (idx + 2, inode.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
fn append_entry(&mut self, name: &str, inode: Arc<RamInode>) {
|
||||
fn append_entry(&mut self, name: &str, inode: Arc<RamInode>) -> usize {
|
||||
self.children.put((Str256::from(name), inode))
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ impl DirEntry {
|
||||
// Read the normal child entries.
|
||||
for (offset, (name, child)) in self
|
||||
.children
|
||||
.idxes_and_entries()
|
||||
.idxes_and_items()
|
||||
.map(|(offset, (name, child))| (offset + 2, (name, child)))
|
||||
{
|
||||
if offset < *idx {
|
||||
|
@ -1,87 +1,7 @@
|
||||
use super::Inode;
|
||||
use crate::prelude::*;
|
||||
|
||||
/// DirEntryVec is used to store the entries of a directory.
|
||||
/// It can guarantee that the index of one dir entry remains unchanged during
|
||||
/// adding or deleting other dir entries of it.
|
||||
pub struct DirEntryVec<T> {
|
||||
// The slots to store dir entries.
|
||||
slots: Vec<Option<T>>,
|
||||
// The number of occupied slots.
|
||||
// The i-th slot is occupied if `self.slots[i].is_some()`.
|
||||
num_occupied: usize,
|
||||
}
|
||||
|
||||
impl<T> DirEntryVec<T> {
|
||||
/// New an empty vec.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
slots: Vec::new(),
|
||||
num_occupied: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the vec contains no entries.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_occupied == 0
|
||||
}
|
||||
|
||||
/// Put a dir entry into the vec.
|
||||
/// it may be put into an existing empty slot or the back of the vec.
|
||||
pub fn put(&mut self, entry: T) {
|
||||
if self.num_occupied == self.slots.len() {
|
||||
self.slots.push(Some(entry));
|
||||
} else {
|
||||
let idx = self.slots.iter().position(|x| x.is_none()).unwrap();
|
||||
self.slots[idx] = Some(entry);
|
||||
}
|
||||
self.num_occupied += 1;
|
||||
}
|
||||
|
||||
/// Removes and returns the entry at position `idx`.
|
||||
/// Returns `None` if `idx` is out of bounds or the entry has been removed.
|
||||
pub fn remove(&mut self, idx: usize) -> Option<T> {
|
||||
if idx >= self.slots.len() {
|
||||
return None;
|
||||
}
|
||||
let mut del_entry = None;
|
||||
core::mem::swap(&mut del_entry, &mut self.slots[idx]);
|
||||
if del_entry.is_some() {
|
||||
debug_assert!(self.num_occupied > 0);
|
||||
self.num_occupied -= 1;
|
||||
}
|
||||
del_entry
|
||||
}
|
||||
|
||||
/// Put and returns the entry at position `idx`.
|
||||
/// Returns `None` if `idx` is out of bounds or the entry has been removed.
|
||||
pub fn put_at(&mut self, idx: usize, entry: T) -> Option<T> {
|
||||
if idx >= self.slots.len() {
|
||||
return None;
|
||||
}
|
||||
let mut sub_entry = Some(entry);
|
||||
core::mem::swap(&mut sub_entry, &mut self.slots[idx]);
|
||||
if sub_entry.is_none() {
|
||||
self.num_occupied += 1;
|
||||
}
|
||||
sub_entry
|
||||
}
|
||||
|
||||
/// Creates an iterator which gives both of the index and the dir entry.
|
||||
/// The index may not be continuous.
|
||||
pub fn idxes_and_entries(&self) -> impl Iterator<Item = (usize, &'_ T)> {
|
||||
self.slots
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, x)| x.is_some())
|
||||
.map(|(idx, x)| (idx, x.as_ref().unwrap()))
|
||||
}
|
||||
|
||||
/// Creates an iterator which gives the dir entry.
|
||||
pub fn iter(&self) -> impl Iterator<Item = &'_ T> {
|
||||
self.slots.iter().filter_map(|x| x.as_ref())
|
||||
}
|
||||
}
|
||||
use jinux_util::slot_vec::SlotVec;
|
||||
|
||||
pub trait DirEntryVecExt {
|
||||
/// If the entry is not found by `name`, use `f` to get the inode, then put the entry into vec.
|
||||
@ -92,7 +12,7 @@ pub trait DirEntryVecExt {
|
||||
fn remove_entry_by_name(&mut self, name: &str) -> Option<(String, Arc<dyn Inode>)>;
|
||||
}
|
||||
|
||||
impl DirEntryVecExt for DirEntryVec<(String, Arc<dyn Inode>)> {
|
||||
impl DirEntryVecExt for SlotVec<(String, Arc<dyn Inode>)> {
|
||||
fn put_entry_if_not_found(&mut self, name: &str, f: impl Fn() -> Arc<dyn Inode>) {
|
||||
if self
|
||||
.iter()
|
||||
@ -106,7 +26,7 @@ impl DirEntryVecExt for DirEntryVec<(String, Arc<dyn Inode>)> {
|
||||
|
||||
fn remove_entry_by_name(&mut self, name: &str) -> Option<(String, Arc<dyn Inode>)> {
|
||||
let idx = self
|
||||
.idxes_and_entries()
|
||||
.idxes_and_items()
|
||||
.find(|(_, (child_name, _))| child_name == name)
|
||||
.map(|(idx, _)| idx);
|
||||
if let Some(idx) = idx {
|
||||
|
@ -5,7 +5,7 @@ pub use channel::{Channel, Consumer, Producer};
|
||||
pub use creation_flags::CreationFlags;
|
||||
pub use dentry_cache::Dentry;
|
||||
pub use dirent_visitor::DirentVisitor;
|
||||
pub use direntry_vec::{DirEntryVec, DirEntryVecExt};
|
||||
pub use direntry_vec::DirEntryVecExt;
|
||||
pub use fcntl::FcntlCmd;
|
||||
pub use file_creation_mask::FileCreationMask;
|
||||
pub use fs::{FileSystem, FsFlags, SuperBlock};
|
||||
|
Reference in New Issue
Block a user