From f265ccef596aba6ea1d77bdf67f6b032e6e271b3 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 30 Oct 2020 18:54:34 +0100 Subject: [PATCH] TrapWriter: add global ID caching and populate folders --- extractor/src/extractor.rs | 120 +++++++++++++++++++++++++------------ 1 file changed, 81 insertions(+), 39 deletions(-) diff --git a/extractor/src/extractor.rs b/extractor/src/extractor.rs index 2c8a3e24ab7..f36f012760a 100644 --- a/extractor/src/extractor.rs +++ b/extractor/src/extractor.rs @@ -11,12 +11,15 @@ struct TrapWriter { trap_output: Vec, /// A counter for generating fresh labels counter: i32, + /// cache of global keys + global_keys: std::collections::HashMap, } fn new_trap_writer() -> TrapWriter { TrapWriter { counter: -1, trap_output: Vec::new(), + global_keys: std::collections::HashMap::new(), } } @@ -37,12 +40,16 @@ impl TrapWriter { label } - fn global_id(&mut self, key: &str) -> Label { + fn global_id(&mut self, key: &str) -> (Label, bool) { + if let Some(label) = self.global_keys.get(key) { + return (*label, false); + } self.counter += 1; let label = Label(self.counter); + self.global_keys.insert(key.to_owned(), label); self.trap_output .push(TrapEntry::MapLabelToKey(label, key.to_owned())); - label + (label, true) } fn add_tuple(&mut self, table_name: &str, args: Vec) { @@ -51,32 +58,62 @@ impl TrapWriter { } fn populate_file(&mut self, absolute_path: &Path) -> Label { - let file_label = self.global_id(&full_id_for_file(absolute_path)); - self.trap_output.push(TrapEntry::GenericTuple( - "files".to_owned(), - vec![ - Arg::Label(file_label), - Arg::String(normalize_path(absolute_path)), - Arg::String(match absolute_path.file_name() { - None => "".to_owned(), - Some(file_name) => format!("{}", file_name.to_string_lossy()), - }), - Arg::String(match absolute_path.extension() { - None => "".to_owned(), - Some(ext) => format!("{}", ext.to_string_lossy()), - }), - Arg::Int(1), // 1 = from source - ], - )); + let (file_label, fresh) = self.global_id(&full_id_for_file(absolute_path)); + if fresh { + self.add_tuple( + "files", + vec![ + Arg::Label(file_label), + Arg::String(normalize_path(absolute_path)), + Arg::String(match absolute_path.file_name() { + None => "".to_owned(), + Some(file_name) => format!("{}", file_name.to_string_lossy()), + }), + Arg::String(match absolute_path.extension() { + None => "".to_owned(), + Some(ext) => format!("{}", ext.to_string_lossy()), + }), + Arg::Int(1), // 1 = from source + ], + ); + self.populate_parent_folders(file_label, absolute_path.parent()); + } file_label } - // fn populate_unknown_file(&mut self) -> Label { - // self.global_id("unknown;sourcefile") - // } - // fn populate_folder(&mut self, absolute_path: &str) -> Label { - // self.global_id(&format!("{};folder", absolute_path)) - // } + fn populate_parent_folders(&mut self, child_label: Label, path: Option<&Path>) { + let mut path = path; + let mut child_label = child_label; + loop { + match path { + None => break, + Some(folder) => { + let (folder_label, fresh) = self.global_id(&full_id_for_folder(folder)); + self.add_tuple( + "containerparent", + vec![Arg::Label(folder_label), Arg::Label(child_label)], + ); + if fresh { + self.add_tuple( + "folders", + vec![ + Arg::Label(folder_label), + Arg::String(normalize_path(folder)), + Arg::String(match folder.file_name() { + None => "".to_owned(), + Some(file_name) => format!("{}", file_name.to_string_lossy()), + }), + ], + ); + path = folder.parent(); + child_label = folder_label; + } else { + break; + } + } + } + } + } fn location( &mut self, @@ -86,22 +123,23 @@ impl TrapWriter { end_line: usize, end_column: usize, ) -> Label { - let key = format!( + let (loc_label, fresh) = self.global_id(&format!( "loc,{{{}}},{},{},{},{}", file_label, start_line, start_column, end_line, end_column - ); - let loc_label = self.global_id(&key); - self.add_tuple( - "locations_default", - vec![ - Arg::Label(loc_label), - Arg::Label(file_label), - Arg::Int(start_line), - Arg::Int(start_column), - Arg::Int(end_line), - Arg::Int(end_column), - ], - ); + )); + if fresh { + self.add_tuple( + "locations_default", + vec![ + Arg::Label(loc_label), + Arg::Label(file_label), + Arg::Int(start_line), + Arg::Int(start_column), + Arg::Int(end_line), + Arg::Int(end_column), + ], + ); + } loc_label } @@ -203,6 +241,10 @@ fn full_id_for_file(path: &Path) -> String { format!("{};sourcefile", normalize_path(path)) } +fn full_id_for_folder(path: &Path) -> String { + format!("{};folder", normalize_path(path)) +} + fn build_schema_lookup<'a>(schema: &'a Vec) -> Map<&'a TypeName, &'a Entry> { let mut map = std::collections::BTreeMap::new(); for entry in schema {