diff --git a/scorpio/src/dicfuse/async_io.rs b/scorpio/src/dicfuse/async_io.rs index 5943a905..babd9dab 100644 --- a/scorpio/src/dicfuse/async_io.rs +++ b/scorpio/src/dicfuse/async_io.rs @@ -12,8 +12,6 @@ use mercury::internal::object::tree::TreeItemMode; use std::vec::IntoIter; -use crate::dicfuse::store::IntoEntry; - use super::Dicfuse; use crate::manager::fetch::fetch_tree; use crate::util::GPath;use reqwest::Client; @@ -37,7 +35,8 @@ impl Filesystem for Dicfuse { //let pitem = store.get_inode(parent).await?; ppath.push(name.to_string_lossy().into_owned()); let chil = store.get_by_path(&ppath.to_string()).await?; - Ok(chil.into_reply().await) + let re = self.get_stat(chil).await; + Ok(re) } /// initialize filesystem. Called before any other filesystem method. async fn init(&self, _req: Request) -> Result{ @@ -68,11 +67,7 @@ impl Filesystem for Dicfuse { let store = self.store.clone(); let _i = store.find_path(inode).await.ok_or_else(|| std::io::Error::from_raw_os_error(libc::ENODATA))?; let item = store.get_inode(inode).await?; - let mut e =item.get_stat().await; - let rl = self.open_buff.read().await; - if let Some(datas) = rl.get(&inode){ - e.attr.size = datas.len() as u64; - } + let e =self.get_stat(item).await; Ok(ReplyAttr { ttl: e.ttl, attr: e.attr }) } /// open a directory. Filesystem may store an arbitrary file handle (pointer, index, etc) in @@ -188,6 +183,8 @@ impl Filesystem for Dicfuse { let parent_item = self.store.get_inode(parent).await?; let tree = fetch_tree(&GPath::from(parent_item.get_path())).await.unwrap(); + + let mut is_first = true; let client = Client::new(); for i in tree.tree_items{ @@ -207,6 +204,18 @@ impl Filesystem for Dicfuse { let data: Vec = content.to_vec(); let child_osstr = OsStr::new(&i.name); let i_inode = self.lookup(req, parent,child_osstr).await?; + if is_first{ + match self.open_buff.write().await.get(&i_inode.attr.ino) { + Some(_) => { + break; + // is loaded , no need to reload ; + }, + None => { + // this dictionary is not loaded , just go ahead. + is_first = false; + }, + } + } self.open_buff.write().await.insert(i_inode.attr.ino, data); } else { @@ -216,7 +225,7 @@ impl Filesystem for Dicfuse { } for (index,item) in items.into_iter().enumerate(){ if index as u64 >= offset { - let attr = item.get_stat().await; + let attr = self.get_stat(item.clone()).await; let e_name = if index ==0{ String::from(".") diff --git a/scorpio/src/dicfuse/mod.rs b/scorpio/src/dicfuse/mod.rs index e0891edf..bb7255c7 100644 --- a/scorpio/src/dicfuse/mod.rs +++ b/scorpio/src/dicfuse/mod.rs @@ -5,7 +5,8 @@ mod tree_store; use std::{collections::HashMap,sync::Arc}; -use store::DictionaryStore; +use fuse3::raw::reply::ReplyEntry; +use store::{DicItem, DictionaryStore}; pub struct Dicfuse{ pub store: Arc, open_buff: Arc>>>, @@ -18,6 +19,14 @@ impl Dicfuse{ open_buff: Arc::new(tokio::sync::RwLock::new(HashMap::new())), } } + pub async fn get_stat(&self,item:Arc) -> ReplyEntry { + let mut e =item.get_stat().await; + let rl = self.open_buff.read().await; + if let Some(datas) = rl.get(&item.get_inode()){ + e.attr.size = datas.len() as u64; + } + e + } // pub async fn pull_fiel(&self,parent_inode:u64)->Result<()>{ // let parent_item = self.store.get_inode(parent_inode).await?; // let tree = fetch_tree(&GPath::from(parent_item.get_path())).await.unwrap(); diff --git a/scorpio/src/dicfuse/store.rs b/scorpio/src/dicfuse/store.rs index 99386f0d..f8513c63 100644 --- a/scorpio/src/dicfuse/store.rs +++ b/scorpio/src/dicfuse/store.rs @@ -1,6 +1,6 @@ -use fuse3::raw::reply::{FileAttr, ReplyEntry}; -use fuse3::{FileType, Timestamp}; +use fuse3::raw::reply::ReplyEntry; +use fuse3::FileType; /// Read only file system for obtaining and displaying monorepo directory information use reqwest::Client; @@ -10,7 +10,7 @@ use tokio::sync::Mutex; use std::io; -use std::time::Duration; + use std::{collections::HashMap, error::Error}; use std::collections::VecDeque; use once_cell::sync::Lazy; @@ -104,39 +104,6 @@ impl DicItem { } } -pub trait IntoEntry { - // async fn into_entry(self) -> Entry; - async fn into_reply(self) -> ReplyEntry; -} - -impl IntoEntry for Arc { - async fn into_reply(self) -> ReplyEntry { - ReplyEntry{ - ttl: Duration::new(500, 0), - attr: FileAttr{ - ino: self.get_inode(), - size: 0, - blocks: 0, - atime: Timestamp::new(0, 0), - mtime: Timestamp::new(0, 0), - ctime: Timestamp::new(0, 0), - kind: { - match *self.content_type.lock().await { - ContentType::File => FileType::RegularFile, - ContentType::Dictionary(_) => FileType::Directory, - } - }, - perm: 0o755, - nlink: 0, - uid: 0, - gid: 0, - rdev: 0, - blksize: 0, - }, - generation: 0, - } - } -} #[derive(Serialize, Deserialize, Debug,Default,Clone)] struct ApiResponse {