-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Fix aggregation memory revoke when operator is finishing #164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8b565e5
31f0197
f945a57
0162c92
f7f1701
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,9 +36,11 @@ | |
| import java.util.Optional; | ||
|
|
||
| import static com.google.common.base.Preconditions.checkState; | ||
| import static com.google.common.base.Verify.verify; | ||
| import static com.google.common.collect.ImmutableList.toImmutableList; | ||
| import static com.google.common.util.concurrent.Futures.immediateFuture; | ||
| import static io.airlift.concurrent.MoreFutures.getFutureValue; | ||
| import static io.prestosql.operator.Operator.NOT_BLOCKED; | ||
| import static java.lang.Math.max; | ||
|
|
||
| public class SpillableHashAggregationBuilder | ||
|
|
@@ -68,6 +70,7 @@ public class SpillableHashAggregationBuilder | |
|
|
||
| private long hashCollisions; | ||
| private double expectedHashCollisions; | ||
| private boolean producingOutput; | ||
|
|
||
| public SpillableHashAggregationBuilder( | ||
| List<AccumulatorFactory> accumulatorFactories, | ||
|
|
@@ -112,8 +115,15 @@ public Work<?> processPage(Page page) | |
| public void updateMemory() | ||
| { | ||
| checkState(spillInProgress.isDone()); | ||
| localUserMemoryContext.setBytes(emptyHashAggregationBuilderSize); | ||
| localRevocableMemoryContext.setBytes(hashAggregationBuilder.getSizeInMemory() - emptyHashAggregationBuilderSize); | ||
|
|
||
| if (producingOutput) { | ||
| localRevocableMemoryContext.setBytes(0); | ||
| localUserMemoryContext.setBytes(hashAggregationBuilder.getSizeInMemory()); | ||
| } | ||
| else { | ||
| localUserMemoryContext.setBytes(emptyHashAggregationBuilderSize); | ||
| localRevocableMemoryContext.setBytes(hashAggregationBuilder.getSizeInMemory() - emptyHashAggregationBuilderSize); | ||
| } | ||
| } | ||
|
|
||
| public long getSizeInMemory() | ||
|
|
@@ -154,9 +164,13 @@ private boolean hasPreviousSpillCompletedSuccessfully() | |
| @Override | ||
| public ListenableFuture<?> startMemoryRevoke() | ||
| { | ||
| checkState(spillInProgress.isDone()); | ||
| spillToDisk(); | ||
| return spillInProgress; | ||
| if (producingOutput) { | ||
| // all revocable memory has been released in buildResult method | ||
| verify(localRevocableMemoryContext.getBytes() == 0); | ||
| return NOT_BLOCKED; | ||
findepi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| return spillToDisk(); | ||
sopel39 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -174,6 +188,22 @@ private boolean shouldMergeWithMemory(long memorySize) | |
| public WorkProcessor<Page> buildResult() | ||
| { | ||
| checkState(hasPreviousSpillCompletedSuccessfully(), "Previous spill hasn't yet finished"); | ||
| producingOutput = true; | ||
|
|
||
| // Convert revocable memory to user memory as returned WorkProcessor holds on to memory so we no longer can revoke. | ||
| if (localRevocableMemoryContext.getBytes() > 0) { | ||
| long currentRevocableBytes = localRevocableMemoryContext.getBytes(); | ||
| localRevocableMemoryContext.setBytes(0); | ||
| if (!localUserMemoryContext.trySetBytes(localUserMemoryContext.getBytes() + currentRevocableBytes)) { | ||
| // TODO: this might fail (even though we have just released memory), but we don't | ||
| // have a proper way to atomically convert memory reservations | ||
sopel39 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| localRevocableMemoryContext.setBytes(currentRevocableBytes); | ||
sopel39 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // spill since revocable memory could not be converted to user memory immediately | ||
| // TODO: this should be asynchronous | ||
| getFutureValue(spillToDisk()); | ||
|
||
| updateMemory(); | ||
| } | ||
| } | ||
|
|
||
| if (!spiller.isPresent()) { | ||
| return hashAggregationBuilder.buildResult(); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.