diff options
Diffstat (limited to 'src/memory/cached_block.rs')
-rw-r--r-- | src/memory/cached_block.rs | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/src/memory/cached_block.rs b/src/memory/cached_block.rs index 783e987..002a75b 100644 --- a/src/memory/cached_block.rs +++ b/src/memory/cached_block.rs @@ -75,7 +75,7 @@ impl<T: Block> BlockCache<T> { if !self.cache.contains(&index) { self.load_block(index); } - self.cache.get(&index).map(convert::<T,U>) + self.cache.get(&index).map(convert::<T, U>) } /// 从 LRU cache 里获取一个 block 的可变引用, 如果没有在 cache 中会加载. @@ -90,6 +90,24 @@ impl<T: Block> BlockCache<T> { }) } + /// 向 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); + } + } + } + /// 从 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>) @@ -117,26 +135,33 @@ impl<T: Block> BlockCache<T> { } impl AyaFS { - pub(crate) fn load_block(&mut self, index: usize) -> bool { - if !self.data_bitmap.query(index) { - self.cached_blocks.pop(&index); - // deallocate 时只更新 bitmap 没有动 cache, lazy 地驱逐 cache 中的无效 entry. - return false; - } - self.cached_blocks.load_block(index) + 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>> { - self.data_bitmap - .query(index) - .then(|| self.cached_blocks.get_block::<T>(index).unwrap()) + 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>> { - self.data_bitmap - .query(index) - .then(|| self.cached_blocks.get_block_mut::<T>(index).unwrap()) + 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 } |