summaryrefslogtreecommitdiff
path: root/src/memory/cached_block.rs
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-11-30 02:15:06 -0800
committerChuyan Zhang <me@zcy.moe>2023-11-30 02:15:06 -0800
commit1eac97eea4ec0bcef0be061a2cba93a584355283 (patch)
treed98fb1f6e3811286a0733c9df21e467590635ad2 /src/memory/cached_block.rs
parentb3db8a5a710aa0890c80241ffb3fd9792bf1cbe7 (diff)
downloadmyfs-1eac97eea4ec0bcef0be061a2cba93a584355283.tar.gz
myfs-1eac97eea4ec0bcef0be061a2cba93a584355283.zip
Add real disk i/o, add mkfs.aya (not yet implemented)
Diffstat (limited to 'src/memory/cached_block.rs')
-rw-r--r--src/memory/cached_block.rs180
1 files changed, 0 insertions, 180 deletions
diff --git a/src/memory/cached_block.rs b/src/memory/cached_block.rs
deleted file mode 100644
index c3d0338..0000000
--- a/src/memory/cached_block.rs
+++ /dev/null
@@ -1,180 +0,0 @@
-use crate::block_device::{BlockDevice, BLOCK_SIZE};
-use crate::disk::block::Block;
-use crate::AyaFS;
-use lru::LruCache;
-use std::num::NonZeroUsize;
-use std::sync::Arc;
-
-#[derive(Clone)]
-pub struct CachedBlock<T: Block> {
- pub block: T,
- pub index: usize,
- pub dirty: bool,
-}
-
-pub fn convert_mut<U: Block, T: Block>(input_block: &mut CachedBlock<U>) -> &mut CachedBlock<T> {
- let ptr = input_block as *const CachedBlock<U> as *mut u8;
- let block = ptr.cast::<CachedBlock<T>>();
- unsafe { &mut *block }
-}
-
-pub fn convert<U: Block, T: Block>(input_block: &CachedBlock<U>) -> &CachedBlock<T> {
- let ptr = input_block as *const CachedBlock<U> as *mut u8;
- let block = ptr.cast::<CachedBlock<T>>();
- unsafe { &*block }
-}
-
-pub(crate) struct BlockCache<T: Block> {
- device: Arc<dyn BlockDevice>,
- cache: LruCache<usize, CachedBlock<T>>,
-}
-
-impl<T: Block> BlockCache<T> {
- pub(crate) fn new(device: Arc<dyn BlockDevice>, cache_size: usize) -> Self {
- Self {
- device,
- cache: LruCache::new(NonZeroUsize::new(cache_size).unwrap()),
- }
- }
-
- pub(crate) fn load_block(&mut self, index: usize) -> bool {
- if self.cache.contains(&index) == false {
- let mut buffer = [0u8; BLOCK_SIZE];
- self.device.read(index, &mut buffer);
- let block: T = unsafe { std::mem::transmute_copy(&buffer) };
- let cached_block = CachedBlock {
- block,
- index,
- dirty: false,
- };
- if let Some((old_index, old_block)) = self.cache.push(index, cached_block) {
- assert_ne!(old_index, index); // 只有 block 不在 cache 里的时候才会插入
- if old_block.dirty {
- let old_block_ptr = &old_block.block as *const T as *mut u8;
- let old_block_buffer =
- unsafe { std::slice::from_raw_parts(old_block_ptr, BLOCK_SIZE) };
- self.device.write(old_index, old_block_buffer);
- }
- }
- }
- true
- }
-
- /// 从 LRU cache 里获取一个 block 的引用, 如果没有在 cache 中会加载.
- /// 这个函数不应该返回 None
- pub(crate) fn get_block<U: Block>(&mut self, index: usize) -> Option<&CachedBlock<U>> {
- if !self.cache.contains(&index) {
- self.load_block(index);
- }
- self.cache.get(&index).map(convert::<T, U>)
- }
-
- /// 从 LRU cache 里获取一个 block 的可变引用, 如果没有在 cache 中会加载.
- /// 这个函数不应该返回 None
- pub(crate) fn get_block_mut<U: Block>(&mut self, index: usize) -> Option<&mut CachedBlock<U>> {
- if !self.cache.contains(&index) {
- self.load_block(index);
- }
- self.cache.get_mut(&index).map(|block| {
- block.dirty = true;
- convert_mut::<T, U>(block)
- })
- }
-
- /// 向 LRU cache 中插入一个全新初始化的 block
- /// 这个 block 全 0, 而且是 dirty 的, 即使被挤出去也会触发一次落盘
- pub(crate) fn init_block(&mut self, index: usize) {
- let allocated_block = CachedBlock {
- block: T::default(),
- index,
- dirty: true,
- };
- if let Some((old_index, old_block)) = self.cache.push(index, allocated_block) {
- if old_block.dirty {
- let old_block_ptr = &old_block.block as *const T as *mut u8;
- let old_block_buffer =
- unsafe { std::slice::from_raw_parts(old_block_ptr, BLOCK_SIZE) };
- self.device.write(old_index, old_block_buffer);
- }
- }
- }
-
- #[allow(unused)]
- /// 从 LRU cache 中读取一个 block 的引用, *不会* 影响 LRU cache 的结构, 如果没有在 cache 中不会加载.
- pub(crate) fn peek_block<U: Block>(&self, index: usize) -> Option<&CachedBlock<U>> {
- self.cache.peek(&index).map(convert::<T, U>)
- }
-
- #[allow(unused)]
- /// 从 LRU cache 中读取一个 block 的可变引用, *不会* 影响 LRU cache 的结构, 如果没有在 cache 中不会加载.
- pub(crate) fn peek_block_mut<U: Block>(&mut self, index: usize) -> Option<&mut CachedBlock<U>> {
- self.cache.peek_mut(&index).map(convert_mut::<T, U>)
- }
-
- pub(crate) fn update_block<U: Block>(&mut self, block: CachedBlock<U>) -> bool {
- if self.cache.contains(&block.index) {
- let mut data_block = convert::<U, T>(&block).clone();
- data_block.dirty = true; // TODO 需要把显式写回的都标记为 dirty 吗
- self.cache.push(block.index, data_block);
- true
- } else {
- false
- }
- }
-
- fn pop(&mut self, entry: &usize) -> Option<CachedBlock<T>> {
- self.cache.pop(entry)
- }
-}
-
-impl AyaFS {
- pub(crate) fn init_block(&mut self, index: usize) {
- self.cached_blocks.init_block(index);
- }
-
- pub(crate) fn get_block<T: Block>(&mut self, index: usize) -> Option<&CachedBlock<T>> {
- if self.data_bitmap.query(index) {
- Some(self.cached_blocks.get_block::<T>(index).unwrap())
- } else {
- self.cached_blocks.pop(&index);
- None
- }
- // self.data_bitmap
- // .query(index)
- // .then(|| self.cached_blocks.get_block::<T>(index).unwrap())
- // 返回 None 当且仅当 data_bitmap 中这个 block 为 invalid
- }
-
- pub(crate) fn get_block_mut<T: Block>(&mut self, index: usize) -> Option<&mut CachedBlock<T>> {
- if self.data_bitmap.query(index) {
- Some(self.cached_blocks.get_block_mut::<T>(index).unwrap())
- } else {
- self.cached_blocks.pop(&index);
- None
- }
- // self.data_bitmap
- // .query(index)
- // .then(|| self.cached_blocks.get_block_mut::<T>(index).unwrap())
- // 返回 None 当且仅当 data_bitmap 中这个 block 为 invalid
- }
-
- #[allow(unused)]
- pub(crate) fn peek_block<T: Block>(&self, index: usize) -> Option<&CachedBlock<T>> {
- self.data_bitmap
- .query(index)
- .then(|| self.cached_blocks.peek_block::<T>(index).unwrap())
- // 返回 None 当且仅当 data_bitmap 中这个 block 为 invalid
- }
-
- #[allow(unused)]
- pub(crate) fn peek_block_mut<T: Block>(&mut self, index: usize) -> Option<&mut CachedBlock<T>> {
- self.data_bitmap
- .query(index)
- .then(|| self.cached_blocks.peek_block_mut::<T>(index).unwrap())
- // 返回 None 当且仅当 data_bitmap 中这个 block 为 invalid
- }
-
- pub(crate) fn update_block<T: Block>(&mut self, block: CachedBlock<T>) -> bool {
- self.cached_blocks.update_block(block)
- }
-}