From 9e9c9376494e85a3d79b986ab41a3ae661f7d2ab Mon Sep 17 00:00:00 2001 From: Лач Date: Fri, 26 Jun 2020 12:35:45 +0000 Subject: [PATCH] perf: rc imports --- --- a/cmds/jrsonnet/src/main.rs +++ b/cmds/jrsonnet/src/main.rs @@ -136,7 +136,7 @@ let mut input = current_dir().unwrap(); input.push(opts.input.clone()); let code_string = String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap(); - if let Err(e) = evaluator.add_file(input.clone(), code_string.clone()) { + if let Err(e) = evaluator.add_file(Rc::new(input.clone()), code_string.clone().into()) { print_syntax_error(e, &input, &code_string); std::process::exit(1); } --- a/crates/jsonnet-evaluator/src/import.rs +++ b/crates/jsonnet-evaluator/src/import.rs @@ -3,19 +3,19 @@ use fs::File; use std::fs; use std::io::Read; -use std::{cell::RefCell, collections::HashMap, path::PathBuf}; +use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc}; pub trait ImportResolver { - fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result; - fn load_file_contents(&self, resolved: &PathBuf) -> Result; + fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result>; + fn load_file_contents(&self, resolved: &PathBuf) -> Result>; } pub struct DummyImportResolver; impl ImportResolver for DummyImportResolver { - fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result { + fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result> { create_error(Error::ImportNotSupported(from.clone(), path.clone())) } - fn load_file_contents(&self, _resolved: &PathBuf) -> Result { + fn load_file_contents(&self, _resolved: &PathBuf) -> Result> { // Can be only caused by library direct consumer, not by supplied jsonnet panic!("dummy resolver can't load any file") } @@ -30,23 +30,23 @@ pub library_paths: Vec, } impl ImportResolver for FileImportResolver { - fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result { + fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result> { let mut new_path = from.clone(); new_path.push(path); if new_path.exists() { - Ok(new_path) + Ok(Rc::new(new_path)) } else { for library_path in self.library_paths.iter() { let mut cloned = library_path.clone(); cloned.push(path); if cloned.exists() { - return Ok(cloned); + return Ok(Rc::new(cloned)); } } create_error(Error::ImportFileNotFound(from.clone(), path.clone())) } } - fn load_file_contents(&self, id: &PathBuf) -> Result { + fn load_file_contents(&self, id: &PathBuf) -> Result> { let mut file = File::open(id).map_err(|_e| { create_error::<()>(Error::ResolvedFileNotFound(id.clone())) .err() @@ -58,24 +58,24 @@ .err() .unwrap() })?; - Ok(out) + Ok(out.into()) } } pub struct CachingImportResolver { - resolution_cache: RefCell>>, - loading_cache: RefCell>>, + resolution_cache: RefCell>>>, + loading_cache: RefCell>>>, inner: Box, } impl ImportResolver for CachingImportResolver { - fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result { + fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result> { self.resolution_cache .borrow_mut() .entry((from.clone(), path.clone())) .or_insert_with(|| self.inner.resolve_file(from, path)) .clone() } - fn load_file_contents(&self, resolved: &PathBuf) -> Result { + fn load_file_contents(&self, resolved: &PathBuf) -> Result> { self.loading_cache .borrow_mut() .entry(resolved.clone()) --- a/crates/jsonnet-evaluator/src/lib.rs +++ b/crates/jsonnet-evaluator/src/lib.rs @@ -57,15 +57,15 @@ } } -pub struct FileData(String, LocExpr, Option); +pub struct FileData(Rc, LocExpr, Option); #[derive(Default)] pub struct EvaluationStateInternals { /// Used for stack-overflows and stacktraces stack: RefCell>, /// Contains file source codes and evaluated results for imports and pretty /// printing stacktraces - files: RefCell>, - str_files: RefCell>>, + files: RefCell, FileData>>, + str_files: RefCell, Rc>>, globals: RefCell, Val>>, /// Values to use with std.extVar @@ -109,7 +109,11 @@ ..Default::default() })) } - pub fn add_file(&self, name: PathBuf, code: String) -> std::result::Result<(), ParseError> { + pub fn add_file( + &self, + name: Rc, + code: Rc, + ) -> std::result::Result<(), ParseError> { self.0.files.borrow_mut().insert( name.clone(), FileData( @@ -117,7 +121,7 @@ parse( &code, &ParserSettings { - file_name: Rc::new(name), + file_name: name, loc_data: true, }, )?, @@ -129,8 +133,8 @@ } pub fn add_parsed_file( &self, - name: PathBuf, - code: String, + name: Rc, + code: Rc, parsed: LocExpr, ) -> std::result::Result<(), ()> { self.0 @@ -140,7 +144,7 @@ Ok(()) } - pub fn get_source(&self, name: &PathBuf) -> Option { + pub fn get_source(&self, name: &PathBuf) -> Option> { let ro_map = self.0.files.borrow(); ro_map.get(name).map(|value| value.0.clone()) } @@ -221,12 +225,13 @@ } pub fn with_stdlib(&self) -> &Self { + let std_path = Rc::new(PathBuf::from("std.jsonnet")); self.run_in_state(|| { use jsonnet_stdlib::STDLIB_STR; if cfg!(feature = "serialized-stdlib") { self.add_parsed_file( - PathBuf::from("std.jsonnet"), - STDLIB_STR.to_owned(), + std_path, + STDLIB_STR.to_owned().into(), bincode::deserialize(include_bytes!(concat!( env!("OUT_DIR"), "/stdlib.bincode" @@ -235,7 +240,7 @@ ) .unwrap(); } else { - self.add_file(PathBuf::from("std.jsonnet"), STDLIB_STR.to_owned()) + self.add_file(std_path, STDLIB_STR.to_owned().into()) .unwrap(); } let val = self.evaluate_file(&PathBuf::from("std.jsonnet")).unwrap(); -- gitstuff