cargo fmt for async-fat32

This commit is contained in:
SKTT1Ryze 2021-07-16 12:48:06 +08:00
parent 3baa556e34
commit 8ae2d0c4c3
5 changed files with 50 additions and 41 deletions

View File

@ -1,48 +1,51 @@
//! 块缓冲层实现
use core::mem::MaybeUninit;
use alloc::sync::Arc;
use spin::Mutex;
use crate::AsyncBlockDevive;
use super::cache::{Cache, Node, LFUCache};
use super::cache::{Cache, LFUCache, Node};
use super::config::*;
use crate::AsyncBlockDevive;
use alloc::sync::Arc;
use core::mem::MaybeUninit;
use spin::Mutex;
// B: 一个块中的字节数
// N: 块缓冲层的块数
pub struct BlockCache<C: Cache<N, Key = usize, Value = [u8; B]>, const B: usize, const N: usize> {
block_device: Arc<dyn AsyncBlockDevive + Send + Sync>,
cache: Mutex<C>
cache: Mutex<C>,
}
impl BlockCache<LFUCache<usize, [u8; BLOCK_SIZE], CACHE_SIZE>, BLOCK_SIZE, CACHE_SIZE> {
pub fn init(device: Arc<dyn AsyncBlockDevive + Send + Sync>) -> Self {
let mut data: [MaybeUninit<Node<usize, [u8; BLOCK_SIZE]>>; CACHE_SIZE] = unsafe {
MaybeUninit::uninit().assume_init()
};
let mut data: [MaybeUninit<Node<usize, [u8; BLOCK_SIZE]>>; CACHE_SIZE] =
unsafe { MaybeUninit::uninit().assume_init() };
for elem in &mut data[..] {
*elem = MaybeUninit::new(Node::new(0, [0; BLOCK_SIZE]));
}
let nodes = unsafe { core::mem::transmute::<_, [Node<usize, [u8; BLOCK_SIZE]>; CACHE_SIZE]>(data) };
let nodes =
unsafe { core::mem::transmute::<_, [Node<usize, [u8; BLOCK_SIZE]>; CACHE_SIZE]>(data) };
let lfu_cache = LFUCache::empty(nodes);
Self {
block_device: device,
cache: Mutex::new(lfu_cache)
cache: Mutex::new(lfu_cache),
}
}
pub async fn read_block(&self, block_id: usize) -> [u8; BLOCK_SIZE] {
{ // 申请锁
{
// 申请锁
let mut s = self.cache.lock();
if let Some(block) = s.get(&block_id) { // 如果想要读取的块在缓冲层中,则读出来直接返回,不用读写块设备
if let Some(block) = s.get(&block_id) {
// 如果想要读取的块在缓冲层中,则读出来直接返回,不用读写块设备
return block;
}
} // 释放锁
// 如果要读取的块不在缓冲层中,则需要从块设备读取
// 如果要读取的块不在缓冲层中,则需要从块设备读取
let mut data = [0; BLOCK_SIZE];
self.block_device.read(block_id, &mut data).await;
// 将读取到的块写入到缓冲层
let mut s = self.cache.lock(); // 申请锁
let write_back = s.put(&block_id, data.clone());
drop(s); // 释放锁
if let Some((id, mut block)) = write_back { // 如果有需要写回到块设备的数据,这里写回
if let Some((id, mut block)) = write_back {
// 如果有需要写回到块设备的数据,这里写回
self.block_device.write(id, &mut block).await;
}
data
@ -73,4 +76,4 @@ impl BlockCache<LFUCache<usize, [u8; BLOCK_SIZE], CACHE_SIZE>, BLOCK_SIZE, CACHE
// lazy_static::lazy_static! {
// pub static ref AsyncBlockCache: BlockCache<LFUCache<usize, [u8; BLOCK_SIZE], CACHE_SIZE>, BLOCK_SIZE, CACHE_SIZE> = BlockCache::init(Arc::new(TestDevice::default()));
// }
// }

View File

@ -17,7 +17,7 @@ enum BootSectorOffset {
/// Volume label
VolLab = 71,
/// One of the strings "FAT12", "FAT16", "FAT32"
FilSysType = 82
FilSysType = 82,
}
/// BPB 各字段的偏移
@ -64,5 +64,5 @@ enum BPBOffset {
/// ignored
BkBootSec = 50,
/// Reserved
Reserved = 52
}
Reserved = 52,
}

View File

@ -19,7 +19,7 @@ pub struct Node<K: Eq + PartialEq + Copy, V: Clone> {
value: V,
cnt: usize,
time: usize,
dirty: bool
dirty: bool,
}
impl<K: Eq + PartialEq + Copy, V: Clone> Node<K, V> {
@ -29,7 +29,7 @@ impl<K: Eq + PartialEq + Copy, V: Clone> Node<K, V> {
value,
cnt: 0,
time: 0,
dirty: false
dirty: false,
}
}
}
@ -44,7 +44,9 @@ impl<K: Eq + PartialEq + Copy, V: Clone> Eq for Node<K, V> {}
impl<K: Eq + PartialEq + Copy, V: Clone> Ord for Node<K, V> {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.cnt.cmp(&other.cnt).then_with(|| self.time.cmp(&other.time))
self.cnt
.cmp(&other.cnt)
.then_with(|| self.time.cmp(&other.time))
}
}
@ -58,7 +60,7 @@ impl<K: Eq + PartialEq + Copy, V: Clone> PartialOrd for Node<K, V> {
pub struct LFUCache<K: Eq + PartialEq + Copy, V: Clone, const N: usize> {
data: [Node<K, V>; N],
size: usize,
time: usize
time: usize,
}
impl<K: Eq + PartialEq + Copy, V: Clone, const N: usize> LFUCache<K, V, N> {
@ -66,7 +68,7 @@ impl<K: Eq + PartialEq + Copy, V: Clone, const N: usize> LFUCache<K, V, N> {
Self {
data,
size: N,
time: 0
time: 0,
}
}
// todo: 用 `maybuninit`
@ -74,7 +76,7 @@ impl<K: Eq + PartialEq + Copy, V: Clone, const N: usize> LFUCache<K, V, N> {
Self {
data,
size: 0,
time: 0
time: 0,
}
}
}
@ -85,12 +87,15 @@ impl<K: Eq + PartialEq + Copy, V: Clone, const N: usize> Cache<N> for LFUCache<K
fn get(&mut self, key: &Self::Key) -> Option<Self::Value> {
self.time += 1;
let time = self.time;
self.data[0..self.size].iter_mut().find(|i| i.key == *key).map(|node| {
// 更新结点时间和访问次数
node.time = time;
node.cnt += 1;
node.value.clone()
})
self.data[0..self.size]
.iter_mut()
.find(|i| i.key == *key)
.map(|node| {
// 更新结点时间和访问次数
node.time = time;
node.cnt += 1;
node.value.clone()
})
}
fn put(&mut self, key: &Self::Key, value: Self::Value) -> Option<(Self::Key, Self::Value)> {
self.time += 1;
@ -99,17 +104,19 @@ impl<K: Eq + PartialEq + Copy, V: Clone, const N: usize> Cache<N> for LFUCache<K
node.cnt += 1;
node.time = self.time;
// 写脏
node.dirty = true;
node.dirty = true;
return None;
} else {
if self.size < N { // 缓存未满
if self.size < N {
// 缓存未满
self.data[self.size].key = *key;
self.data[self.size].value = value;
self.data[self.size].cnt = 1;
self.data[self.size].time = self.time;
self.size += 1;
return None;
} else { // 缓存已满
} else {
// 缓存已满
// 顺序排序
self.data[0..self.size].sort_by(|a, b| a.cmp(b));
// 淘汰第一项
@ -122,19 +129,18 @@ impl<K: Eq + PartialEq + Copy, V: Clone, const N: usize> Cache<N> for LFUCache<K
// 如果数据已经被写脏,现在需要写回
match node.dirty {
true => Some(write_back),
false => None
false => None,
}
}
}
}
}
#[test]
fn lfu_cache_test() {
let nodes = [Node::new(0, 0); 2];
let mut lfu_cache = LFUCache::empty(nodes);
assert!(lfu_cache.get(&0).is_none());
assert!(lfu_cache.get(&1).is_none());
assert!(lfu_cache.get(&2).is_none());
@ -150,4 +156,4 @@ fn lfu_cache_test() {
assert_eq!(lfu_cache.get(&1), None);
assert_eq!(lfu_cache.get(&3), Some(3));
assert_eq!(lfu_cache.get(&4), Some(4));
}
}

View File

@ -1,2 +1,2 @@
pub const BLOCK_SIZE: usize = 512;
pub const CACHE_SIZE: usize = 100;
pub const CACHE_SIZE: usize = 100;

View File

@ -1,8 +1,8 @@
//! Async FAT32 File System Implemetation
mod block_cache;
mod bs_bpb;
mod cache;
mod block_cache;
mod config;
extern crate alloc;
@ -13,4 +13,4 @@ use async_trait::async_trait;
pub trait AsyncBlockDevive {
async fn read(&self, block_id: usize, buf: &mut [u8]);
async fn write(&self, block_id: usize, buf: &[u8]);
}
}