ByteKeyRange implements Serializable,
        HasDefaultTracker<
            ByteKeyRange, org.apache.beam.sdk.transforms.splittabledofn.ByteKeyRangeTracker> { public ByteKey interpolateKey(double fraction) { checkArgument( fraction >= 0.0 && fraction < 1.0, "Fraction %s must be in the range [0, 1)", fraction); byte[] startBytes = startKey.getBytes(); byte[] endBytes = endKey.getBytes(); if (endKey.isEmpty()) { startBytes = addHeadByte(startBytes, (byte) 0); endBytes = addHeadByte(endBytes, (byte) 1); } int paddedKeyLength = Math.max(startBytes.length, endBytes.length); BigInteger rangeStartInt = paddedPositiveInt(startBytes, paddedKeyLength); BigInteger rangeEndInt = paddedPositiveInt(endBytes, paddedKeyLength); BigInteger range = rangeEndInt.subtract(rangeStartInt); checkState( !range.equals(BigInteger.ZERO), "Refusing to interpolate for near-empty %s where start and end keys differ only by trailing" + " zero bytes.", this); int bytesNeeded = ((53 - range.bitLength()) + 7) / 8; if (bytesNeeded > 0) { range = range.shiftLeft(bytesNeeded * 8); rangeStartInt = rangeStartInt.shiftLeft(bytesNeeded * 8); paddedKeyLength += bytesNeeded; } BigInteger interpolatedOffset = new BigDecimal(range).multiply(BigDecimal.valueOf(fraction)).toBigInteger(); int outputKeyLength = endKey.isEmpty() ? (paddedKeyLength - 1) : paddedKeyLength; return ByteKey.copyFrom( fixupHeadZeros(rangeStartInt.add(interpolatedOffset).toByteArray(), outputKeyLength)); } private  ByteKeyRange(ByteKey startKey, ByteKey endKey); static ByteKeyRange of(ByteKey startKey, ByteKey endKey); ByteKey getStartKey(); ByteKey getEndKey(); Boolean containsKey(ByteKey key); Boolean overlaps(ByteKeyRange other); List<ByteKey> split(int numSplits); double estimateFractionForKey(ByteKey key); ByteKey interpolateKey(double fraction); ByteKeyRange withStartKey(ByteKey startKey); ByteKeyRange withEndKey(ByteKey endKey); @Override String toString(); @Override boolean equals(@Nullable Object o); @Override int hashCode(); @Override org.apache.beam.sdk.transforms.splittabledofn.ByteKeyRangeTracker newTracker(); static final ByteKeyRange ALL_KEYS; }
@Test public void testInterpolateKey() { assertEqualExceptPadding(ByteKey.of(0x80), ByteKeyRange.ALL_KEYS.interpolateKey(0.5)); ByteKeyRange after0 = ByteKeyRange.of(ByteKey.of(0), ByteKey.EMPTY); assertEqualExceptPadding(ByteKey.of(0x80), after0.interpolateKey(0.5)); ByteKeyRange after00 = ByteKeyRange.of(ByteKey.of(0, 0), ByteKey.EMPTY); assertEqualExceptPadding(ByteKey.of(0x80), after00.interpolateKey(0.5)); ByteKeyRange upToFE = ByteKeyRange.of(ByteKey.EMPTY, ByteKey.of(0xfe)); assertEqualExceptPadding(ByteKey.of(0x7f), upToFE.interpolateKey(0.5)); assertEqualExceptPadding(ByteKey.of(0x40), ByteKeyRange.ALL_KEYS.interpolateKey(0.25)); ByteKeyRange upTo80 = ByteKeyRange.of(ByteKey.EMPTY, ByteKey.of(0x80)); assertEqualExceptPadding(ByteKey.of(0x40), upTo80.interpolateKey(0.5)); ByteKeyRange range30to50 = ByteKeyRange.of(ByteKey.of(0x30), ByteKey.of(0x50)); assertEqualExceptPadding(ByteKey.of(0x40), range30to50.interpolateKey(0.5)); ByteKeyRange range31to4f = ByteKeyRange.of(ByteKey.of(0x30, 0, 1), ByteKey.of(0x4f, 0xff, 0xff, 0, 0)); assertEqualExceptPadding(ByteKey.of(0x40), range31to4f.interpolateKey(0.5)); }
@Test public void testInterpolateKeyIsNotEmpty() { String fmt = "Interpolating %s at fraction 0.0 should not return the empty key"; for (ByteKeyRange range : TEST_RANGES) { range = ByteKeyRange.ALL_KEYS; assertFalse(String.format(fmt, range), range.interpolateKey(0.0).isEmpty()); } }