From 18486a02fae5966e61f16ea7bc5c33c6c7c69487 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
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')

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<String>) {
+    pub fn change_file(&mut self, path: PathBuf, text: Option<String>) {
+        self.change_files(::std::iter::once((path, text)));
+    }
+
+    pub fn change_files(&mut self, changes: impl Iterator<Item=(PathBuf, Option<String>)>) {
         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<Arc<FileData>> {
-        {
-            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<PathBuf, Arc<String>>,
-    file_map: RwLock<HashMap<PathBuf, Arc<FileData>>>,
+    file_map: HashMap<PathBuf, Arc<FileData>>,
 }
 
 #[derive(Debug)]
 struct FileData {
-    text: Option<String>,
+    text: String,
     syntax: OnceCell<ast::File>,
     lines: OnceCell<LineIndex>,
 }
+
+impl FileData {
+    fn new(text: String) -> FileData {
+        FileData {
+            text,
+            syntax: OnceCell::new(),
+            lines: OnceCell::new(),
+        }
+    }
+}
-- 
cgit v1.2.3