com.google.cloud.dataflow.sdk.io.range

## Class ByteKeyRange

- java.lang.Object
- - com.google.cloud.dataflow.sdk.io.range.ByteKeyRange

All Implemented Interfaces:
  Serializable

    public final class ByteKeyRange
    extends Object
    implements Serializable

A class representing a range of `ByteKeys`.

Instances of `ByteKeyRange` are immutable.

A `ByteKeyRange` enforces the restriction that its start and end keys must form a valid, non-empty range `[startKey, endKey)` that is inclusive of the start key and exclusive of the end key.

When the end key is empty, it is treated as the largest possible key.

### Interpreting `ByteKey` in a `ByteKeyRange`

The primary role of `ByteKeyRange` is to provide functionality for `estimateFractionForKey(ByteKey)`, `interpolateKey(double)`, and `split(int)`, which are used for Google Cloud Dataflow's Autoscaling and Dynamic Work Rebalancing features.

`ByteKeyRange` implements these features by treating a `ByteKey`'s underlying `byte[]` as the binary expansion of floating point numbers in the range `[0.0, 1.0]`. For example, the keys `ByteKey.of(0x80)`, `ByteKey.of(0xc0)`, and `ByteKey.of(0xe0)` are interpreted as `0.5`, `0.75`, and `0.875` respectively. The empty `ByteKey.EMPTY` is interpreted as `0.0` when used as the start of a range and `1.0` when used as the end key.

Key interpolation, fraction estimation, and range splitting are all interpreted in these floating-point semantics. See the respective implementations for further details. Note: the underlying implementations of these functions use `BigInteger` and `BigDecimal`, so they can be slow and should not be called in hot loops. Dataflow's dynamic work rebalancing will only invoke these functions during periodic control operations, so they are not called on the critical path.

See Also:
  `ByteKey`, Serialized Form

### Field Summary

Fields
`static ByteKeyRange` `ALL_KEYS` The range of all keys, with empty start and end keys.

### Method Summary

All Methods Static Methods Instance Methods Concrete Methods
`Boolean` `containsKey(ByteKey key)` Returns `true` if the specified `ByteKey` is contained within this range.
`boolean` `equals(Object o)`
`double` `estimateFractionForKey(ByteKey key)` Returns the fraction of this range `[startKey, endKey)` that is in the interval `[startKey, key)`.
`ByteKey` `getEndKey()` Returns the `ByteKey` representing the upper bound of this `ByteKeyRange`.
`ByteKey` `getStartKey()` Returns the `ByteKey` representing the lower bound of this `ByteKeyRange`.
`int` `hashCode()`
`ByteKey` `interpolateKey(double fraction)` Returns a `ByteKey` `key` such that `[startKey, key)` represents approximately the specified fraction of the range `[startKey, endKey)`.
`static ByteKeyRange` `of(ByteKey startKey, ByteKey endKey)` Creates a new `ByteKeyRange` with the given start and end keys.
`Boolean` `overlaps(ByteKeyRange other)` Returns `true` if the specified `ByteKeyRange` overlaps this range.
`List<ByteKey>` `split(int numSplits)` Returns a list of up to `numSplits + 1` `ByteKeys` in ascending order, where the keys have been interpolated to form roughly equal sub-ranges of this `ByteKeyRange`, assuming a uniform distribution of keys within this range.
`String` `toString()`
`ByteKeyRange` `withEndKey(ByteKey endKey)` Returns new `ByteKeyRange` like this one, but with the specified end key.
`ByteKeyRange` `withStartKey(ByteKey startKey)` Returns new `ByteKeyRange` like this one, but with the specified start key.

### Methods inherited from class java.lang.Object

`clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

### Field Detail

#### ALL_KEYS

    public static final ByteKeyRange ALL_KEYS

The range of all keys, with empty start and end keys.

### Method Detail

#### of

    public static ByteKeyRange of(ByteKey startKey,
                                  ByteKey endKey)

Creates a new `ByteKeyRange` with the given start and end keys.

Note that if `endKey` is empty, it is treated as the largest possible key.

Throws:
  `IllegalArgumentException` - if `endKey` is less than or equal to `startKey`, unless `endKey` is empty indicating the maximum possible `ByteKey`.
See Also:
  `ByteKeyRange`

#### getStartKey

    public ByteKey getStartKey()

Returns the `ByteKey` representing the lower bound of this `ByteKeyRange`.

#### getEndKey

    public ByteKey getEndKey()

Returns the `ByteKey` representing the upper bound of this `ByteKeyRange`.

Note that if `endKey` is empty, it is treated as the largest possible key.

#### containsKey

    public Boolean containsKey(ByteKey key)

Returns `true` if the specified `ByteKey` is contained within this range.

#### overlaps

    public Boolean overlaps(ByteKeyRange other)

Returns `true` if the specified `ByteKeyRange` overlaps this range.

#### split

    public List<ByteKey> split(int numSplits)

Returns a list of up to `numSplits + 1` `ByteKeys` in ascending order, where the keys have been interpolated to form roughly equal sub-ranges of this `ByteKeyRange`, assuming a uniform distribution of keys within this range.

The first `ByteKey` in the result is guaranteed to be equal to `getStartKey()`, and the last `ByteKey` in the result is guaranteed to be equal to `getEndKey()`. Thus the resulting list exactly spans the same key range as this `ByteKeyRange`.

Note that the number of keys returned is not always equal to `numSplits + 1`. Specifically, if this range is unsplittable (e.g., because the start and end keys are equal up to padding by zero bytes), the list returned will only contain the start and end key.

Throws:
  `IllegalArgumentException` - if the specified number of splits is < 1
See Also:
  `the ByteKeyRange class Javadoc for more information about split semantics.`

#### estimateFractionForKey

    public double estimateFractionForKey(ByteKey key)

Returns the fraction of this range `[startKey, endKey)` that is in the interval `[startKey, key)`.

Throws:
  `IllegalArgumentException` - if `key` does not fall within this range
See Also:
  `the ByteKeyRange class Javadoc for more information about fraction semantics.`

#### interpolateKey

    public ByteKey interpolateKey(double fraction)

Returns a `ByteKey` `key` such that `[startKey, key)` represents approximately the specified fraction of the range `[startKey, endKey)`. The interpolation is computed assuming a uniform distribution of keys.

For example, given the largest possible range (defined by empty start and end keys), the fraction `0.5` will return the `ByteKey.of(0x80)`, which will also be returned for ranges `[0x40, 0xc0)` and `[0x6f, 0x91)`.

The key returned will never be empty.

Throws:
  `IllegalArgumentException` - if `fraction` is outside the range [0, 1)
  `IllegalStateException` - if this range cannot be interpolated
See Also:
  `the ByteKeyRange class Javadoc for more information about fraction semantics.`

#### withStartKey

    public ByteKeyRange withStartKey(ByteKey startKey)

Returns new `ByteKeyRange` like this one, but with the specified start key.

#### withEndKey

    public ByteKeyRange withEndKey(ByteKey endKey)

Returns new `ByteKeyRange` like this one, but with the specified end key.

#### toString

    public String toString()

Overrides:
  `toString` in class `Object`

#### equals

    public boolean equals(Object o)

Overrides:
  `equals` in class `Object`

#### hashCode

    public int hashCode()

Overrides:
  `hashCode` in class `Object`