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

difftreelog

perf only cache gets in top-level object

Yaroslav Bolyukin2022-08-05parent: #673ea5e.patch.diff
in: master
Deep cache only has sense in presence of standalone self, and most of
the time it only takes unnecessary space, and takes time to fill/rehash
the cache map.

1 file changed

modifiedcrates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth
109}109}
110110
111// Field => This111// Field => This
112type CacheKey = (IStr, WeakObjValue);
113112
114#[derive(Trace)]113#[derive(Trace)]
115enum CacheValue {114enum CacheValue {
129 assertions: Cc<Vec<TraceBox<dyn ObjectAssertion>>>,128 assertions: Cc<Vec<TraceBox<dyn ObjectAssertion>>>,
130 assertions_ran: RefCell<GcHashSet<ObjValue>>,129 assertions_ran: RefCell<GcHashSet<ObjValue>>,
131 this_entries: Cc<GcHashMap<IStr, ObjMember>>,130 this_entries: Cc<GcHashMap<IStr, ObjMember>>,
132 value_cache: RefCell<GcHashMap<CacheKey, CacheValue>>,131 value_cache: RefCell<GcHashMap<IStr, CacheValue>>,
133}132}
134133
135#[derive(Clone, Trace)]134#[derive(Clone, Trace)]
367 .map_or(false, |v| v.is_visible())366 .map_or(false, |v| v.is_visible())
368 }367 }
369368
370 pub fn get(&self, s: State, key: IStr) -> Result<Option<Val>> {369 pub fn get(&self, s: State, key: IStr) -> Result<Option<Val>> {
371 self.run_assertions(s.clone())?;370 self.run_assertions(s.clone())?;
372 self.get_raw(s, key, self.0.this.clone().unwrap_or_else(|| self.clone()))
373 }
374
375 // pub fn extend_with(self, key: )
376
377 fn get_raw(&self, s: State, key: IStr, real_this: Self) -> Result<Option<Val>> {
378 let cache_key = (key.clone(), WeakObjValue(real_this.0.downgrade()));371 if let Some(v) = self.0.value_cache.borrow().get(&key) {
379
380 if let Some(v) = self.0.value_cache.borrow().get(&cache_key) {
381 return Ok(match v {372 return Ok(match v {
382 CacheValue::Cached(v) => Some(v.clone()),373 CacheValue::Cached(v) => Some(v.clone()),
383 CacheValue::NotFound => None,374 CacheValue::NotFound => None,
384 CacheValue::Pending => throw!(InfiniteRecursionDetected),375 CacheValue::Pending => throw!(InfiniteRecursionDetected),
385 CacheValue::Errored(e) => return Err(e.clone()),376 CacheValue::Errored(e) => return Err(e.clone()),
386 });377 });
387 }378 }
388 self.0379 self.0
389 .value_cache380 .value_cache
390 .borrow_mut()381 .borrow_mut()
391 .insert(cache_key.clone(), CacheValue::Pending);382 .insert(key.clone(), CacheValue::Pending);
392 let fill_error = |e: LocError| {383 let value = self
393 self.0384 .get_raw(
394 .value_cache385 s,
395 .borrow_mut()386 key.clone(),
396 .insert(cache_key.clone(), CacheValue::Errored(e.clone()));387 self.0.this.clone().unwrap_or_else(|| self.clone()),
397 e388 )
398 };389 .map_err(|e| {
390 self.0
391 .value_cache
392 .borrow_mut()
393 .insert(key.clone(), CacheValue::Errored(e.clone()));
394 e
395 })?;
396 self.0.value_cache.borrow_mut().insert(
397 key,
398 match &value {
399 Some(v) => CacheValue::Cached(v.clone()),
400 None => CacheValue::NotFound,
401 },
402 );
403 Ok(value)
404 }
405
406 fn get_raw(&self, s: State, key: IStr, real_this: Self) -> Result<Option<Val>> {
399 let value = match (self.0.this_entries.get(&key), &self.0.sup) {407 match (self.0.this_entries.get(&key), &self.0.sup) {
400 (Some(k), None) => Ok(Some(408 (Some(k), None) => Ok(Some(self.evaluate_this(s, k, real_this)?)),
401 self.evaluate_this(s, k, real_this).map_err(fill_error)?,
402 )),
403 (Some(k), Some(super_obj)) => {409 (Some(k), Some(super_obj)) => {
404 let our = self410 let our = self.evaluate_this(s.clone(), k, real_this.clone())?;
405 .evaluate_this(s.clone(), k, real_this.clone())
406 .map_err(fill_error)?;
407 if k.add {411 if k.add {
408 super_obj412 super_obj
409 .get_raw(s.clone(), key, real_this)413 .get_raw(s.clone(), key, real_this)?
410 .map_err(fill_error)?
411 .map_or(Ok(Some(our.clone())), |v| {414 .map_or(Ok(Some(our.clone())), |v| {
412 Ok(Some(evaluate_add_op(s.clone(), &v, &our)?))415 Ok(Some(evaluate_add_op(s.clone(), &v, &our)?))
413 })416 })
418 (None, Some(super_obj)) => super_obj.get_raw(s, key, real_this),421 (None, Some(super_obj)) => super_obj.get_raw(s, key, real_this),
419 (None, None) => Ok(None),422 (None, None) => Ok(None),
420 }423 }
421 .map_err(fill_error)?;424 }
422 self.0.value_cache.borrow_mut().insert(
423 cache_key,
424 match &value {
425 Some(v) => CacheValue::Cached(v.clone()),
426 None => CacheValue::NotFound,
427 },
428 );
429 Ok(value)
430 }
431 fn evaluate_this(&self, s: State, v: &ObjMember, real_this: Self) -> Result<Val> {425 fn evaluate_this(&self, s: State, v: &ObjMember, real_this: Self) -> Result<Val> {
432 v.invoke426 v.invoke
433 .evaluate(s.clone(), self.0.sup.clone(), Some(real_this))?427 .evaluate(s.clone(), self.0.sup.clone(), Some(real_this))?