Skip to content

Commit 49447a7

Browse files
feat(revset): use hints to optimize binary revset evals
Now that we can pass revsets around to limit how many commits a rhs examines during it's evaluation, this change actually starts passing such hints, but only for `intersection()` and `difference()`. This is a crude approach, of course, but it gets the job done and it significantly improves performance for `intersection()` and `difference()`.
1 parent 07cb519 commit 49447a7

File tree

2 files changed

+77
-6
lines changed

2 files changed

+77
-6
lines changed

git-branchless-revset/src/builtins.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ fn fn_none(ctx: &mut Context, name: &str, args: &[Expr], _: &Option<&CommitSet>)
9494

9595
#[instrument]
9696
fn fn_union(ctx: &mut Context, name: &str, args: &[Expr], _: &Option<&CommitSet>) -> EvalResult {
97-
let (lhs, rhs) = eval2(ctx, name, args)?;
97+
let (lhs, rhs) = eval2(ctx, name, args, false)?;
9898
Ok(lhs.union(&rhs))
9999
}
100100

@@ -105,7 +105,7 @@ fn fn_intersection(
105105
args: &[Expr],
106106
_: &Option<&CommitSet>,
107107
) -> EvalResult {
108-
let (lhs, rhs) = eval2(ctx, name, args)?;
108+
let (lhs, rhs) = eval2(ctx, name, args, true)?;
109109
Ok(lhs.intersection(&rhs))
110110
}
111111

@@ -116,19 +116,19 @@ fn fn_difference(
116116
args: &[Expr],
117117
_: &Option<&CommitSet>,
118118
) -> EvalResult {
119-
let (lhs, rhs) = eval2(ctx, name, args)?;
119+
let (lhs, rhs) = eval2(ctx, name, args, true)?;
120120
Ok(lhs.difference(&rhs))
121121
}
122122

123123
#[instrument]
124124
fn fn_only(ctx: &mut Context, name: &str, args: &[Expr], _: &Option<&CommitSet>) -> EvalResult {
125-
let (lhs, rhs) = eval2(ctx, name, args)?;
125+
let (lhs, rhs) = eval2(ctx, name, args, false)?;
126126
Ok(ctx.dag.query_only(lhs, rhs)?)
127127
}
128128

129129
#[instrument]
130130
fn fn_range(ctx: &mut Context, name: &str, args: &[Expr], _: &Option<&CommitSet>) -> EvalResult {
131-
let (lhs, rhs) = eval2(ctx, name, args)?;
131+
let (lhs, rhs) = eval2(ctx, name, args, false)?;
132132
Ok(ctx.dag.query_range(lhs, rhs)?)
133133
}
134134

git-branchless-revset/src/eval.rs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,12 @@ pub(super) fn eval2(
310310
ctx: &mut Context,
311311
function_name: &str,
312312
args: &[Expr],
313+
limit_rhs: bool,
313314
) -> Result<(CommitSet, CommitSet), EvalError> {
314315
match args {
315316
[lhs, rhs] => {
316317
let lhs = eval_inner(ctx, lhs, &None)?;
317-
let rhs = eval_inner(ctx, rhs, &None)?;
318+
let rhs = eval_inner(ctx, rhs, &limit_rhs.then_some(&lhs))?;
318319
Ok((lhs, rhs))
319320
}
320321

@@ -507,6 +508,76 @@ mod tests {
507508
"###);
508509
}
509510

511+
{
512+
let expr = Expr::FunctionCall(
513+
Cow::Borrowed("intersection"),
514+
vec![
515+
Expr::Name(Cow::Owned(test1_oid.to_string())),
516+
Expr::Name(Cow::Owned(test2_oid.to_string())),
517+
],
518+
);
519+
insta::assert_debug_snapshot!(eval_and_sort(&effects, &repo, &mut dag, &expr), @r###"
520+
Ok(
521+
[],
522+
)
523+
"###);
524+
525+
let expr = Expr::FunctionCall(
526+
Cow::Borrowed("intersection"),
527+
vec![
528+
Expr::Name(Cow::Owned(test1_oid.to_string())),
529+
Expr::Name(Cow::Owned(test1_oid.to_string())),
530+
],
531+
);
532+
insta::assert_debug_snapshot!(eval_and_sort(&effects, &repo, &mut dag, &expr), @r###"
533+
Ok(
534+
[
535+
Commit {
536+
inner: Commit {
537+
id: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
538+
summary: "create test1.txt",
539+
},
540+
},
541+
],
542+
)
543+
"###);
544+
}
545+
546+
{
547+
let expr = Expr::FunctionCall(
548+
Cow::Borrowed("difference"),
549+
vec![
550+
Expr::Name(Cow::Owned(test1_oid.to_string())),
551+
Expr::Name(Cow::Owned(test2_oid.to_string())),
552+
],
553+
);
554+
insta::assert_debug_snapshot!(eval_and_sort(&effects, &repo, &mut dag, &expr), @r###"
555+
Ok(
556+
[
557+
Commit {
558+
inner: Commit {
559+
id: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
560+
summary: "create test1.txt",
561+
},
562+
},
563+
],
564+
)
565+
"###);
566+
567+
let expr = Expr::FunctionCall(
568+
Cow::Borrowed("difference"),
569+
vec![
570+
Expr::Name(Cow::Owned(test1_oid.to_string())),
571+
Expr::Name(Cow::Owned(test1_oid.to_string())),
572+
],
573+
);
574+
insta::assert_debug_snapshot!(eval_and_sort(&effects, &repo, &mut dag, &expr), @r###"
575+
Ok(
576+
[],
577+
)
578+
"###);
579+
}
580+
510581
{
511582
let expr = Expr::FunctionCall(
512583
Cow::Borrowed("siblings"),

0 commit comments

Comments
 (0)