git.delta.rocks / jrsonnet / refs/commits / 9e9c9376494e

difftreelog

perf rc imports

Лач2020-06-26parent: #4a1c9d0.patch.diff
in: master

3 files changed

modifiedcmds/jrsonnet/src/main.rsdiffbeforeafterboth
--- 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);
 	}
modifiedcrates/jsonnet-evaluator/src/import.rsdiffbeforeafterboth
before · crates/jsonnet-evaluator/src/import.rs
1use crate::create_error;2use crate::error::{Error, Result};3use fs::File;4use std::fs;5use std::io::Read;6use std::{cell::RefCell, collections::HashMap, path::PathBuf};78pub trait ImportResolver {9	fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<PathBuf>;10	fn load_file_contents(&self, resolved: &PathBuf) -> Result<String>;11}1213pub struct DummyImportResolver;14impl ImportResolver for DummyImportResolver {15	fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<PathBuf> {16		create_error(Error::ImportNotSupported(from.clone(), path.clone()))17	}18	fn load_file_contents(&self, _resolved: &PathBuf) -> Result<String> {19		// Can be only caused by library direct consumer, not by supplied jsonnet20		panic!("dummy resolver can't load any file")21	}22}23impl Default for Box<dyn ImportResolver> {24	fn default() -> Self {25		Box::new(DummyImportResolver)26	}27}2829pub struct FileImportResolver {30	pub library_paths: Vec<PathBuf>,31}32impl ImportResolver for FileImportResolver {33	fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<PathBuf> {34		let mut new_path = from.clone();35		new_path.push(path);36		if new_path.exists() {37			Ok(new_path)38		} else {39			for library_path in self.library_paths.iter() {40				let mut cloned = library_path.clone();41				cloned.push(path);42				if cloned.exists() {43					return Ok(cloned);44				}45			}46			create_error(Error::ImportFileNotFound(from.clone(), path.clone()))47		}48	}49	fn load_file_contents(&self, id: &PathBuf) -> Result<String> {50		let mut file = File::open(id).map_err(|_e| {51			create_error::<()>(Error::ResolvedFileNotFound(id.clone()))52				.err()53				.unwrap()54		})?;55		let mut out = String::new();56		file.read_to_string(&mut out).map_err(|_e| {57			create_error::<()>(Error::ImportBadFileUtf8(id.clone()))58				.err()59				.unwrap()60		})?;61		Ok(out)62	}63}6465pub struct CachingImportResolver {66	resolution_cache: RefCell<HashMap<(PathBuf, PathBuf), Result<PathBuf>>>,67	loading_cache: RefCell<HashMap<PathBuf, Result<String>>>,68	inner: Box<dyn ImportResolver>,69}70impl ImportResolver for CachingImportResolver {71	fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<PathBuf> {72		self.resolution_cache73			.borrow_mut()74			.entry((from.clone(), path.clone()))75			.or_insert_with(|| self.inner.resolve_file(from, path))76			.clone()77	}78	fn load_file_contents(&self, resolved: &PathBuf) -> Result<String> {79		self.loading_cache80			.borrow_mut()81			.entry(resolved.clone())82			.or_insert_with(|| self.inner.load_file_contents(resolved))83			.clone()84	}85}
after · crates/jsonnet-evaluator/src/import.rs
1use crate::create_error;2use crate::error::{Error, Result};3use fs::File;4use std::fs;5use std::io::Read;6use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc};78pub trait ImportResolver {9	fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>>;10	fn load_file_contents(&self, resolved: &PathBuf) -> Result<Rc<str>>;11}1213pub struct DummyImportResolver;14impl ImportResolver for DummyImportResolver {15	fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {16		create_error(Error::ImportNotSupported(from.clone(), path.clone()))17	}18	fn load_file_contents(&self, _resolved: &PathBuf) -> Result<Rc<str>> {19		// Can be only caused by library direct consumer, not by supplied jsonnet20		panic!("dummy resolver can't load any file")21	}22}23impl Default for Box<dyn ImportResolver> {24	fn default() -> Self {25		Box::new(DummyImportResolver)26	}27}2829pub struct FileImportResolver {30	pub library_paths: Vec<PathBuf>,31}32impl ImportResolver for FileImportResolver {33	fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {34		let mut new_path = from.clone();35		new_path.push(path);36		if new_path.exists() {37			Ok(Rc::new(new_path))38		} else {39			for library_path in self.library_paths.iter() {40				let mut cloned = library_path.clone();41				cloned.push(path);42				if cloned.exists() {43					return Ok(Rc::new(cloned));44				}45			}46			create_error(Error::ImportFileNotFound(from.clone(), path.clone()))47		}48	}49	fn load_file_contents(&self, id: &PathBuf) -> Result<Rc<str>> {50		let mut file = File::open(id).map_err(|_e| {51			create_error::<()>(Error::ResolvedFileNotFound(id.clone()))52				.err()53				.unwrap()54		})?;55		let mut out = String::new();56		file.read_to_string(&mut out).map_err(|_e| {57			create_error::<()>(Error::ImportBadFileUtf8(id.clone()))58				.err()59				.unwrap()60		})?;61		Ok(out.into())62	}63}6465pub struct CachingImportResolver {66	resolution_cache: RefCell<HashMap<(PathBuf, PathBuf), Result<Rc<PathBuf>>>>,67	loading_cache: RefCell<HashMap<PathBuf, Result<Rc<str>>>>,68	inner: Box<dyn ImportResolver>,69}70impl ImportResolver for CachingImportResolver {71	fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {72		self.resolution_cache73			.borrow_mut()74			.entry((from.clone(), path.clone()))75			.or_insert_with(|| self.inner.resolve_file(from, path))76			.clone()77	}78	fn load_file_contents(&self, resolved: &PathBuf) -> Result<Rc<str>> {79		self.loading_cache80			.borrow_mut()81			.entry(resolved.clone())82			.or_insert_with(|| self.inner.load_file_contents(resolved))83			.clone()84	}85}
modifiedcrates/jsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jsonnet-evaluator/src/lib.rs
+++ b/crates/jsonnet-evaluator/src/lib.rs
@@ -57,15 +57,15 @@
 	}
 }
 
-pub struct FileData(String, LocExpr, Option<Val>);
+pub struct FileData(Rc<str>, LocExpr, Option<Val>);
 #[derive(Default)]
 pub struct EvaluationStateInternals {
 	/// Used for stack-overflows and stacktraces
 	stack: RefCell<Vec<StackTraceElement>>,
 	/// Contains file source codes and evaluated results for imports and pretty
 	/// printing stacktraces
-	files: RefCell<HashMap<PathBuf, FileData>>,
-	str_files: RefCell<HashMap<PathBuf, Rc<str>>>,
+	files: RefCell<HashMap<Rc<PathBuf>, FileData>>,
+	str_files: RefCell<HashMap<Rc<PathBuf>, Rc<str>>>,
 	globals: RefCell<HashMap<Rc<str>, 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<PathBuf>,
+		code: Rc<str>,
+	) -> 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<PathBuf>,
+		code: Rc<str>,
 		parsed: LocExpr,
 	) -> std::result::Result<(), ()> {
 		self.0
@@ -140,7 +144,7 @@
 
 		Ok(())
 	}
-	pub fn get_source(&self, name: &PathBuf) -> Option<String> {
+	pub fn get_source(&self, name: &PathBuf) -> Option<Rc<str>> {
 		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();