Class UnixFSDualCounter

java.lang.Object
dev.getelements.elements.rt.transact.unix.UnixFSDualCounter

public class UnixFSDualCounter extends Object
Represents a wraparound counter with a leading and trailing value. This allows multiple threads to safely share an integer-based index of resources independently. When acquiring a resource, a thread will increment the leading value and use that to reference a particular piece of data. When the thread is finished, it will increment the trailing value thereby allowing another thread to access the shared resource. Both values, leading and trailing, automatically wrap around a fixed-size maximum value. If the leading value wraps around and catches up to the trailing value, then all resources are exhausted and the counter will throw an instance of FatalException. If, while incrementing the trailing value, a thread catches up to the leading value then this counter will throw an instance of IllegalStateException indicating a situation implying programmer error and likely data corruption.UnixFSTransactionProgramBuilder They are backed by a single instance of an AtomicLong and bit-shifting is used to pack the values together. Because this dual-counter transparently supports wraparound, the trailing value may not necessarily be less than the leading value as the values wrap around automatically.
  • Field Details

  • Constructor Details

    • UnixFSDualCounter

      public UnixFSDualCounter(int max)
      Creates a dual count with the supplied maximum value. The max value represents the actual number the counter will hit, including zero. Therefore, if using this to index an array, the max value shoudl be one less than the total size of the array.
      Parameters:
      max - the maximum value, inclusive
    • UnixFSDualCounter

      public UnixFSDualCounter(int max, AtomicLong counter)
      Same as UnixFSDualCounter(int), but allows for the caller to specify its own AtomicLong used.
      Parameters:
      max -
      counter -
    • UnixFSDualCounter

      public UnixFSDualCounter(int max, UnixFSAtomicLong counter)
      Allows for the caller to specify an arbitrary UnixFSAtomicLong.
      Parameters:
      max - the max value
      counter - the counter
  • Method Details

    • reset

      public UnixFSDualCounter reset()
      Resets this counter ensuring that both leading/trailing values are equal to zero and the sign bits are set indicating that the counter is empty.
    • isEmpty

      public boolean isEmpty()
      Tests if the counter is empty, that is to say that no values are valid at all.
      Returns:
      true if empty, false otherwise.
    • isFull

      public boolean isFull()
      Tests if the counter is full, that is to say the next operation involving an increment of the leading value would result in an exception.
      Returns:
      true if the data is full
    • size

      public int size()
      Returns the distance between the trailing and leading value.
      Returns:
    • incrementLeadingAndGet

      public int incrementLeadingAndGet()
      Increments the leading value. This may be incremented up to the maximum value until with a call to getTrailingAndIncrement() before throwing an instance of FatalException.
      Returns:
      the pre-incremented value
      Throws:
      FatalException - if the count has been exhausted
    • incrementLeadingAndGetSnapshot

      public UnixFSDualCounter.Snapshot incrementLeadingAndGetSnapshot()
      Increments the leading value. This may be incremented up to the maximum value until with a call to getTrailingAndIncrement() before throwing an instance of FatalException.
      Returns:
      the post-incremented value
      Throws:
      FatalException - if the count has been exhausted
    • getTrailingAndIncrement

      public int getTrailingAndIncrement()
      Increments the trailing value. This may not be incremented past the upper value, if so it indicates programmer error and an instance of IllegalStateException will be thrown. The counter will be flagged as empty once the trailing value matches the leading value.
      Returns:
      the pre-increment value
    • getSnapshot

      public UnixFSDualCounter.Snapshot getSnapshot()
      Gets the snapshot value of this UnixFSDualCounter. This represents the current state of the counter and is fetched atomically.
      Returns:
      the UnixFSDualCounter.Snapshot
    • compareAndIncrementTrailing

      public boolean compareAndIncrementTrailing(UnixFSDualCounter.Snapshot snapshot)
      Given a UnixFSDualCounter.Snapshot, this attempts to increment the trailing value. If the increment succeeds, this method returns true indicating so. Otherwise, it returns false. This allows for external code to safely and deterministically replenish trailing values managed by this counter.
      Parameters:
      snapshot - the UnixFSDualCounter.Snapshot
      Returns:
      true, if successful. false otherwise.
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • getLeading

      public int getLeading()
      Gets the leading value, ignoring the empty state.
      Returns:
      the leading
    • getTrailing

      public int getTrailing()
      Gets the trailing value, ignoring the empty state.
      Returns:
      the trailing value
    • isFull

      public static boolean isFull(long packed, int max)
      Tests if the packed value represents a full counter. That is the sign bits of the upper and lower values are set to 0 and the upper and lower bits are equal.
      Parameters:
      packed - the packed value
      Returns:
      true if empty, false otherwise
    • size

      public static int size(long packed, int max)
      Given the 64-bit packed value, this method reads both the leading and trailing values and finds the distance between the two numbers.
      Parameters:
      packed - the packed value
      max - the max value
      Returns:
      the distance between the two numbers
    • isEmpty

      public static boolean isEmpty(long packed)
      Tests if the packed value represents an empty counter. That is the sign bits of the upper and lower values are set to 1.
      Parameters:
      packed - the packed value
      Returns:
      true if empty, false otherwise
    • leading

      public static int leading(long packed)
      Gets the leading value from the the packed long.
      Parameters:
      packed - the packed long
      Returns:
      the leading value
    • trailing

      public static int trailing(long packed)
      Sets the leading value from the packed long.
      Parameters:
      packed - the packed long
      Returns:
      the trailing value
    • increment

      public static int increment(int value, int max)
      Increments the supplied value wrapping up to the max value.
      Parameters:
      value - the value to increment
      max - the max value
      Returns:
      the incremented value
    • pack

      public static long pack(int trailing, int leading)
      Packs the leading and trailing values together and returns the long representation.
      Parameters:
      trailing - the trailing value
      leading - the leading value
      Returns:
      the packed value
    • getMax

      public int getMax()
      Gets the maximum value from this counter.
      Returns:
      the max value