Class Versionstamp

java.lang.Object
com.apple.foundationdb.tuple.Versionstamp
All Implemented Interfaces:
Comparable<Versionstamp>

public class Versionstamp extends Object implements Comparable<Versionstamp>
Used to represent values written by versionstamp operations with a Tuple. This wraps a single array which should contain twelve bytes. The first ten bytes are the "transaction" version, and they are usually assigned by the database in such a way that all transactions receive a different version that is consistent with a serialization order of the transactions within the database. (One can use the Transaction.getVersionstamp() method to retrieve this version from a Transaction.) This also implies that the transaction version of newly committed transactions will be monotonically increasing over time. The final two bytes are the "user" version and should be set by the client. This allows the user to use this class to impose a total order of items across multiple transactions in the database in a consistent and conflict-free way. The user can elect to ignore this parameter by instantiating the class with the parameterless incomplete() and one-parameter complete static initializers. If they do so, then versions are written with a default (constant) user version.

All Versionstamps can exist in one of two states: "incomplete" and "complete". An "incomplete" Versionstamp is a Versionstamp that has not been initialized with a meaningful transaction version. For example, this might be used with a Versionstamp that one wants to fill in with the current transaction's version information. A "complete" Versionstamp, in contradistinction, is one that has been assigned a meaningful transaction version. This is usually the case if one is reading back a Versionstamp from the database.

Example usage might be to do something like the following:

 
  CompletableFuture<byte[]> trVersionFuture = db.run((Transaction tr) -> {
       // The incomplete Versionstamp will be overwritten with tr's version information when committed.
       Tuple t = Tuple.from("prefix", Versionstamp.incomplete());
       tr.mutate(MutationType.SET_VERSIONSTAMPED_KEY, t.packWithVersionstamp(), new byte[0]);
       return tr.getVersionstamp();
   });

   byte[] trVersion = trVersionFuture.get();

   Versionstamp v = db.run((Transaction tr) -> {
       Subspace subspace = new Subspace(Tuple.from("prefix"));
       byte[] serialized = tr.getRange(subspace.range(), 1).iterator().next().getKey();
       Tuple t = subspace.unpack(serialized);
       return t.getVersionstamp(0);
   });

   assert v.equals(Versionstamp.complete(trVersion));
 
 

