Skip to content

Commit 6a4ce21

Browse files
committed
Use unsigned integer math to calculate progress in GrowableOffsetRangeTracker since the difference between two offsets does not exceed the maximum value of the unsigned representation.
1 parent 9039608 commit 6a4ce21

1 file changed

Lines changed: 6 additions & 22 deletions

File tree

sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/splittabledofn/GrowableOffsetRangeTracker.java

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.math.MathContext;
2424
import org.apache.beam.sdk.io.range.OffsetRange;
2525
import org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.base.Suppliers;
26+
import org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.primitives.UnsignedLong;
2627

2728
/**
2829
* An {@link OffsetRangeTracker} for tracking a growable offset range. {@code Long.MAX_VALUE} is
@@ -68,6 +69,7 @@ public GrowableOffsetRangeTracker(long start, RangeEndEstimator rangeEndEstimato
6869
this.rangeEndEstimator = checkNotNull(rangeEndEstimator);
6970
}
7071

72+
// TODO(sjvanrossum): Use UnsignedLong instead of BigDecimal for splitting ranges
7173
@Override
7274
public SplitResult<OffsetRange> trySplit(double fractionOfRemainder) {
7375
// If current tracking range is no longer growable, split it as a normal range.
@@ -115,30 +117,12 @@ public Progress getProgress() {
115117
return super.getProgress();
116118
}
117119

118-
// Convert to BigDecimal in computation to prevent overflow, which may result in lost of
119-
// precision.
120-
BigDecimal estimateRangeEnd = BigDecimal.valueOf(rangeEndEstimator.estimate());
121-
122-
if (lastAttemptedOffset == null) {
123-
return Progress.from(
124-
0,
125-
estimateRangeEnd
126-
.subtract(BigDecimal.valueOf(range.getFrom()), MathContext.DECIMAL128)
127-
.max(BigDecimal.ZERO)
128-
.doubleValue());
129-
}
120+
final long completedEnd = lastAttemptedOffset == null ? range.getFrom() : lastAttemptedOffset;
121+
final long remainingEnd = Math.max(completedEnd, rangeEndEstimator.estimate());
130122

131-
BigDecimal workRemaining =
132-
estimateRangeEnd
133-
.subtract(BigDecimal.valueOf(lastAttemptedOffset), MathContext.DECIMAL128)
134-
.max(BigDecimal.ZERO);
135-
BigDecimal totalWork =
136-
estimateRangeEnd
137-
.max(BigDecimal.valueOf(lastAttemptedOffset))
138-
.subtract(BigDecimal.valueOf(range.getFrom()), MathContext.DECIMAL128);
139123
return Progress.from(
140-
totalWork.subtract(workRemaining, MathContext.DECIMAL128).doubleValue(),
141-
workRemaining.doubleValue());
124+
UnsignedLong.fromLongBits(completedEnd - range.getFrom()).doubleValue(),
125+
UnsignedLong.fromLongBits(remainingEnd - completedEnd).doubleValue());
142126
}
143127

144128
@Override

0 commit comments

Comments
 (0)