.TH counters 3erl "erts 11.1.8" "Ericsson AB" "Erlang Module Definition" .SH NAME counters \- Counter Functions .SH DESCRIPTION .LP This module provides a set of functions to do operations towards shared mutable counter variables\&. The implementation does not utilize any software level locking, which makes it very efficient for concurrent access\&. The counters are organized into arrays with the following semantics: .RS 2 .TP 2 * Counters are 64 bit signed integers\&. .LP .TP 2 * Counters wrap around at overflow and underflow operations\&. .LP .TP 2 * Counters are initialized to zero\&. .LP .TP 2 * Write operations guarantee atomicity\&. No intermediate results can be seen from a single write operation\&. .LP .TP 2 * Two types of counter arrays can be created with options \fIatomics\fR\& or \fIwrite_concurrency\fR\&\&. The \fIatomics\fR\& counters have good allround performance with nice consistent semantics while \fIwrite_concurrency\fR\& counters offers even better concurrent write performance at the expense of some potential read inconsistencies\&. See \fInew/2\fR\&\&. .LP .TP 2 * Indexes into counter arrays are one-based\&. A counter array of size N contains N counters with index from 1 to N\&. .LP .RE .SH DATA TYPES .nf \fBcounters_ref()\fR\& .br .fi .RS .LP Identifies a counter array returned from \fInew/2\fR\&\&. .RE .SH EXPORTS .LP .nf .B new(Size, Opts) -> counters_ref() .br .fi .br .RS .LP Types: .RS 3 Size = integer() >= 1 .br Opts = [Opt] .br Opt = atomics | write_concurrency .br .RE .RE .RS .LP Create a new counter array of \fISize\fR\& counters\&. All counters in the array are initially set to zero\&. .LP Argument \fIOpts\fR\& is a list of the following possible options: .RS 2 .TP 2 .B \fIatomics\fR\& (Default): Counters will be sequentially consistent\&. If write operation A is done sequentially before write operation B, then a concurrent reader may see the result of none of them, only A, or both A and B\&. It cannot see the result of only B\&. .TP 2 .B \fIwrite_concurrency\fR\&: This is an optimization to achieve very efficient concurrent \fIadd\fR\& and \fIsub\fR\& operations at the expense of potential read inconsistency and memory consumption per counter\&. .RS 2 .LP Read operations may see sequentially inconsistent results with regard to concurrent write operations\&. Even if write operation A is done sequentially before write operation B, a concurrent reader may see any combination of A and B, including only B\&. A read operation is only guaranteed to see all writes done sequentially before the read\&. No writes are ever lost, but will eventually all be seen\&. .RE .RS 2 .LP The typical use case for \fIwrite_concurrency\fR\& is when concurrent calls to \fIadd\fR\& and \fIsub\fR\& toward the same counters are very frequent, while calls to \fIget\fR\& and \fIput\fR\& are much less frequent\&. The lack of absolute read consistency must also be acceptable\&. .RE .RE .LP Counters are not tied to the current process and are automatically garbage collected when they are no longer referenced\&. .RE .LP .nf .B get(Ref, Ix) -> integer() .br .fi .br .RS .LP Types: .RS 3 Ref = counters_ref() .br Ix = integer() .br .RE .RE .RS .LP Read counter value\&. .RE .LP .nf .B add(Ref, Ix, Incr) -> ok .br .fi .br .RS .LP Types: .RS 3 Ref = counters_ref() .br Ix = Incr = integer() .br .RE .RE .RS .LP Add \fIIncr\fR\& to counter at index \fIIx\fR\&\&. .RE .LP .nf .B sub(Ref, Ix, Decr) -> ok .br .fi .br .RS .LP Types: .RS 3 Ref = counters_ref() .br Ix = Decr = integer() .br .RE .RE .RS .LP Subtract \fIDecr\fR\& from counter at index \fIIx\fR\&\&. .RE .LP .nf .B put(Ref, Ix, Value) -> ok .br .fi .br .RS .LP Types: .RS 3 Ref = counters_ref() .br Ix = Value = integer() .br .RE .RE .RS .LP Write \fIValue\fR\& to counter at index \fIIx\fR\&\&. .LP .RS -4 .B Note: .RE Despite its name, the \fIwrite_concurrency\fR\& optimization does not improve \fIput\fR\&\&. A call to \fIput\fR\& is a relatively heavy operation compared to the very lightweight and scalable \fIadd\fR\& and \fIsub\fR\&\&. The cost for a \fIput\fR\& with \fIwrite_concurrency\fR\& is like a \fIget\fR\& plus a \fIput\fR\& without \fIwrite_concurrency\fR\&\&. .RE .LP .nf .B info(Ref) -> Info .br .fi .br .RS .LP Types: .RS 3 Ref = counters_ref() .br Info = #{size := Size, memory := Memory} .br Size = Memory = integer() >= 0 .br .RE .RE .RS .LP Return information about a counter array in a map\&. The map has the following keys (at least): .RS 2 .TP 2 .B \fIsize\fR\&: The number of counters in the array\&. .TP 2 .B \fImemory\fR\&: Approximate memory consumption for the array in bytes\&. .RE .RE