CounterEx.Backend.Atomics (CounterEx v0.2.0)

View Source

Atomics-based backend for CounterEx using Erlang's :atomics module.

This backend uses Erlang's :atomics for ultra-fast atomic counter operations:

  • Fixed capacity: Pre-allocated array of atomic integers
  • Ultra-fast: Fastest operations, minimal overhead
  • No GC pressure: Atomics live outside the process heap
  • Key mapping: Uses ETS to map keys to array indices

Characteristics

  • Performance: Highest throughput (~10-20M ops/sec)
  • Memory: Fixed at initialization
  • Limitations: Fixed number of counters per namespace (default: 1000)

Configuration

Options:

  • :capacity - Max counters per namespace (default: 1000)
  • :signed - Use signed integers (default: true)

When to Use

Use this backend when:

  • You have a bounded, known set of counters
  • You need maximum performance
  • You can pre-allocate capacity
  • Memory predictability is important

Limitations

  • Cannot create more counters than the configured capacity
  • Deleting a counter doesn't free its slot (reusable after explicit delete)
  • Each namespace requires separate atomic array

Example

# Initialize with capacity for 10,000 counters
{:ok, state} = CounterEx.Backend.Atomics.init(capacity: 10_000)
{:ok, 1} = CounterEx.Backend.Atomics.inc(state, :default, :my_counter, 1, 0)
{:ok, 1} = CounterEx.Backend.Atomics.get(state, :default, :my_counter)

# Attempting to exceed capacity returns an error
{:error, :capacity_exceeded} = CounterEx.Backend.Atomics.inc(state, :ns, :counter_10001, 1, 0)

Summary

Types

t()

@type t() :: %CounterEx.Backend.Atomics{
  capacity: pos_integer(),
  metadata: :ets.tid(),
  registry: :ets.tid(),
  signed: boolean()
}