From 2ae05a6163d8b15f3d8a18a2ab713d1fbd83c505 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 13:18:55 +0300 Subject: vfs crate scaffold --- crates/ra_vfs/Cargo.toml | 3 ++ crates/ra_vfs/src/io.rs | 117 +++++++++++++++++++++++------------------------ crates/ra_vfs/src/lib.rs | 25 ++++++++-- 3 files changed, 82 insertions(+), 63 deletions(-) (limited to 'crates/ra_vfs') diff --git a/crates/ra_vfs/Cargo.toml b/crates/ra_vfs/Cargo.toml index f8d49b3f5..9ce619a77 100644 --- a/crates/ra_vfs/Cargo.toml +++ b/crates/ra_vfs/Cargo.toml @@ -9,3 +9,6 @@ walkdir = "2.2.7" relative-path = "0.4.0" rustc-hash = "1.0" crossbeam-channel = "0.2.4" +log = "0.4.6" + +thread_worker = { path = "../thread_worker" } diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs index f90fe0e84..ce3271d48 100644 --- a/crates/ra_vfs/src/io.rs +++ b/crates/ra_vfs/src/io.rs @@ -6,67 +6,64 @@ use std::{ use walkdir::WalkDir; use crossbeam_channel::{Sender, Receiver}; +use thread_worker::{WorkerHandle, Worker}; -pub(crate) fn start_io() -> (JoinHandle<(), Sender<()>, Receiver()>) {} +#[derive(Debug)] +pub struct FileEvent { + pub path: PathBuf, + pub kind: FileEventKind, +} -// use crate::thread_watcher::{ThreadWatcher, Worker}; +#[derive(Debug)] +pub enum FileEventKind { + Add(String), +} -// #[derive(Debug)] -// pub struct FileEvent { -// pub path: PathBuf, -// pub kind: FileEventKind, -// } +pub fn start() -> (Worker)>, WorkerHandle) { + thread_worker::spawn::), _>( + "vfs", + 128, + |input_receiver, output_sender| { + input_receiver + .map(|path| { + log::debug!("loading {} ...", path.as_path().display()); + let events = load_root(path.as_path()); + log::debug!("... loaded {}", path.as_path().display()); + (path, events) + }) + .for_each(|it| output_sender.send(it)) + }, + ) +} -// #[derive(Debug)] -// pub enum FileEventKind { -// Add(String), -// } - -// pub fn roots_loader() -> (Worker)>, ThreadWatcher) { -// Worker::)>::spawn( -// "roots loader", -// 128, -// |input_receiver, output_sender| { -// input_receiver -// .map(|path| { -// log::debug!("loading {} ...", path.as_path().display()); -// let events = load_root(path.as_path()); -// log::debug!("... loaded {}", path.as_path().display()); -// (path, events) -// }) -// .for_each(|it| output_sender.send(it)) -// }, -// ) -// } - -// fn load_root(path: &Path) -> Vec { -// let mut res = Vec::new(); -// for entry in WalkDir::new(path) { -// let entry = match entry { -// Ok(entry) => entry, -// Err(e) => { -// log::warn!("watcher error: {}", e); -// continue; -// } -// }; -// if !entry.file_type().is_file() { -// continue; -// } -// let path = entry.path(); -// if path.extension().and_then(|os| os.to_str()) != Some("rs") { -// continue; -// } -// let text = match fs::read_to_string(path) { -// Ok(text) => text, -// Err(e) => { -// log::warn!("watcher error: {}", e); -// continue; -// } -// }; -// res.push(FileEvent { -// path: path.to_owned(), -// kind: FileEventKind::Add(text), -// }) -// } -// res -// } +fn load_root(path: &Path) -> Vec { + let mut res = Vec::new(); + for entry in WalkDir::new(path) { + let entry = match entry { + Ok(entry) => entry, + Err(e) => { + log::warn!("watcher error: {}", e); + continue; + } + }; + if !entry.file_type().is_file() { + continue; + } + let path = entry.path(); + if path.extension().and_then(|os| os.to_str()) != Some("rs") { + continue; + } + let text = match fs::read_to_string(path) { + Ok(text) => text, + Err(e) => { + log::warn!("watcher error: {}", e); + continue; + } + }; + res.push(FileEvent { + path: path.to_owned(), + kind: FileEventKind::Add(text), + }) + } + res +} diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 8f6abadb7..b80c12058 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -15,6 +15,7 @@ mod arena; mod io; use std::{ + thread, cmp::Reverse, path::{Path, PathBuf}, ffi::OsStr, @@ -22,7 +23,12 @@ use std::{ }; use relative_path::RelativePathBuf; -use crate::arena::{ArenaId, Arena}; +use thread_worker::{WorkerHandle, Worker}; + +use crate::{ + arena::{ArenaId, Arena}, + io::FileEvent, +}; /// `RootFilter` is a predicate that checks if a file can belong to a root struct RootFilter { @@ -76,16 +82,24 @@ struct VfsFileData { text: Arc, } -#[derive(Default)] struct Vfs { roots: Arena, files: Arena, // pending_changes: Vec, + worker: Worker)>, + worker_handle: WorkerHandle, } impl Vfs { pub fn new(mut roots: Vec) -> Vfs { - let mut res = Vfs::default(); + let (worker, worker_handle) = io::start(); + + let mut res = Vfs { + roots: Arena::default(), + files: Arena::default(), + worker, + worker_handle, + }; roots.sort_by_key(|it| Reverse(it.as_os_str().len())); @@ -104,6 +118,11 @@ impl Vfs { pub fn commit_changes(&mut self) -> Vec { unimplemented!() } + + pub fn shutdown(self) -> thread::Result<()> { + let _ = self.worker.shutdown(); + self.worker_handle.shutdown() + } } #[derive(Debug, Clone)] -- cgit v1.2.3