org.apache.cassandra.db.context

## Class CounterContext

- java.lang.Object
- - org.apache.cassandra.db.context.CounterContext

All Implemented Interfaces:
  IContext

    public class CounterContext
    extends java.lang.Object
    implements IContext

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).

### Nested Class Summary

Nested Classes
`static class` `CounterContext.ContextState` Helper class to work on contexts (works by iterating over them).

### Nested classes/interfaces inherited from interface org.apache.cassandra.db.context.IContext

`IContext.ContextRelationship`

### Constructor Summary

Constructors
Constructor and Description
`CounterContext()`

### Method Summary

Methods
`java.nio.ByteBuffer` `clearAllLocal(java.nio.ByteBuffer context)` Remove all the local of a context (but keep global).
`java.nio.ByteBuffer` `createLocal(long count, Allocator allocator)` Creates a counter context with a single local shard.
`java.nio.ByteBuffer` `createRemote(CounterId id, long clock, long count, Allocator allocator)` Creates a counter context with a single remote shard.
`IContext.ContextRelationship` `diff(java.nio.ByteBuffer left, java.nio.ByteBuffer right)` Determine the count relationship between two contexts.
`boolean` `hasCounterId(java.nio.ByteBuffer context, CounterId id)` Checks whether the provided context has a count for the provided CounterId.
`static CounterContext` `instance()`
`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, Allocator allocator)` Return a context w/ an aggregated count for each counter id.
`boolean` `shouldClearLocal(java.nio.ByteBuffer context)`
`java.lang.String` `toString(java.nio.ByteBuffer context)` Human-readable String from context.
`long` `total(java.nio.ByteBuffer context)` Returns the aggregated count across all counter ids.
`void` `updateDigest(java.security.MessageDigest message, java.nio.ByteBuffer context)` Update a MessageDigest with the content of a context.
`void` `validateContext(java.nio.ByteBuffer context)`

### 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

#### instance

    public static CounterContext instance()

#### createLocal

    public java.nio.ByteBuffer createLocal(long count,
                                  Allocator allocator)

Creates a counter context with a single local shard.

#### createRemote

    public java.nio.ByteBuffer createRemote(CounterId id,
                                   long clock,
                                   long count,
                                   Allocator allocator)

Creates a counter context with a single remote shard.

#### diff

    public IContext.ContextRelationship 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).

Specified by:
  `diff` in interface `IContext`
Parameters:
  `left` - counter context.
  `right` - counter context.
Returns:
  the ContextRelationship between the contexts.

#### merge

    public java.nio.ByteBuffer merge(java.nio.ByteBuffer left,
                            java.nio.ByteBuffer right,
                            Allocator allocator)

Return a context w/ an aggregated count for each counter id.

Specified by:
  `merge` in interface `IContext`
Parameters:
  `left` - counter context.
  `right` - counter context.
  `allocator` - An allocator for the merged value.

#### toString

    public java.lang.String toString(java.nio.ByteBuffer context)

Human-readable String from context.

Specified by:
  `toString` in interface `IContext`
Parameters:
  `context` - counter context.
Returns:
  a human-readable String of the context.

#### total

    public long total(java.nio.ByteBuffer context)

Returns the aggregated count across all counter ids.

Parameters:
  `context` - a counter context
Returns:
  the aggregated count represented by `context`

#### shouldClearLocal

    public boolean shouldClearLocal(java.nio.ByteBuffer context)

#### 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 java.nio.ByteBuffer clearAllLocal(java.nio.ByteBuffer context)

Remove all the local of a context (but keep global).

Parameters:
  `context` - a counter context
Returns:
  a version of `context` where no shards are local.

#### validateContext

    public void validateContext(java.nio.ByteBuffer context)
                         throws MarshalException

Throws:
  `MarshalException`

#### updateDigest

    public void updateDigest(java.security.MessageDigest message,
                    java.nio.ByteBuffer context)

Update a MessageDigest with the content of a context. Note that this skips the header entirely since the header information has local meaning only, while digests are meant for comparison across nodes. This means in particular that we always have: updateDigest(ctx) == updateDigest(clearAllLocal(ctx))

#### hasCounterId

    public boolean hasCounterId(java.nio.ByteBuffer context,
                       CounterId id)

Checks whether the provided context has a count for the provided CounterId. TODO: since the context is sorted, we could implement a binary search. This is however not called in any critical path and contexts will be fairly small so it doesn't matter much.