com.appenginefan.toolkit.common
Class Counter

java.lang.Object
  extended by com.appenginefan.toolkit.common.Counter

public class Counter
extends Object

A class that utilizes a combination of memcache and the datastore backend to implement a fast yet reliable counter. Counts are increased transactionally in memcache and occasionally persisted in the datastore. Sharding techniques are used to minmize the chance of blockage in the store. The frequency of writes can be somewhat controlled, from a guaranteed write (useful for id generators) to an occasional write (page counters). Fully reliable counter objects (with a write-probability of 1) are guaranteed to always be increasing, which is a useful property for storing ordered entities in the store. For more background, check out this blog post


Constructor Summary
Counter(Random random, Persistence<byte[]> persistence, MemcacheService memcache, double chanceToWrite, String key, int numShards)
          Constructor
 
Method Summary
static Counter createIdGenerator(String key)
          Creates a counter that does not loose count (in other words, it writes to the data store all the time).
static Counter createPageCounter(String key, double chanceToWrite)
          Creates a counter that is not completely reliable (it might loose counts if memcache is resetted)
 long get()
          Gets the current value
 long increment(long delta)
          Increments the value by a positive delta
 boolean isIdGenerator()
          Returns true if the counter is writing to the store each and every time, which makes it possible to use as an id generator.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Counter

public Counter(Random random,
               Persistence<byte[]> persistence,
               MemcacheService memcache,
               double chanceToWrite,
               String key,
               int numShards)
Constructor

Parameters:
random - a random number generator
persistence - a persistence that can be used to write to the datastore
memcache - a memcache service for quick access to shared transactional numbers
chanceToWrite - a value between 0.0 and 1.0 (inclusive). Each time the counter gets increased, a random throw of the dice decides whether to write to the store. A chanceToWrite of 1.0 means that every change in the counter will be persisted; a chanceToWrite of 0.0 means that no change will be persisted
key - a key that is used to persist the counter shards in the datastore and memcache. must not contain any slashes
numShards - the number of shards that should be used to store the value. The more shards the less the chance of collision on writes, but the longer it will take to load shards from the store if memcache has been evicted
Method Detail

createPageCounter

public static Counter createPageCounter(String key,
                                        double chanceToWrite)
Creates a counter that is not completely reliable (it might loose counts if memcache is resetted)

Parameters:
key - a key that is used to persist the counter shards in the datastore and memcache. must not contain any slashes
chanceToWrite - the relative probability that changes to memcache get persisted. Must be between 0 and 1. The higher the value, the more reliable the counter is.
Returns:
a counter object

createIdGenerator

public static Counter createIdGenerator(String key)
Creates a counter that does not loose count (in other words, it writes to the data store all the time).

Parameters:
key - a key that is used to persist the counter shards in the datastore and memcache. must not contain any slashes
Returns:
a counter object

get

public long get()
Gets the current value


increment

public long increment(long delta)
Increments the value by a positive delta

Parameters:
delta -
Returns:
the value that the counter was changed to

isIdGenerator

public boolean isIdGenerator()
Returns true if the counter is writing to the store each and every time, which makes it possible to use as an id generator.

Returns:
true if the chance-to-write is 1.0