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.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/sets.rs
+++ b/crates/jrsonnet-stdlib/src/sets.rs
@@ -71,3 +71,48 @@
}
Ok(ArrValue::lazy(out))
}
+#[builtin]
+#[allow(non_snake_case, clippy::redundant_closure)]
+pub fn builtin_set_diff(a: ArrValue, b: ArrValue, keyF: Option<FuncVal>) -> Result<ArrValue> {
+ let mut a = a.iter_lazy();
+ let mut b = b.iter_lazy();
+
+ let keyF = keyF
+ .unwrap_or(FuncVal::identity())
+ .into_native::<((Thunk<Val>,), Val)>();
+ let keyF = |v| keyF(v);
+
+ let mut av = a.next();
+ let mut bv = b.next();
+ let mut ak = av.clone().map(keyF).transpose()?;
+ let mut bk = bv.map(keyF).transpose()?;
+
+ let mut out = Vec::new();
+ while let (Some(ac), Some(bc)) = (&ak, &bk) {
+ match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {
+ Ordering::Less => {
+ // In a, but not in b
+ out.push(av.clone().expect("ak != None"));
+ av = a.next();
+ ak = av.clone().map(keyF).transpose()?;
+ }
+ Ordering::Greater => {
+ bv = b.next();
+ bk = bv.map(keyF).transpose()?;
+ }
+ Ordering::Equal => {
+ av = a.next();
+ ak = av.clone().map(keyF).transpose()?;
+ bv = b.next();
+ bk = bv.map(keyF).transpose()?;
+ }
+ };
+ }
+ while let Some(ac) = &ak {
+ // In a, but not in b
+ out.push(av.clone().expect("ak != None"));
+ av = a.next();
+ ak = av.clone().map(keyF).transpose()?;
+ }
+ Ok(ArrValue::lazy(out))
+}
crates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/std.jsonnet
+++ b/crates/jrsonnet-stdlib/src/std.jsonnet
@@ -214,21 +214,6 @@
aux(a, b, i, j + 1, acc + [b[j]]) tailstrict;
aux(a, b, 0, 0, []),
- setDiff(a, b, keyF=id)::
- local aux(a, b, i, j, acc) =
- if i >= std.length(a) then
- acc
- else if j >= std.length(b) then
- acc + a[i:]
- else
- if keyF(a[i]) == keyF(b[j]) then
- aux(a, b, i + 1, j + 1, acc) tailstrict
- else if keyF(a[i]) < keyF(b[j]) then
- aux(a, b, i + 1, j, acc + [a[i]]) tailstrict
- else
- aux(a, b, i, j + 1, acc) tailstrict;
- aux(a, b, 0, 0, []) tailstrict,
-
mergePatch(target, patch)::
if std.isObject(patch) then
local target_object =