From a5e319ec7ed72d14486631934ff652d9fe4e5319 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Sun, 2 Sep 2018 23:09:47 +0300
Subject: Store symbols separately from file data

---
 crates/libanalysis/Cargo.toml   |  2 +-
 crates/libanalysis/src/roots.rs | 23 ++++++++++-------------
 2 files changed, 11 insertions(+), 14 deletions(-)

(limited to 'crates')

diff --git a/crates/libanalysis/Cargo.toml b/crates/libanalysis/Cargo.toml
index 9c7977e92..4d565e95f 100644
--- a/crates/libanalysis/Cargo.toml
+++ b/crates/libanalysis/Cargo.toml
@@ -8,7 +8,7 @@ relative-path = "0.3.7"
 log = "0.4.2"
 crossbeam-channel = "0.2.4"
 parking_lot = "0.6.3"
-once_cell = "0.1.4"
+once_cell = "0.1.5"
 rayon = "1.0.2"
 fst = "0.3.1"
 libsyntax2 = { path = "../libsyntax2" }
diff --git a/crates/libanalysis/src/roots.rs b/crates/libanalysis/src/roots.rs
index 675bce54c..eb14e7567 100644
--- a/crates/libanalysis/src/roots.rs
+++ b/crates/libanalysis/src/roots.rs
@@ -18,7 +18,7 @@ use {
 
 #[derive(Clone, Default, Debug)]
 pub(crate) struct SourceRoot {
-    file_map: HashMap<FileId, Arc<FileData>>,
+    file_map: HashMap<FileId, Arc<(FileData, OnceCell<FileSymbols>)>>,
     module_map: ModuleMap,
 }
 
@@ -37,9 +37,7 @@ impl SourceRoot {
         self.file_map.remove(&file_id);
         if let Some(text) = text {
             let file_data = FileData::new(text);
-            self.file_map.insert(file_id, Arc::new(file_data));
-        } else {
-            self.file_map.remove(&file_id);
+            self.file_map.insert(file_id, Arc::new((file_data, Default::default())));
         }
     }
     pub fn module_map(&self) -> &ModuleMap {
@@ -64,7 +62,7 @@ impl SourceRoot {
     pub(crate) fn symbols(&self) -> Vec<(FileId, &FileSymbols)> {
         self.file_map
             .iter()
-            .map(|(&file_id, data)| (file_id, data.symbols()))
+            .map(|(&file_id, data)| (file_id, symbols(data)))
             .collect()
     }
     pub fn reindex(&self) {
@@ -72,32 +70,35 @@ impl SourceRoot {
         self.file_map
             .par_iter()
             .for_each(|(_, data)| {
-                data.symbols();
+                symbols(data);
             });
         info!("parallel indexing took {:?}", now.elapsed());
 
     }
     fn data(&self, file_id: FileId) -> &FileData {
         match self.file_map.get(&file_id) {
-            Some(data) => data,
+            Some(data) => &data.0,
             None => panic!("unknown file: {:?}", file_id),
         }
     }
 }
 
+fn symbols((data, symbols): &(FileData, OnceCell<FileSymbols>)) -> &FileSymbols {
+    let syntax = data.syntax_transient();
+    symbols.get_or_init(|| FileSymbols::new(&syntax))
+}
+
 #[derive(Debug)]
 struct FileData {
     text: String,
     lines: OnceCell<LineIndex>,
     syntax: OnceCell<File>,
-    symbols: OnceCell<FileSymbols>,
 }
 
 impl FileData {
     fn new(text: String) -> FileData {
         FileData {
             text,
-            symbols: OnceCell::new(),
             syntax: OnceCell::new(),
             lines: OnceCell::new(),
         }
@@ -106,8 +107,4 @@ impl FileData {
         self.syntax.get().map(|s| s.clone())
             .unwrap_or_else(|| File::parse(&self.text))
     }
-    fn symbols(&self) -> &FileSymbols {
-        let syntax = self.syntax_transient();
-        self.symbols.get_or_init(|| FileSymbols::new(&syntax))
-    }
 }
-- 
cgit v1.2.3