difftreelog
perf implement std.setDiff in native
in: master
3 files changed
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth175 // Sets175 // Sets176 ("setMember", builtin_set_member::INST),176 ("setMember", builtin_set_member::INST),177 ("setInter", builtin_set_inter::INST),177 ("setInter", builtin_set_inter::INST),178 ("setDiff", builtin_set_diff::INST),178 // Compat179 // Compat179 ("__compare", builtin___compare::INST),180 ("__compare", builtin___compare::INST),180 ]181 ]crates/jrsonnet-stdlib/src/sets.rsdiffbeforeafterboth71 }71 }72 Ok(ArrValue::lazy(out))72 Ok(ArrValue::lazy(out))73}73}74#[builtin]75#[allow(non_snake_case, clippy::redundant_closure)]76pub fn builtin_set_diff(a: ArrValue, b: ArrValue, keyF: Option<FuncVal>) -> Result<ArrValue> {77 let mut a = a.iter_lazy();78 let mut b = b.iter_lazy();7980 let keyF = keyF81 .unwrap_or(FuncVal::identity())82 .into_native::<((Thunk<Val>,), Val)>();83 let keyF = |v| keyF(v);8485 let mut av = a.next();86 let mut bv = b.next();87 let mut ak = av.clone().map(keyF).transpose()?;88 let mut bk = bv.map(keyF).transpose()?;8990 let mut out = Vec::new();91 while let (Some(ac), Some(bc)) = (&ak, &bk) {92 match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {93 Ordering::Less => {94 // In a, but not in b95 out.push(av.clone().expect("ak != None"));96 av = a.next();97 ak = av.clone().map(keyF).transpose()?;98 }99 Ordering::Greater => {100 bv = b.next();101 bk = bv.map(keyF).transpose()?;102 }103 Ordering::Equal => {104 av = a.next();105 ak = av.clone().map(keyF).transpose()?;106 bv = b.next();107 bk = bv.map(keyF).transpose()?;108 }109 };110 }111 while let Some(ac) = &ak {112 // In a, but not in b113 out.push(av.clone().expect("ak != None"));114 av = a.next();115 ak = av.clone().map(keyF).transpose()?;116 }117 Ok(ArrValue::lazy(out))118}74119crates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth214 aux(a, b, i, j + 1, acc + [b[j]]) tailstrict;214 aux(a, b, i, j + 1, acc + [b[j]]) tailstrict;215 aux(a, b, 0, 0, []),215 aux(a, b, 0, 0, []),216216217 setDiff(a, b, keyF=id)::218 local aux(a, b, i, j, acc) =219 if i >= std.length(a) then220 acc221 else if j >= std.length(b) then222 acc + a[i:]223 else224 if keyF(a[i]) == keyF(b[j]) then225 aux(a, b, i + 1, j + 1, acc) tailstrict226 else if keyF(a[i]) < keyF(b[j]) then227 aux(a, b, i + 1, j, acc + [a[i]]) tailstrict228 else229 aux(a, b, i, j + 1, acc) tailstrict;230 aux(a, b, 0, 0, []) tailstrict,231232 mergePatch(target, patch)::217 mergePatch(target, patch)::233 if std.isObject(patch) then218 if std.isObject(patch) then234 local target_object =219 local target_object =