From 18486a02fae5966e61f16ea7bc5c33c6c7c69487 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 13 Aug 2018 13:46:05 +0300 Subject: indexing infra --- crates/libanalysis/src/lib.rs | 78 ++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 46 deletions(-) (limited to 'crates/libanalysis/src') diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index 74f043a9b..e4df3de2e 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs @@ -1,3 +1,4 @@ +#[macro_use] extern crate failure; extern crate parking_lot; #[macro_use] @@ -9,12 +10,10 @@ extern crate libeditor; use once_cell::sync::OnceCell; use std::{ - fs, sync::Arc, collections::hash_map::HashMap, path::{PathBuf, Path}, }; -use parking_lot::RwLock; use libsyntax2::ast; use libeditor::LineIndex; @@ -40,22 +39,27 @@ impl WorldState { World { data: self.data.clone() } } - pub fn change_overlay(&mut self, path: PathBuf, text: Option) { + pub fn change_file(&mut self, path: PathBuf, text: Option) { + self.change_files(::std::iter::once((path, text))); + } + + pub fn change_files(&mut self, changes: impl Iterator)>) { let data = self.data_mut(); - data.file_map.get_mut().remove(&path); - if let Some(text) = text { - data.mem_map.insert(path, Arc::new(text)); - } else { - data.mem_map.remove(&path); + for (path, text) in changes { + data.file_map.remove(&path); + if let Some(text) = text { + let file_data = FileData::new(text); + data.file_map.insert(path, Arc::new(file_data)); + } else { + data.file_map.remove(&path); + } } } fn data_mut(&mut self) -> &mut WorldData { if Arc::get_mut(&mut self.data).is_none() { - let file_map = self.data.file_map.read().clone(); self.data = Arc::new(WorldData { - mem_map: self.data.mem_map.clone(), - file_map: RwLock::new(file_map), + file_map: self.data.file_map.clone(), }); } Arc::get_mut(&mut self.data).unwrap() @@ -69,7 +73,7 @@ impl World { let syntax = data.syntax .get_or_init(|| { trace!("parsing: {}", path.display()); - ast::File::parse(self.file_text(path, &data)) + ast::File::parse(&data.text) }).clone(); Ok(syntax) } @@ -79,56 +83,38 @@ impl World { let index = data.lines .get_or_init(|| { trace!("calc line index: {}", path.display()); - LineIndex::new(self.file_text(path, &data)) + LineIndex::new(&data.text) }); Ok(index.clone()) } - fn file_text<'a>(&'a self, path: &Path, file_data: &'a FileData) -> &'a str { - match file_data.text.as_ref() { - Some(text) => text.as_str(), - None => self.data.mem_map[path].as_str() - } - } - fn file_data(&self, path: &Path) -> Result> { - { - let guard = self.data.file_map.read(); - if let Some(data) = guard.get(path) { - return Ok(data.clone()); - } + match self.data.file_map.get(path) { + Some(data) => Ok(data.clone()), + None => bail!("unknown file: {}", path.display()), } - - let text = if self.data.mem_map.contains_key(path) { - None - } else { - trace!("loading file from disk: {}", path.display()); - Some(fs::read_to_string(path)?) - }; - let res = { - let mut guard = self.data.file_map.write(); - guard.entry(path.to_owned()) - .or_insert_with(|| Arc::new(FileData { - text, - syntax: OnceCell::new(), - lines: OnceCell::new(), - })) - .clone() - }; - Ok(res) } } #[derive(Default, Debug)] struct WorldData { - mem_map: HashMap>, - file_map: RwLock>>, + file_map: HashMap>, } #[derive(Debug)] struct FileData { - text: Option, + text: String, syntax: OnceCell, lines: OnceCell, } + +impl FileData { + fn new(text: String) -> FileData { + FileData { + text, + syntax: OnceCell::new(), + lines: OnceCell::new(), + } + } +} -- cgit v1.2.3