git.delta.rocks / jrsonnet / refs/commits / a9b3ad095ce8

difftreelog

perf(evaluator) "faster" feature flag

Лач2020-06-25parent: #f8b6073.patch.diff
in: master

3 files changed

modifiedcrates/jsonnet-evaluator/Cargo.tomldiffbeforeafterboth
--- a/crates/jsonnet-evaluator/Cargo.toml
+++ b/crates/jsonnet-evaluator/Cargo.toml
@@ -7,8 +7,10 @@
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [features]
-default = ["serialized-stdlib"]
+default = ["serialized-stdlib", "faster"]
 serialized-stdlib = ["serde", "bincode"]
+# Replace some standard library functions with faster implementations
+faster = []
 
 [dependencies]
 jsonnet-parser = { path = "../jsonnet-parser" }
modifiedcrates/jsonnet-evaluator/build.rsdiffbeforeafterboth
before · crates/jsonnet-evaluator/build.rs
1use bincode::serialize;2use jsonnet_parser::{parse, ParserSettings};3use jsonnet_stdlib::STDLIB_STR;4use std::{5	env,6	fs::File,7	io::Write,8	path::{Path, PathBuf},9};1011fn main() {12	let parsed = parse(13		STDLIB_STR,14		&ParserSettings {15			file_name: PathBuf::from("std.jsonnet"),16			loc_data: true,17		},18	)19	.expect("parse");2021	let out_dir = env::var("OUT_DIR").unwrap();22	let dest_path = Path::new(&out_dir).join("stdlib.bincode");23	let mut f = File::create(&dest_path).unwrap();24	f.write_all(&serialize(&parsed).expect("serialize"))25		.unwrap();26}
modifiedcrates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
--- a/crates/jsonnet-evaluator/src/evaluate.rs
+++ b/crates/jsonnet-evaluator/src/evaluate.rs
@@ -661,6 +661,76 @@
 							panic!("bad extVar call");
 						}
 					}
+					("std", "filter") => {
+						assert_eq!(args.len(), 2);
+						if let (Val::Func(predicate), Val::Arr(arr)) = (
+							evaluate(context, &args[0].1)?,
+							evaluate(context, &args[1].1)?,
+						) {
+							Val::Arr(
+								arr.into_iter()
+									.filter(|e| {
+										predicate
+											.evaluate_values(&context, &[e.clone()])
+											.unwrap()
+											.try_cast_bool("filter predicate")
+											.unwrap()
+									})
+									.collect(),
+							)
+						} else {
+							panic!("bad filter call");
+						}
+					}
+					// faster
+					("std", "join") => {
+						assert_eq!(args.len(), 2);
+						let joiner = evaluate(context, &args[0].1)?.unwrap_if_lazy()?;
+						let items = evaluate(context, &args[1].1)?.unwrap_if_lazy()?;
+						println!("Before");
+						let result = match (joiner, items) {
+							(Val::Arr(joiner_items), Val::Arr(items)) => {
+								// TODO: Minimal size should be known
+								let mut out = Vec::new();
+
+								let mut first = true;
+								for item in items {
+									if let Val::Arr(items) = item.unwrap_if_lazy()? {
+										if !first {
+											out.extend(joiner_items.iter().cloned());
+										}
+										first = false;
+										out.extend(items);
+									} else {
+										panic!("all array items should be arrays")
+									}
+								}
+
+								Val::Arr(out)
+							}
+							(Val::Str(joiner), Val::Arr(items)) => {
+								let mut out = String::new();
+
+								let mut first = true;
+								for item in items {
+									if let Val::Str(item) = item.unwrap_if_lazy()? {
+										if !first {
+											out += &joiner;
+										}
+										first = false;
+										out += &item;
+									} else {
+										panic!("all array items should be strings")
+									}
+								}
+
+								Val::Str(out)
+							}
+							(joiner, items) => panic!("bad join call: {:?} {:?}", joiner, items),
+						};
+						println!("After");
+						result
+					}
 					(ns, name) => panic!("Intristic not found: {}.{}", ns, name),
 				},
 				Val::Func(f) => {