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

difftreelog

perf switch to external storage for object comp

Yaroslav Bolyukin2021-05-23parent: #1cc9e6c.patch.diff
in: master

1 file changed

modifiedcrates/jrsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
1use crate::{1use crate::{
2 error::Error::*, lazy_val, push, throw, with_state, Context, ContextCreator, FuncDesc, FuncVal,2 equals, error::Error::*, lazy_val, push, throw, with_state, ArrValue, Context, ContextCreator,
3 FutureWrapper, LazyBinding, LazyVal, ObjMember, ObjValue, Result, Val,3 FuncDesc, FuncVal, FutureWrapper, LazyBinding, LazyVal, ObjMember, ObjValue, Result, Val,
4 equals,
5};4};
6use closure::closure;5use closure::closure;
7use jrsonnet_interner::IStr;6use jrsonnet_interner::IStr;
209 })208 })
210}209}
211210
212pub fn evaluate_comp<T>(211pub fn evaluate_comp(
213 context: Context,212 context: Context,
213 specs: &[CompSpec],
214 value: &impl Fn(Context) -> Result<T>,214 callback: &mut impl FnMut(Context) -> Result<()>,
215 specs: &[CompSpec],
216) -> Result<Option<Vec<T>>> {215) -> Result<()> {
217 Ok(match specs.get(0) {216 match specs.get(0) {
218 None => Some(vec![value(context)?]),217 None => callback(context)?,
219 Some(CompSpec::IfSpec(IfSpecData(cond))) => {218 Some(CompSpec::IfSpec(IfSpecData(cond))) => {
220 if evaluate(context.clone(), cond)?.try_cast_bool("if spec")? {219 if evaluate(context.clone(), cond)?.try_cast_bool("if spec")? {
221 evaluate_comp(context, value, &specs[1..])?220 evaluate_comp(context, &specs[1..], callback)?
222 } else {221 }
223 None
224 }
225 }222 }
226 Some(CompSpec::ForSpec(ForSpecData(var, expr))) => match evaluate(context.clone(), expr)? {223 Some(CompSpec::ForSpec(ForSpecData(var, expr))) => match evaluate(context.clone(), expr)? {
227 Val::Arr(list) => {224 Val::Arr(list) => {
228 let mut out = Vec::new();
229 for item in list.iter() {225 for item in list.iter() {
230 out.push(evaluate_comp(226 evaluate_comp(
231 context.clone().with_var(var.clone(), item?.clone()),227 context.clone().with_var(var.clone(), item?.clone()),
232 value,
233 &specs[1..],228 &specs[1..],
229 callback,
234 )?);230 )?
235 }231 }
236 Some(out.into_iter().flatten().flatten().collect())
237 }232 }
238 _ => throw!(InComprehensionCanOnlyIterateOverArray),233 _ => throw!(InComprehensionCanOnlyIterateOverArray),
239 },234 },
240 })235 }
236 Ok(())
241}237}
242238
243pub fn evaluate_member_list_object(context: Context, members: &[Member]) -> Result<ObjValue> {239pub fn evaluate_member_list_object(context: Context, members: &[Member]) -> Result<ObjValue> {
342 ObjBody::ObjComp(obj) => {338 ObjBody::ObjComp(obj) => {
343 let future_this = FutureWrapper::new();339 let future_this = FutureWrapper::new();
344 let mut new_members = FxHashMap::default();340 let mut new_members = FxHashMap::default();
345 for (k, v) in evaluate_comp(341 evaluate_comp(context.clone(), &obj.compspecs, &mut |ctx| {
346 context.clone(),
347 &|ctx| {
348 let new_bindings = FutureWrapper::new();342 let new_bindings = FutureWrapper::new();
360 let ctx = ctx.extend_unbound(bindings, None, None, None)?;358 let ctx = ctx.extend_unbound(bindings, None, None, None)?;
361 let key = evaluate(ctx.clone(), &obj.key)?;359 let key = evaluate(ctx.clone(), &obj.key)?;
360
361 match key {
362 Val::Null => {}
363 Val::Str(n) => {
364 new_members.insert(
365 n,
366 ObjMember {
367 add: false,
368 visibility: Visibility::Normal,
362 let value = LazyBinding::Bindable(Rc::new(369 invoke: LazyBinding::Bindable(Rc::new(
363 closure!(clone ctx, clone obj.value, |this, _super_obj| {370 closure!(clone ctx, clone obj.value, |this, _super_obj| {
364 Ok(LazyVal::new_resolved(evaluate(ctx.clone().extend(FxHashMap::default(), None, this, None), &value)?))371 Ok(LazyVal::new_resolved(evaluate(ctx.clone().extend(FxHashMap::default(), None, this, None), &value)?))
365 }),372 }),
366 ));373 )),
374 location: obj.value.1.clone(),
375 },
376 );
377 }
378 v => throw!(FieldMustBeStringGot(v.value_type())),
379 }
367380
368 Ok((key, value))381 Ok(())
369 },382 })?;
370 &obj.compspecs,
371 )?
372 .unwrap()
373 {
374 match k {
382 invoke: v,
383 location: obj.value.1.clone(),
384 },
385 );
386 }
387 v => throw!(FieldMustBeStringGot(v.value_type())),
388 }
389 }
390383
391 let this = ObjValue::new(context, None, Rc::new(new_members), Rc::new(Vec::new()));384 let this = ObjValue::new(context, None, Rc::new(new_members), Rc::new(Vec::new()));
392 future_this.fill(this.clone());385 future_this.fill(this.clone());
567 }557 }
568 Val::Arr(out.into())558 Val::Arr(out.into())
569 }559 }
570 ArrComp(expr, comp_specs) => Val::Arr(560 ArrComp(expr, comp_specs) => {
571 // First comp_spec should be for_spec, so no "None" possible here561 let mut out = Vec::new();
572 evaluate_comp(context, &|ctx| evaluate(ctx, expr), comp_specs)?562 evaluate_comp(context, comp_specs, &mut |ctx| {
573 .unwrap()563 out.push(evaluate(ctx, expr)?);
574 .into(),564 Ok(())
575 ),565 })?;
566 Val::Arr(ArrValue::Eager(Rc::new(out)))
567 }
576 Obj(body) => Val::Obj(evaluate_object(context, body)?),568 Obj(body) => Val::Obj(evaluate_object(context, body)?),
577 ObjExtend(s, t) => evaluate_add_op(569 ObjExtend(s, t) => evaluate_add_op(
578 &evaluate(context.clone(), s)?,570 &evaluate(context.clone(), s)?,