Skip to content

Commit 216fce5

Browse files
fmeumcopybara-github
authored andcommitted
Also apply NestedSet optimizations to Depset
If the construction of a `NestedSet` involves only a single non-empty transitive set, this set may be returned directly as an optimization. This commit checks for this case when constructing a `Depset` and reuses the corresponding `Depset` if possible. Since `Depset`s that are direct elements of providers are usually unwrapped into their `NestedSet`, this optimization only applies to instances stored in `struct`s as well as reduces allocations. Realizes an optimization proposed by @brentleyjones in https://bazelbuild.slack.com/archives/CA31HN1T3/p1693487067454409?thread_ts=1693484609.534579&cid=CA31HN1T3. Closes #19379. PiperOrigin-RevId: 563679197 Change-Id: I542bbf56784832768ca3bbbd550cc78bfb981ffe
1 parent d57e0a7 commit 216fce5

File tree

2 files changed

+23
-1
lines changed
  • src
    • main/java/com/google/devtools/build/lib/collect/nestedset
    • test/java/com/google/devtools/build/lib/collect/nestedset

2 files changed

+23
-1
lines changed

src/main/java/com/google/devtools/build/lib/collect/nestedset/Depset.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,16 @@ public static Depset fromDirectAndTransitive(
377377
if (builder.isEmpty()) {
378378
return builder.getOrder().emptyDepset();
379379
}
380-
return new Depset(type, builder.build());
380+
NestedSet<Object> set = builder.build();
381+
// If the nested set was optimized to one of the transitive elements, reuse the corresponding
382+
// depset.
383+
for (Depset x : transitive) {
384+
if (x.getSet() == set) {
385+
return x;
386+
}
387+
}
388+
389+
return new Depset(type, set);
381390
}
382391

383392
/** An exception thrown when validation fails on the type of elements of a nested set. */

src/test/java/com/google/devtools/build/lib/collect/nestedset/DepsetTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,4 +419,17 @@ public void testEmptyDepsetInternedPerOrder() throws Exception {
419419
assertThat(ev.lookup("stable1")).isNotSameInstanceAs(ev.lookup("preorder1"));
420420
assertThat(ev.lookup("stable2")).isNotSameInstanceAs(ev.lookup("preorder2"));
421421
}
422+
423+
@Test
424+
public void testSingleNonEmptyTransitiveAndNoDirectsUnwrapped() throws Exception {
425+
ev.exec(
426+
"inner = depset([1, 2, 3])", "outer = depset(transitive = [depset(), inner, depset()])");
427+
assertThat(ev.lookup("outer")).isSameInstanceAs(ev.lookup("inner"));
428+
}
429+
430+
@Test
431+
public void testSingleNonEmptyTransitiveAndMatchingDirectUnwrapped() throws Exception {
432+
ev.exec("inner = depset([1])", "outer = depset([1], transitive = [depset(), inner, depset()])");
433+
assertThat(ev.lookup("outer")).isSameInstanceAs(ev.lookup("inner"));
434+
}
422435
}

0 commit comments

Comments
 (0)