Class CounterContext


  • public class CounterContext
    extends java.lang.Object
    An implementation of a partitioned counter context. A context is primarily a list of tuples (counter id, clock, count) -- called shards, with some shards flagged as global or local (with special resolution rules in merge()). The data structure has two parts: a) a header containing the lists of global and local shard indexes in the body b) a list of shards -- (counter id, logical clock, count) tuples -- (the so-called 'body' below) The exact layout is: | header | body | context : |--|------|----------| ^ ^ | list of indices in the body list (2*#elt bytes) #elt in rest of header (2 bytes) Non-negative indices refer to local shards. Global shard indices are encoded as [idx + Short.MIN_VALUE], and are thus always negative. The body layout being: body: |----|----|----|----|----|----|.... ^ ^ ^ ^ ^ ^ | | count_1 | | count_2 | clock_1 | clock_2 counterid_1 counterid_2 The rules when merging two shard with the same counter id are: - global + global = keep the shard with the highest logical clock - global + local = keep the global one - global + remote = keep the global one - local + local = sum counts (and logical clocks) - local + remote = keep the local one - remote + remote = keep the shard with the highest logical clock For a detailed description of the meaning of a local and why the merging rules work this way, see CASSANDRA-1938 - specifically the 1938_discussion attachment (doesn't cover global shards, see CASSANDRA-4775 for that).
    • Constructor Summary

      Constructors 
      Constructor Description
      CounterContext()  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      <V> V clearAllLocal​(V context, ValueAccessor<V> accessor)  
      java.nio.ByteBuffer createGlobal​(CounterId id, long clock, long count)
      Creates a counter context with a single global, 2.1+ shard (a result of increment).
      java.nio.ByteBuffer createLocal​(long count)
      Creates a counter context with a single local shard.
      java.nio.ByteBuffer createRemote​(CounterId id, long clock, long count)
      Creates a counter context with a single remote shard.
      java.nio.ByteBuffer createUpdate​(long count)
      Creates a counter context with a single local shard with clock id of UPDATE_CLOCK_ID.
      CounterContext.Relationship diff​(java.nio.ByteBuffer left, java.nio.ByteBuffer right)
      Determine the count relationship between two contexts.
      int findPositionOf​(java.nio.ByteBuffer context, CounterId id)
      Finds the position of a shard with the given id within the context (via binary search).
      ClockAndCount getClockAndCountOf​(java.nio.ByteBuffer context, CounterId id)
      Returns the clock and the count associated with the given counter id, or (0, 0) if no such shard is present.
      ClockAndCount getLocalClockAndCount​(java.nio.ByteBuffer context)
      Returns the clock and the count associated with the local counter id, or (0, 0) if no such shard is present.
      long getLocalCount​(java.nio.ByteBuffer context)
      Returns the count associated with the local counter id, or 0 if no such shard is present.
      <V> boolean hasLegacyShards​(V context, ValueAccessor<V> accessor)
      Detects whether or not the context has any legacy (local or remote) shards in it.
      static <V> int headerLength​(V context, ValueAccessor<V> accessor)  
      static CounterContext instance()  
      boolean isUpdate​(java.nio.ByteBuffer context)
      Checks if a context is an update (see createUpdate() for justification).
      java.nio.ByteBuffer markLocalToBeCleared​(java.nio.ByteBuffer context)
      Mark context to delete local references afterward.
      java.nio.ByteBuffer merge​(java.nio.ByteBuffer left, java.nio.ByteBuffer right)
      Return a context w/ an aggregated count for each counter id.
      <V> boolean shouldClearLocal​(V context, ValueAccessor<V> accessor)  
      java.lang.String toString​(java.nio.ByteBuffer context)
      Human-readable String from context.
      <V> long total​(Cell<V> cell)  
      <V> long total​(V context, ValueAccessor<V> accessor)
      Returns the aggregated count across all counter ids.
      <V> void validateContext​(V context, ValueAccessor<V> accessor)  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • CounterContext

        public CounterContext()
    • Method Detail

      • createUpdate

        public java.nio.ByteBuffer createUpdate​(long count)
        Creates a counter context with a single local shard with clock id of UPDATE_CLOCK_ID. This is only used in a PartitionUpdate until the update has gone through CounterMutation.apply(), at which point this special local shard will be replaced by a regular global one. It should never hit commitlog / memtable / disk, but can hit network. We use this so that if an update statement has multiple increments of the same counter we properly add them rather than keeping only one of them. NOTE: Before CASSANDRA-13691 we used a regular local shard without a hard-coded clock id value here. It was problematic, because it was possible to return a false positive, and on read path encode an old counter cell from 2.0 era with a regular local shard as a counter update, and to break the 2.1 coordinator.
      • isUpdate

        public boolean isUpdate​(java.nio.ByteBuffer context)
        Checks if a context is an update (see createUpdate() for justification).
      • createGlobal

        public java.nio.ByteBuffer createGlobal​(CounterId id,
                                                long clock,
                                                long count)
        Creates a counter context with a single global, 2.1+ shard (a result of increment).
      • createLocal

        public java.nio.ByteBuffer createLocal​(long count)
        Creates a counter context with a single local shard. For use by tests of compatibility with pre-2.1 counters only.
      • createRemote

        public java.nio.ByteBuffer createRemote​(CounterId id,
                                                long clock,
                                                long count)
        Creates a counter context with a single remote shard. For use by tests of compatibility with pre-2.1 counters only.
      • headerLength

        public static <V> int headerLength​(V context,
                                           ValueAccessor<V> accessor)
      • diff

        public CounterContext.Relationship diff​(java.nio.ByteBuffer left,
                                                java.nio.ByteBuffer right)
        Determine the count relationship between two contexts. EQUAL: Equal set of nodes and every count is equal. GREATER_THAN: Superset of nodes and every count is equal or greater than its corollary. LESS_THAN: Subset of nodes and every count is equal or less than its corollary. DISJOINT: Node sets are not equal and/or counts are not all greater or less than. Strategy: compare node logical clocks (like a version vector).
        Parameters:
        left - counter context.
        right - counter context.
        Returns:
        the Relationship between the contexts.
      • merge

        public java.nio.ByteBuffer merge​(java.nio.ByteBuffer left,
                                         java.nio.ByteBuffer right)
        Return a context w/ an aggregated count for each counter id.
        Parameters:
        left - counter context.
        right - counter context.
      • toString

        public java.lang.String toString​(java.nio.ByteBuffer context)
        Human-readable String from context.
        Parameters:
        context - counter context.
        Returns:
        a human-readable String of the context.
      • total

        public <V> long total​(V context,
                              ValueAccessor<V> accessor)
        Returns the aggregated count across all counter ids.
        Parameters:
        context - a counter context
        Returns:
        the aggregated count represented by context
      • total

        public <V> long total​(Cell<V> cell)
      • shouldClearLocal

        public <V> boolean shouldClearLocal​(V context,
                                            ValueAccessor<V> accessor)
      • hasLegacyShards

        public <V> boolean hasLegacyShards​(V context,
                                           ValueAccessor<V> accessor)
        Detects whether or not the context has any legacy (local or remote) shards in it.
      • markLocalToBeCleared

        public java.nio.ByteBuffer markLocalToBeCleared​(java.nio.ByteBuffer context)
        Mark context to delete local references afterward. Marking is done by multiply #elt by -1 to preserve header length and #elt count in order to clear all local refs later.
        Parameters:
        context - a counter context
        Returns:
        context that marked to delete local refs
      • clearAllLocal

        public <V> V clearAllLocal​(V context,
                                   ValueAccessor<V> accessor)
      • getLocalClockAndCount

        public ClockAndCount getLocalClockAndCount​(java.nio.ByteBuffer context)
        Returns the clock and the count associated with the local counter id, or (0, 0) if no such shard is present.
      • getLocalCount

        public long getLocalCount​(java.nio.ByteBuffer context)
        Returns the count associated with the local counter id, or 0 if no such shard is present.
      • getClockAndCountOf

        public ClockAndCount getClockAndCountOf​(java.nio.ByteBuffer context,
                                                CounterId id)
        Returns the clock and the count associated with the given counter id, or (0, 0) if no such shard is present.
      • findPositionOf

        public int findPositionOf​(java.nio.ByteBuffer context,
                                  CounterId id)
        Finds the position of a shard with the given id within the context (via binary search).