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
136 let mut input = current_dir().unwrap();136 let mut input = current_dir().unwrap();
137 input.push(opts.input.clone());137 input.push(opts.input.clone());
138 let code_string = String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap();138 let code_string = String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap();
139 if let Err(e) = evaluator.add_file(input.clone(), code_string.clone()) {139 if let Err(e) = evaluator.add_file(Rc::new(input.clone()), code_string.clone().into()) {
140 print_syntax_error(e, &input, &code_string);140 print_syntax_error(e, &input, &code_string);
141 std::process::exit(1);141 std::process::exit(1);
142 }142 }
modifiedcrates/jsonnet-evaluator/src/import.rsdiffbeforeafterboth
3use fs::File;3use fs::File;
4use std::fs;4use std::fs;
5use std::io::Read;5use std::io::Read;
6use std::{cell::RefCell, collections::HashMap, path::PathBuf};6use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc};
77
8pub trait ImportResolver {8pub trait ImportResolver {
9 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<PathBuf>;9 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>>;
10 fn load_file_contents(&self, resolved: &PathBuf) -> Result<String>;10 fn load_file_contents(&self, resolved: &PathBuf) -> Result<Rc<str>>;
11}11}
1212
13pub struct DummyImportResolver;13pub struct DummyImportResolver;
14impl ImportResolver for DummyImportResolver {14impl ImportResolver for DummyImportResolver {
15 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<PathBuf> {15 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {
16 create_error(Error::ImportNotSupported(from.clone(), path.clone()))16 create_error(Error::ImportNotSupported(from.clone(), path.clone()))
17 }17 }
18 fn load_file_contents(&self, _resolved: &PathBuf) -> Result<String> {18 fn load_file_contents(&self, _resolved: &PathBuf) -> Result<Rc<str>> {
19 // Can be only caused by library direct consumer, not by supplied jsonnet19 // Can be only caused by library direct consumer, not by supplied jsonnet
20 panic!("dummy resolver can't load any file")20 panic!("dummy resolver can't load any file")
21 }21 }
30 pub library_paths: Vec<PathBuf>,30 pub library_paths: Vec<PathBuf>,
31}31}
32impl ImportResolver for FileImportResolver {32impl ImportResolver for FileImportResolver {
33 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<PathBuf> {33 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {
34 let mut new_path = from.clone();34 let mut new_path = from.clone();
35 new_path.push(path);35 new_path.push(path);
36 if new_path.exists() {36 if new_path.exists() {
37 Ok(new_path)37 Ok(Rc::new(new_path))
38 } else {38 } else {
39 for library_path in self.library_paths.iter() {39 for library_path in self.library_paths.iter() {
40 let mut cloned = library_path.clone();40 let mut cloned = library_path.clone();
41 cloned.push(path);41 cloned.push(path);
42 if cloned.exists() {42 if cloned.exists() {
43 return Ok(cloned);43 return Ok(Rc::new(cloned));
44 }44 }
45 }45 }
46 create_error(Error::ImportFileNotFound(from.clone(), path.clone()))46 create_error(Error::ImportFileNotFound(from.clone(), path.clone()))
47 }47 }
48 }48 }
49 fn load_file_contents(&self, id: &PathBuf) -> Result<String> {49 fn load_file_contents(&self, id: &PathBuf) -> Result<Rc<str>> {
50 let mut file = File::open(id).map_err(|_e| {50 let mut file = File::open(id).map_err(|_e| {
51 create_error::<()>(Error::ResolvedFileNotFound(id.clone()))51 create_error::<()>(Error::ResolvedFileNotFound(id.clone()))
52 .err()52 .err()
58 .err()58 .err()
59 .unwrap()59 .unwrap()
60 })?;60 })?;
61 Ok(out)61 Ok(out.into())
62 }62 }
63}63}
6464
65pub struct CachingImportResolver {65pub struct CachingImportResolver {
66 resolution_cache: RefCell<HashMap<(PathBuf, PathBuf), Result<PathBuf>>>,66 resolution_cache: RefCell<HashMap<(PathBuf, PathBuf), Result<Rc<PathBuf>>>>,
67 loading_cache: RefCell<HashMap<PathBuf, Result<String>>>,67 loading_cache: RefCell<HashMap<PathBuf, Result<Rc<str>>>>,
68 inner: Box<dyn ImportResolver>,68 inner: Box<dyn ImportResolver>,
69}69}
70impl ImportResolver for CachingImportResolver {70impl ImportResolver for CachingImportResolver {
71 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<PathBuf> {71 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {
72 self.resolution_cache72 self.resolution_cache
73 .borrow_mut()73 .borrow_mut()
74 .entry((from.clone(), path.clone()))74 .entry((from.clone(), path.clone()))
75 .or_insert_with(|| self.inner.resolve_file(from, path))75 .or_insert_with(|| self.inner.resolve_file(from, path))
76 .clone()76 .clone()
77 }77 }
78 fn load_file_contents(&self, resolved: &PathBuf) -> Result<String> {78 fn load_file_contents(&self, resolved: &PathBuf) -> Result<Rc<str>> {
79 self.loading_cache79 self.loading_cache
80 .borrow_mut()80 .borrow_mut()
81 .entry(resolved.clone())81 .entry(resolved.clone())
modifiedcrates/jsonnet-evaluator/src/lib.rsdiffbeforeafterboth
57 }57 }
58}58}
5959
60pub struct FileData(String, LocExpr, Option<Val>);60pub struct FileData(Rc<str>, LocExpr, Option<Val>);
61#[derive(Default)]61#[derive(Default)]
62pub struct EvaluationStateInternals {62pub struct EvaluationStateInternals {
63 /// Used for stack-overflows and stacktraces63 /// Used for stack-overflows and stacktraces
64 stack: RefCell<Vec<StackTraceElement>>,64 stack: RefCell<Vec<StackTraceElement>>,
65 /// Contains file source codes and evaluated results for imports and pretty65 /// Contains file source codes and evaluated results for imports and pretty
66 /// printing stacktraces66 /// printing stacktraces
67 files: RefCell<HashMap<PathBuf, FileData>>,67 files: RefCell<HashMap<Rc<PathBuf>, FileData>>,
68 str_files: RefCell<HashMap<PathBuf, Rc<str>>>,68 str_files: RefCell<HashMap<Rc<PathBuf>, Rc<str>>>,
69 globals: RefCell<HashMap<Rc<str>, Val>>,69 globals: RefCell<HashMap<Rc<str>, Val>>,
7070
71 /// Values to use with std.extVar71 /// Values to use with std.extVar
109 ..Default::default()109 ..Default::default()
110 }))110 }))
111 }111 }
112 pub fn add_file(&self, name: PathBuf, code: String) -> std::result::Result<(), ParseError> {112 pub fn add_file(
113 &self,
114 name: Rc<PathBuf>,
115 code: Rc<str>,
116 ) -> std::result::Result<(), ParseError> {
113 self.0.files.borrow_mut().insert(117 self.0.files.borrow_mut().insert(
114 name.clone(),118 name.clone(),
117 parse(121 parse(
118 &code,122 &code,
119 &ParserSettings {123 &ParserSettings {
120 file_name: Rc::new(name),124 file_name: name,
121 loc_data: true,125 loc_data: true,
122 },126 },
123 )?,127 )?,
129 }133 }
130 pub fn add_parsed_file(134 pub fn add_parsed_file(
131 &self,135 &self,
132 name: PathBuf,136 name: Rc<PathBuf>,
133 code: String,137 code: Rc<str>,
134 parsed: LocExpr,138 parsed: LocExpr,
135 ) -> std::result::Result<(), ()> {139 ) -> std::result::Result<(), ()> {
136 self.0140 self.0
140144
141 Ok(())145 Ok(())
142 }146 }
143 pub fn get_source(&self, name: &PathBuf) -> Option<String> {147 pub fn get_source(&self, name: &PathBuf) -> Option<Rc<str>> {
144 let ro_map = self.0.files.borrow();148 let ro_map = self.0.files.borrow();
145 ro_map.get(name).map(|value| value.0.clone())149 ro_map.get(name).map(|value| value.0.clone())
146 }150 }
221 }225 }
222226
223 pub fn with_stdlib(&self) -> &Self {227 pub fn with_stdlib(&self) -> &Self {
228 let std_path = Rc::new(PathBuf::from("std.jsonnet"));
224 self.run_in_state(|| {229 self.run_in_state(|| {
225 use jsonnet_stdlib::STDLIB_STR;230 use jsonnet_stdlib::STDLIB_STR;
226 if cfg!(feature = "serialized-stdlib") {231 if cfg!(feature = "serialized-stdlib") {
227 self.add_parsed_file(232 self.add_parsed_file(
228 PathBuf::from("std.jsonnet"),233 std_path,
229 STDLIB_STR.to_owned(),234 STDLIB_STR.to_owned().into(),
230 bincode::deserialize(include_bytes!(concat!(235 bincode::deserialize(include_bytes!(concat!(
231 env!("OUT_DIR"),236 env!("OUT_DIR"),
232 "/stdlib.bincode"237 "/stdlib.bincode"
235 )240 )
236 .unwrap();241 .unwrap();
237 } else {242 } else {
238 self.add_file(PathBuf::from("std.jsonnet"), STDLIB_STR.to_owned())243 self.add_file(std_path, STDLIB_STR.to_owned().into())
239 .unwrap();244 .unwrap();
240 }245 }
241 let val = self.evaluate_file(&PathBuf::from("std.jsonnet")).unwrap();246 let val = self.evaluate_file(&PathBuf::from("std.jsonnet")).unwrap();