basho/riak_kv — pull request #536 by russelldb (2013-04-25 16:15:44+00:00)
Title: A simple way to store a PN-Counter in a riak_object

Adds an API endpoint for PB and HTTP for incrementing (and getting the value of) a counter.

The counter is implemented as a PN-Counter. In fact the PN-Counter and G-Counter modules from riak_dt are copied into riak_kv (along with their quickcheck tests).

There is a wrapper module `riak_kv_counter` that mediates between `riak_object` and `riak_kv_pn_counter`.

The regular get/put fsms are used. Some small change is made to the vnode to allow counter siblings to merge to a single value before being written to disk.

The wm` and `pb` endpoints also use the `riak_kv_counter` merge function to ensure a single value is returned to the user.

If (by accident, I hope) a bucket/key is written too as a regular riak_object write, the conflicting riak_object sibling is maintained.

To use store counters the bucket _must_ be `{allow_mult, true}`. I recommend that you don't mix counter and non-counter objects in the same bucket.

----
Examples:

> curl -v -X POST localhost:8098/buckets/my_counters/counters/c1 -d"1"
curl -X PUT localhost:8098/buckets/my_counters/props -H"Content-Type: application/json" -d "{\"props\" : {\"allow_mult\": true}}"

> curl -X POST localhost:8098/buckets/my_counters/counters/c1 -d"1"
> curl localhost:8098/buckets/my_counters/counters/c2
1
> curl -X POST localhost:8098/buckets/my_counters/counters/c1 -d"100"
101
> curl -X POST localhost:8098/buckets/my_counters/counters/c1 -d"-1"