Class KeyRanges

java.lang.Object
io.permazen.kv.KeyRanges
All Implemented Interfaces:
KeyFilter, Cloneable, Iterable<KeyRange>
Direct Known Subclasses:
Reads

public class KeyRanges extends Object implements Iterable<KeyRange>, KeyFilter, Cloneable
A fixed set of KeyRange instances that can be treated as a unified whole, in particular as a KeyFilter.

Instances are not thread safe.

See Also:
  • Constructor Details

    • KeyRanges

      public KeyRanges(Iterable<? extends KeyRange> ranges)
      Constructor.

      Creates an instance that contains all keys contained by any of the KeyRanges in ranges. The given ranges may be empty, adjacent, overlap, and/or be listed in any order; this constructor will normalize them.

      Parameters:
      ranges - individual key ranges
      Throws:
      IllegalArgumentException - if ranges or any KeyRange therein is null
    • KeyRanges

      public KeyRanges(Stream<? extends KeyRange> ranges)
      Constructor.

      Creates an instance that contains all keys contained by any of the KeyRanges in ranges. The given ranges may be empty, adjacent, overlap, and/or be listed in any order; this constructor will normalize them.

      Parameters:
      ranges - individual key ranges
      Throws:
      IllegalArgumentException - if ranges or any KeyRange therein is null
    • KeyRanges

      public KeyRanges(KeyRange... ranges)
      Constructor.

      Creates an instance that contains all keys contained by any of the KeyRanges in ranges. The given ranges may be empty, adjacent, overlap, and/or be listed in any order; this constructor will normalize them.

      Parameters:
      ranges - individual key ranges
      Throws:
      IllegalArgumentException - if ranges or any KeyRange therein is null
    • KeyRanges

      public KeyRanges(KeyRanges ranges)
      Copy constructor.
      Parameters:
      ranges - value to copy
      Throws:
      IllegalArgumentException - if ranges is null
    • KeyRanges

      public KeyRanges(KeyRange range)
      Constructor for an instance containing a single range.
      Parameters:
      range - single range
      Throws:
      IllegalArgumentException - if range is null
    • KeyRanges

      public KeyRanges(byte[] key)
      Constructor for an instance containing a single range containing a single key.
      Parameters:
      key - key in range; must not be null
      Throws:
      IllegalArgumentException - if key is null
    • KeyRanges

      public KeyRanges(byte[] min, byte[] max)
      Constructor for an instance containing a single range.
      Parameters:
      min - minimum key (inclusive); must not be null
      max - maximum key (exclusive), or null for no maximum
      Throws:
      IllegalArgumentException - if min > max
    • KeyRanges

      public KeyRanges(InputStream input) throws IOException
      Constructor to deserialize an instance created by serialize().

      Equivalent to KeyRanges(input, false).

      Parameters:
      input - input stream containing data from serialize()
      Throws:
      IOException - if an I/O error occurs
      EOFException - if the input ends unexpectedly
      IllegalArgumentException - if input is null
      IllegalArgumentException - if input is invalid
    • KeyRanges

      public KeyRanges(InputStream input, boolean immutable) throws IOException
      Constructor to deserialize an instance created by serialize().
      Parameters:
      input - input stream containing data from serialize()
      immutable - whether this new instance should be immutable
      Throws:
      IOException - if an I/O error occurs
      EOFException - if the input ends unexpectedly
      IllegalArgumentException - if input is null
      IllegalArgumentException - if input is invalid
  • Method Details

    • forPrefix

      public static KeyRanges forPrefix(byte[] prefix)
      Construct an instance containing a single range corresponding to all keys with the given prefix.
      Parameters:
      prefix - prefix of all keys in the range
      Returns:
      instance containing all keys prefixed by prefix
      Throws:
      IllegalArgumentException - if prefix is null
    • empty

      public static KeyRanges empty()
      Create an empty instance containing zero ranges.
      Returns:
      empty instance
    • full

      public static KeyRanges full()
      Create a "full" instance containing a single KeyRange that contains all keys.
      Returns:
      instance spanning all keys
    • asList

      public List<KeyRange> asList()
      Get the KeyRanges underlying with this instance as a list.

      The returned KeyRanges will be listed in order. Modifications to the returned list do not affect this instance.

      Returns:
      minimal list of KeyRanges sorted by key range
    • asSet

      public NavigableSet<KeyRange> asSet()
      Get a view of the KeyRanges underlying with this instance as a sorted set.

      The returned KeyRanges will be sorted in order according to KeyRange.SORT_BY_MIN.

      Returns:
      view of this instance as a minimal, unmodifiable sorted set of KeyRanges sorted by minimum key
    • size

      public int size()
      Determine the number of individual KeyRanges contained in this instance.
      Returns:
      size of this instance
    • clear

      public void clear()
      Remove all keys from this instance.
      Throws:
      UnsupportedOperationException - if this instance is immutable
    • isEmpty

      public boolean isEmpty()
      Determine whether this instance is empty, i.e., contains no keys.
      Returns:
      true if this instance is empty
    • isFull

      public boolean isFull()
      Determine whether this instance is "full", i.e., contains all keys.
      Returns:
      true if this instance is full
    • getMin

      public byte[] getMin()
      Get the minimum key contained by this instance (inclusive).
      Returns:
      minimum key contained by this instance (inclusive), or null if this instance isEmpty()
    • getMax

      public byte[] getMax()
      Get the maximum key contained by this instance (exclusive).
      Returns:
      maximum key contained by this instance (exclusive), or null if there is no upper bound, or this instance isEmpty()
    • prefixedBy

      public KeyRanges prefixedBy(byte[] prefix)
      Create a new instance from this one, with each KeyRange prefixed by the given byte sequence.
      Parameters:
      prefix - prefix to apply to this instance
      Returns:
      prefixed instance
      Throws:
      IllegalArgumentException - if prefix is null
    • inverse

      public KeyRanges inverse()
      Create the inverse of this instance. The inverse contains all keys not contained by this instance.
      Returns:
      the inverse of this instance
    • contains

      public boolean contains(KeyRanges ranges)
      Determine whether this instance contains the given KeyRanges, i.e., all keys contained by the given KeyRanges are also contained by this instance.
      Parameters:
      ranges - other instance to test
      Returns:
      true if this instance contains ranges, otherwise false
      Throws:
      IllegalArgumentException - if ranges is null
    • contains

      public boolean contains(KeyRange range)
      Determine whether this instance contains the given KeyRange, i.e., all keys contained by the given KeyRange are also contained by this instance.
      Parameters:
      range - key range to test
      Returns:
      true if this instance contains range, otherwise false
      Throws:
      IllegalArgumentException - if range is null
    • intersects

      public boolean intersects(KeyRange range)
      Determine whether this instance intersects the given KeyRange, i.e., there exists at least one key contained in both.
      Parameters:
      range - key range to test
      Returns:
      true if this instance intersects range, otherwise false
      Throws:
      IllegalArgumentException - if range is null
    • findKey

      public KeyRange[] findKey(byte[] key)
      Find the contiguous KeyRange(s) within this instance containing, or adjacent to, the given key.

      This method returns an array of length two: if this instance contains key then both elements are the same Java object, namely, the KeyRange that contains key; otherwise, the first element is the nearest KeyRange to the left of key, or null if none exists, and the second element is the KeyRange to the right of key, or null if none exists. Note if this instance is empty then { null, null } is returned.

      Parameters:
      key - key to find
      Returns:
      array with the containing KeyRange or nearest neighbor to the left (or null) and the containing KeyRange or nearest neighbor to the right (or null)
      Throws:
      IllegalArgumentException - if key is null
    • add

      public void add(KeyRange range)
      Add all the keys in the given KeyRange to this instance.
      Parameters:
      range - key range to add
      Throws:
      IllegalArgumentException - if range is null
      UnsupportedOperationException - if this instance is immutable
    • remove

      public void remove(KeyRange range)
      Remove all the keys in the given KeyRange from this instance.
      Parameters:
      range - range to remove
      Throws:
      IllegalArgumentException - if range is null
      UnsupportedOperationException - if this instance is immutable
    • intersect

      public void intersect(KeyRange range)
      Remove all the keys not also in the given KeyRange from this instance.
      Parameters:
      range - key range to intersect with
      Throws:
      IllegalArgumentException - if range is null
      UnsupportedOperationException - if this instance is immutable
    • add

      public void add(KeyRanges ranges)
      Add all the key ranges in the given KeyRanges to this instance.
      Parameters:
      ranges - key ranges to add
      Throws:
      IllegalArgumentException - if ranges is null
      UnsupportedOperationException - if this instance is immutable
    • remove

      public void remove(KeyRanges ranges)
      Remove all the key ranges in the given KeyRanges from this instance.
      Parameters:
      ranges - key ranges to remove
      Throws:
      IllegalArgumentException - if ranges is null
    • intersect

      public void intersect(KeyRanges ranges)
      Remove all key ranges not also in the given KeyRanges from this instance.

      Equivalent to remove(ranges.inverse()).

      Parameters:
      ranges - key ranges to intersect with
      Throws:
      IllegalArgumentException - if ranges is null
      UnsupportedOperationException - if this instance is immutable
    • iterator

      public Iterator<KeyRange> iterator()
      Specified by:
      iterator in interface Iterable<KeyRange>
    • serialize

      public void serialize(OutputStream out) throws IOException
      Serialize this instance.
      Parameters:
      out - output
      Throws:
      IOException - if an error occurs
      IllegalArgumentException - if out is null
    • serializedLength

      public long serializedLength()
      Calculate the number of bytes required to serialize this instance via serialize().
      Returns:
      number of serialized bytes
    • deserializeIterator

      public static Iterator<KeyRange> deserializeIterator(InputStream input)
      Deserialize an instance created by serialize() in the form of an iterator of the individual KeyRanges.

      If an IOException is thrown while reading, the returned Iterator will throw a RuntimeException wrapping it. If invalid data is encountered, the returned Iterator will throw an IllegalArgumentException.

      Parameters:
      input - input stream containing data from serialize()
      Returns:
      deserialized iteration of KeyRanges
      Throws:
      IllegalArgumentException - if input is null
    • contains

      public boolean contains(byte[] key)
      Description copied from interface: KeyFilter
      Determine whether this instance contains the given key.
      Specified by:
      contains in interface KeyFilter
      Parameters:
      key - key to test
      Returns:
      true if key is contained by this instance, otherwise false
    • seekHigher

      public byte[] seekHigher(byte[] key)
      Description copied from interface: KeyFilter
      Skip over the largest possible uncontained region in an upward direction.

      This method should return an inclusive lower bound on all keys greater than or equal to key that are contained by this instance. The bound does not have to be tight, but the tighter the better.

      A value of null may be returned to indicate that no key greater than or equal to key is contained by this instance.

      If key is contained by this instance, this method must return key; if key is not contained by this instance, this method must return a key strictly higher than key or null.

      Specified by:
      seekHigher in interface KeyFilter
      Parameters:
      key - starting key
      Returns:
      a lower bound (inclusive) for contained keys greater than or equal to key, or null if no key greater than or equal to key is contained by this instance
    • seekLower

      public byte[] seekLower(byte[] key)
      Description copied from interface: KeyFilter
      Skip over the largest possible uncontained region in a downward direction.

      This method should return an exclusive upper bound on all keys strictly less than key that are contained by this instance. The bound does not have to be tight, but the tighter the better.

      A value of null may be returned to indicate that no key strictly less than key is contained by this instance.

      For the purposes of this method, an empty byte[] array represents an upper bound greater than all byte[] keys. This interpretation applies both to the key parameter and returned value. Note that this implies an empty array cannot be returned to indicate that no keys exist (instead, return null).

      This method must either return null or a value less than or equal to key (using the above interpretation for empty arrays).

      Specified by:
      seekLower in interface KeyFilter
      Parameters:
      key - starting key, or an empty array to indicate a maximal upper bound
      Returns:
      an upper bound (exclusive) for contained keys strictly less that key, null if no key strictly less than key is contained by this instance, or an empty byte[] array to indicate an upper bound greater than all byte[] keys (which implies key was also empty)
    • clone

      public KeyRanges clone()
      Clone this instance.

      The returned clone will always be mutable, even if this instance is not.

      Overrides:
      clone in class Object
    • readOnlySnapshot

      public KeyRanges readOnlySnapshot()
      Return an immutable snapshot of this instance.
      Returns:
      immutable snapshot
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object