extract Roots struct

This commit is contained in:
Bernardo 2019-01-24 19:04:56 +01:00 committed by Aleksey Kladov
parent cfbf47b002
commit 86fadbd4e5

View File

@ -18,6 +18,7 @@ mod io;
use std::{ use std::{
cmp::Reverse, cmp::Reverse,
fmt, fs, mem, fmt, fs, mem,
ops::{Deref, DerefMut},
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::Arc, sync::Arc,
thread, thread,
@ -88,8 +89,38 @@ struct VfsFileData {
text: Arc<String>, text: Arc<String>,
} }
pub struct Vfs { pub(crate) struct Roots {
roots: Arena<VfsRoot, Arc<RootFilter>>, roots: Arena<VfsRoot, Arc<RootFilter>>,
}
impl Roots {
pub(crate) fn new() -> Roots {
Roots {
roots: Arena::default(),
}
}
pub(crate) fn find(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf)> {
self.roots
.iter()
.find_map(|(root, data)| data.can_contain(path).map(|it| (root, it)))
}
}
impl Deref for Roots {
type Target = Arena<VfsRoot, Arc<RootFilter>>;
fn deref(&self) -> &Self::Target {
&self.roots
}
}
impl DerefMut for Roots {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.roots
}
}
pub struct Vfs {
roots: Arc<Roots>,
files: Arena<VfsFile, VfsFileData>, files: Arena<VfsFile, VfsFileData>,
root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>, root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>,
pending_changes: Vec<VfsChange>, pending_changes: Vec<VfsChange>,
@ -103,26 +134,22 @@ impl fmt::Debug for Vfs {
} }
impl Vfs { impl Vfs {
pub fn new(mut roots: Vec<PathBuf>) -> (Vfs, Vec<VfsRoot>) { pub fn new(roots: Vec<PathBuf>) -> (Vfs, Vec<VfsRoot>) {
let mut root_paths = roots;
let worker = io::Worker::start(); let worker = io::Worker::start();
let mut res = Vfs { let mut roots = Roots::new();
roots: Arena::default(), let mut root2files = FxHashMap::default();
files: Arena::default(),
root2files: FxHashMap::default(),
worker,
pending_changes: Vec::new(),
};
// A hack to make nesting work. // A hack to make nesting work.
roots.sort_by_key(|it| Reverse(it.as_os_str().len())); root_paths.sort_by_key(|it| Reverse(it.as_os_str().len()));
for (i, path) in roots.iter().enumerate() { for (i, path) in root_paths.iter().enumerate() {
let root_filter = Arc::new(RootFilter::new(path.clone())); let root_filter = Arc::new(RootFilter::new(path.clone()));
let root = res.roots.alloc(root_filter.clone()); let root = roots.alloc(root_filter.clone());
res.root2files.insert(root, Default::default()); root2files.insert(root, Default::default());
let nested_roots = roots[..i] let nested_roots = root_paths[..i]
.iter() .iter()
.filter(|it| it.starts_with(path)) .filter(|it| it.starts_with(path))
.map(|it| it.clone()) .map(|it| it.clone())
@ -134,10 +161,17 @@ impl Vfs {
root_filter, root_filter,
nested_roots, nested_roots,
}; };
res.worker.sender().send(task).unwrap(); worker.sender().send(task).unwrap();
} }
let roots = res.roots.iter().map(|(id, _)| id).collect(); let res = Vfs {
(res, roots) roots: Arc::new(roots),
files: Arena::default(),
root2files,
worker,
pending_changes: Vec::new(),
};
let vfs_roots = res.roots.iter().map(|(id, _)| id).collect();
(res, vfs_roots)
} }
pub fn root2path(&self, root: VfsRoot) -> PathBuf { pub fn root2path(&self, root: VfsRoot) -> PathBuf {
@ -399,10 +433,7 @@ impl Vfs {
} }
fn find_root(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf, Option<VfsFile>)> { fn find_root(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf, Option<VfsFile>)> {
let (root, path) = self let (root, path) = self.roots.find(&path)?;
.roots
.iter()
.find_map(|(root, data)| data.can_contain(path).map(|it| (root, it)))?;
let file = self.root2files[&root] let file = self.root2files[&root]
.iter() .iter()
.map(|&it| it) .map(|&it| it)