Class ByteKeyRange

  • All Implemented Interfaces:
    java.io.Serializable, HasDefaultTracker<ByteKeyRange,​ByteKeyRangeTracker>

    public final class ByteKeyRange
    extends java.lang.Object
    implements java.io.Serializable, HasDefaultTracker<ByteKeyRange,​ByteKeyRangeTracker>
    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).

    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. 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 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:
        java.lang.IllegalArgumentException - if endKey is less than or equal to startKey, unless endKey is empty indicating the maximum possible ByteKey.
        See Also:
        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 java.lang.Boolean containsKey​(ByteKey key)
        Returns true if the specified ByteKey is contained within this range.
      • overlaps

        public java.lang.Boolean overlaps​(ByteKeyRange other)
        Returns true if the specified ByteKeyRange overlaps this range.
      • split

        public java.util.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:
        java.lang.IllegalArgumentException - if the specified number of splits is less than 1
        See Also:
        the ByteKeyRange class Javadoc for more information about split 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:
        java.lang.IllegalArgumentException - if fraction is outside the range [0, 1)
        java.lang.IllegalStateException - if this range cannot be interpolated
        See Also:
        the ByteKeyRange class Javadoc for more information about fraction semantics.
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • equals

        public boolean equals​(@Nullable java.lang.Object o)
        Overrides:
        equals in class java.lang.Object
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class java.lang.Object