Skip to content

Commit 21c5a6d

Browse files
committed
Cleanup DistinctWindowAccumulator
Use exact distinct positions count instead of estimating the size, clean up control flow to handle no distinct positions earlier.
1 parent 5fa18ec commit 21c5a6d

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

core/trino-main/src/main/java/io/trino/operator/MarkDistinctHash.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ private MarkDistinctHash(MarkDistinctHash other)
4242
nextDistinctId = other.nextDistinctId;
4343
}
4444

45+
public long getGroupCount()
46+
{
47+
return groupByHash.getGroupCount();
48+
}
49+
4550
public long getEstimatedSize()
4651
{
4752
return groupByHash.getEstimatedSize();

core/trino-main/src/main/java/io/trino/operator/aggregation/DistinctWindowAccumulator.java

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,13 @@
3030
import io.trino.spi.function.WindowAccumulator;
3131
import io.trino.spi.function.WindowIndex;
3232
import io.trino.spi.type.Type;
33-
import it.unimi.dsi.fastutil.ints.IntArrayList;
3433

3534
import java.util.List;
3635

3736
import static com.google.common.base.Preconditions.checkArgument;
3837
import static com.google.common.base.Preconditions.checkState;
3938
import static io.trino.spi.type.BooleanType.BOOLEAN;
40-
import static java.lang.Math.min;
39+
import static java.lang.Math.toIntExact;
4140
import static java.util.Objects.requireNonNull;
4241

4342
public class DistinctWindowAccumulator
@@ -128,39 +127,46 @@ public void addInput(WindowIndex index, int startPosition, int endPosition)
128127

129128
private void indexCurrentPage(Page page)
130129
{
130+
long initialGroupCount = hash.getGroupCount();
131131
Work<Block> work = hash.markDistinctRows(page);
132132
checkState(work.process());
133133
Block distinctMask = work.getResult();
134134

135135
int positionCount = distinctMask.getPositionCount();
136136
checkArgument(positionCount == page.getPositionCount(), "Page position count does not match distinct mask position count");
137-
PagesIndex pagesIndex = pagesIndexFactory.newPagesIndex(argumentTypes, positionCount);
137+
138+
int distinctPositions = toIntExact(hash.getGroupCount() - initialGroupCount);
139+
if (distinctPositions == 0) {
140+
return;
141+
}
142+
PagesIndex pagesIndex = pagesIndexFactory.newPagesIndex(argumentTypes, distinctPositions);
138143

139144
if (distinctMask instanceof RunLengthEncodedBlock) {
140-
if (test(distinctMask, 0)) {
141-
// all positions selected
142-
pagesIndex.addPage(page);
143-
}
145+
// all positions selected
146+
checkState(test(distinctMask, 0), "all positions must be distinct");
147+
pagesIndex.addPage(page);
144148
}
145149
else {
146-
IntArrayList selectedPositions = new IntArrayList(min(128, positionCount));
150+
int[] selectedPositions = new int[distinctPositions];
151+
int selectedIndex = 0;
147152
for (int position = 0; position < positionCount; position++) {
148153
if (test(distinctMask, position)) {
149-
selectedPositions.add(position);
154+
selectedPositions[selectedIndex++] = position;
150155
}
151156
}
157+
checkState(selectedIndex == selectedPositions.length, "Invalid positions in distinct mask");
152158

153159
Block[] filteredBlocks = new Block[argumentChannels.size()];
154160
for (int channel = 0; channel < argumentChannels.size(); channel++) {
155-
filteredBlocks[channel] = page.getBlock(channel).copyPositions(selectedPositions.elements(), 0, selectedPositions.size());
161+
filteredBlocks[channel] = page.getBlock(channel).copyPositions(selectedPositions, 0, selectedPositions.length);
156162
}
157-
pagesIndex.addPage(new Page(selectedPositions.size(), filteredBlocks));
163+
pagesIndex.addPage(new Page(selectedPositions.length, filteredBlocks));
158164
}
159165
int selectedPositionsCount = pagesIndex.getPositionCount();
160-
if (selectedPositionsCount > 0) {
161-
PagesWindowIndex selectedWindowIndex = new PagesWindowIndex(pagesIndex, 0, selectedPositionsCount);
162-
delegate.addInput(selectedWindowIndex, 0, selectedPositionsCount - 1);
163-
}
166+
checkState(selectedPositionsCount == distinctPositions, "unexpected pagesIndex positions: %s <> %s", selectedPositionsCount, distinctPositions);
167+
168+
PagesWindowIndex selectedWindowIndex = new PagesWindowIndex(pagesIndex, 0, selectedPositionsCount);
169+
delegate.addInput(selectedWindowIndex, 0, selectedPositionsCount - 1);
164170
}
165171

166172
private static boolean test(Block block, int position)

0 commit comments

Comments
 (0)