Here, an incomplete Versionstamp is packed and written to the database with the SET_VERSIONSTAMPED_KEY MutationType. After committing, we then attempt to read back the same key that we just wrote. Then we verify the invariant that the deserialized Versionstamp is the same as a complete Versionstamp instance created from the first transaction's version information.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Length of a serialized Versionstamp instance when converted into a byte array.
  • Method Summary

    Modifier and Type
    Method
    Description
    int
    Compares two Versionstamp instances in a manner consistent with their key order when serialized in the database as keys.
    complete(byte[] trVersion)
    Creates a complete Versionstamp instance with the given transaction and default user versions.
    complete(byte[] trVersion, int userVersion)
    Creates a complete Versionstamp instance with the given transaction and user versions.
    boolean
    Check another object for equality.
    fromBytes(byte[] versionBytes)
    Creates a Versionstamp instance based on the given byte array representation.
    byte[]
    Retrieve a byte-array representation of this Versionstamp.
    byte[]
    Retrieve the portion of this Versionstamp that is set by the database.
    int
    Retrieve the portion of this Versionstamp that is set by the user.
    int
    Hash code for this Versionstamp.
    Creates an incomplete Versionstamp instance with the default user version.
    incomplete(int userVersion)
    Creates an incomplete Versionstamp instance with the given user version.
    boolean
    Whether this Versionstamp's transaction version is meaningful.
    Generate a human-readable representation of this Versionstamp.
    static int
    unpackUserVersion(byte[] bytes, int pos)
    From a byte array, unpack the user version starting at the given position.

    Methods inherited from class java.lang.Object

    getClass, notify, notifyAll, wait, wait, wait
  • Field Details

    • LENGTH

      public static final int LENGTH
      Length of a serialized Versionstamp instance when converted into a byte array.
      See Also:
  • Method Details

    • unpackUserVersion

      public static int unpackUserVersion(byte[] bytes, int pos)
      From a byte array, unpack the user version starting at the given position. This assumes that the bytes are stored in big-endian order as an unsigned short, which is the way the user version is serialized in packed Versionstamps.
      Parameters:
      bytes - byte array including user version
      pos - starting position of user version
      Returns:
      the unpacked user version included in the array
    • fromBytes

      public static Versionstamp fromBytes(byte[] versionBytes)
      Creates a Versionstamp instance based on the given byte array representation. This follows the same format as that used by the main constructor, but the completeness of the Versionstamp is instead automatically determined by comparing its transaction version with the value used to indicate an unset transaction version.
      Parameters:
      versionBytes - byte array representation of Versionstamp
      Returns:
      equivalent instantiated Versionstamp object
    • incomplete

      public static Versionstamp incomplete(int userVersion)
      Creates an incomplete Versionstamp instance with the given user version. The provided user version must fit within an unsigned short. When converted into a byte array, the bytes for the transaction version will be filled in with dummy bytes to be later filled in at transaction commit time.
      Parameters:
      userVersion - intra-transaction portion of version (set by user code)
      Returns:
      an incomplete Versionstamp with the given user version
    • incomplete

      public static Versionstamp incomplete()
      Creates an incomplete Versionstamp instance with the default user version. When converted into a byte array, the bytes for the transaction version will be filled in with dummy bytes to be later filled in at transaction commit time. If multiple keys are created using the returned Versionstamp within the same transaction, then all of those keys will have the same version, but it will provide an ordering between different transactions if that is all that is required.
      Returns:
      an incomplete Versionstamp with the default user version
    • complete

      public static Versionstamp complete(byte[] trVersion, int userVersion)
      Creates a complete Versionstamp instance with the given transaction and user versions. The provided transaction version must have exactly 10 bytes, and the user version must fit within an unsigned short.
      Parameters:
      trVersion - inter-transaction portion of version (set by the database)
      userVersion - intra-transaction portion of version (set by user code)
      Returns:
      a complete Versionstamp assembled from the given parts
    • complete

      public static Versionstamp complete(byte[] trVersion)
      Creates a complete Versionstamp instance with the given transaction and default user versions. The provided transaction version must have exactly 10 bytes.
      Parameters:
      trVersion - inter-transaction portion of version (set by the database)
      Returns:
      a complete Versionstamp assembled from the given transaction version and the default user version
    • isComplete

      public boolean isComplete()
      Whether this Versionstamp's transaction version is meaningful. The database will assign each transaction a different transaction version. A Versionstamp is considered to be "complete" if its transaction version is one of those database-assigned versions rather than just dummy bytes. If one uses this class with our SET_VERSIONSTAMPED_KEY mutation, then the appropriate bytes will be filled in within the database during a successful commit.
      Returns:
      whether the transaction version has been set
    • getBytes

      public byte[] getBytes()
      Retrieve a byte-array representation of this Versionstamp. This representation can then be serialized and added to the database. If this Versionstamp is not complete, the first 10 bytes (representing the transaction version) will not be meaningful and one should probably use with the SET_VERSIONSTAMPED_KEY mutation. Warning: For performance reasons, this method does not create a copy of its underlying data array. As a result, it is dangerous to modify the return value of this function.
      Returns:
      byte representation of this Versionstamp
    • getTransactionVersion

      public byte[] getTransactionVersion()
      Retrieve the portion of this Versionstamp that is set by the database. These 10 bytes are what provide an ordering between different commits.
      Returns:
      transaction version of this Versionstamp
    • getUserVersion

      public int getUserVersion()
      Retrieve the portion of this Versionstamp that is set by the user. This integer is what provides an ordering within a single commit.
      Returns:
      user version of this Versionstamp
    • toString

      public String toString()
      Generate a human-readable representation of this Versionstamp. It contains information as to whether this Versionstamp is incomplete or not, what its transaction version is (if the Versionstamp is complete), and what its user version is.
      Overrides:
      toString in class Object
      Returns:
      a human-readable representation of this Versionstamp
    • compareTo

      public int compareTo(Versionstamp other)
      Compares two Versionstamp instances in a manner consistent with their key order when serialized in the database as keys. The rules for comparison are:
      • All complete Versionstamps sort before incomplete Versionstamps
      • Two complete Versionstamps will sort based on unsigned lexicographic comparison of their byte representations.
      • Two incomplete Versionstamps will sort based on their user versions.
      Specified by:
      compareTo in interface Comparable<Versionstamp>
      Parameters:
      other - Versionstamp instance to compare against
      Returns:
      -1 if this Versionstamp is smaller than other, 1 if it is bigger, and 0 if it is equal
    • equals

      public boolean equals(Object o)
      Check another object for equality. This will return true if and only if the o parameter is of type Versionstamp and has the same completion status and byte representation.
      Overrides:
      equals in class Object
      Parameters:
      o - object to compare for equality
      Returns:
      whether the passed object is an equivalent Versionstamp
    • hashCode

      public int hashCode()
      Hash code for this Versionstamp. It is based off of the hash code for the underlying data array.
      Overrides:
      hashCode in class Object
      Returns:
      hash-table compliant hash code for this instance