Documentation
¶
Overview ¶
Package fenwick implements concurrency-safe Fenwick trees (binary indexed trees) for point updates and prefix/range aggregation queries.
Index ¶
- Variables
- type Float32
- type Float64
- type Int
- type Int64
- type Mutation
- type MutationKind
- type Number
- type NumericOperations
- type OperationFuncs
- type Operations
- type ShardedTree
- func NewNumericSharded[T Number](values []T) *ShardedTree[T]
- func NewNumericShardedWithCount[T Number](values []T, shardCount int) *ShardedTree[T]
- func NewSharded[T Value](values []T) *ShardedTree[T]
- func NewShardedWithCount[T Value](values []T, shardCount int) *ShardedTree[T]
- func NewShardedWithOperations[T any](values []T, ops Operations[T]) *ShardedTree[T]
- func NewShardedWithOperationsAndCount[T any](values []T, shardCount int, ops Operations[T]) *ShardedTree[T]
- func (t *ShardedTree[T]) Add(index int, delta T) error
- func (t *ShardedTree[T]) Apply(mutations ...Mutation[T]) error
- func (t *ShardedTree[T]) At(index int) (T, error)
- func (t *ShardedTree[T]) ExactPrefixSum(index int) (T, error)
- func (t *ShardedTree[T]) ExactRangeSum(left, right int) (T, error)
- func (t *ShardedTree[T]) ExactTotal() T
- func (t *ShardedTree[T]) Len() int
- func (t *ShardedTree[T]) PrefixSum(index int) (T, error)
- func (t *ShardedTree[T]) RangeSum(left, right int) (T, error)
- func (t *ShardedTree[T]) Set(index int, value T) error
- func (t *ShardedTree[T]) ShardCount() int
- func (t *ShardedTree[T]) Total() T
- func (t *ShardedTree[T]) Values() []T
- type Tree
- func (t *Tree[T]) Add(index int, delta T) error
- func (t *Tree[T]) Apply(mutations ...Mutation[T]) error
- func (t *Tree[T]) At(index int) (T, error)
- func (t *Tree[T]) Len() int
- func (t *Tree[T]) PrefixSum(index int) (T, error)
- func (t *Tree[T]) RangeSum(left, right int) (T, error)
- func (t *Tree[T]) Set(index int, value T) error
- func (t *Tree[T]) Total() T
- func (t *Tree[T]) Values() []T
- type Uint
- type Uint64
- type Value
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrIndexOutOfRange = errors.New("fenwick: index out of range") ErrInvalidRange = errors.New("fenwick: invalid range") )
Functions ¶
This section is empty.
Types ¶
type Float32 ¶
type Float32 float32
Float32 is a Value wrapper for float32 that implements arithmetic operations.
type Float64 ¶
type Float64 float64
Float64 is a Value wrapper for float64 that implements arithmetic operations.
type Int64 ¶
type Int64 int64
Int64 is a Value wrapper for int64 that implements arithmetic operations.
type Mutation ¶
type Mutation[T any] struct { Index int Kind MutationKind Value T }
Mutation describes one point change applied by Apply.
Mutations are evaluated in slice order. This matters when multiple mutations target the same index.
func AddMutation ¶
AddMutation creates an additive point mutation.
func SetMutation ¶
SetMutation creates a replacement point mutation.
type MutationKind ¶
type MutationKind uint8
MutationKind identifies how a batch mutation changes a value.
const ( // MutationAdd increments the current value by Mutation.Value. MutationAdd MutationKind = iota + 1 // MutationSet replaces the current value with Mutation.Value. MutationSet )
type Number ¶
Number contains the built-in signed integer and floating-point families. Unsigned types are deliberately excluded because Set may require a negative delta when replacing a larger value with a smaller one.
type NumericOperations ¶
type NumericOperations[T Number] struct{}
NumericOperations implements Operations for signed numeric types.
func (NumericOperations[T]) Add ¶
func (NumericOperations[T]) Add(a, b T) T
func (NumericOperations[T]) Sub ¶
func (NumericOperations[T]) Sub(a, b T) T
func (NumericOperations[T]) Zero ¶
func (NumericOperations[T]) Zero() T
type OperationFuncs ¶
type OperationFuncs[T any] struct { ZeroFunc func() T AddFunc func(a, b T) T SubFunc func(a, b T) T }
OperationFuncs adapts functions to Operations. It is convenient when the aggregation behavior is local to the caller and does not warrant a named operations type.
func (OperationFuncs[T]) Add ¶
func (f OperationFuncs[T]) Add(a, b T) T
func (OperationFuncs[T]) Sub ¶
func (f OperationFuncs[T]) Sub(a, b T) T
func (OperationFuncs[T]) Zero ¶
func (f OperationFuncs[T]) Zero() T
type Operations ¶
type Operations[T any] interface { Zero() T Add(a, b T) T Sub(a, b T) T }
Operations defines the additive algebra used by a Fenwick tree.
It is intentionally separate from the stored model type. This allows domain models to remain free of Fenwick-specific methods and lets callers inject aggregation behavior at construction time.
Implementations must provide an additive identity and satisfy the usual additive group laws required by range sums: Add must be associative, Zero must be an identity, and Sub must undo Add.
type ShardedTree ¶
type ShardedTree[T any] struct { // contains filtered or unexported fields }
ShardedTree splits values into independently locked contiguous Fenwick trees.
func NewNumericSharded ¶
func NewNumericSharded[T Number](values []T) *ShardedTree[T]
NewNumericSharded constructs a sharded tree for signed numeric values.
func NewNumericShardedWithCount ¶
func NewNumericShardedWithCount[T Number](values []T, shardCount int) *ShardedTree[T]
NewNumericShardedWithCount constructs a numeric sharded tree with an explicit shard count.
func NewSharded ¶
func NewSharded[T Value](values []T) *ShardedTree[T]
NewSharded constructs a sharded tree for Value models.
func NewShardedWithCount ¶
func NewShardedWithCount[T Value](values []T, shardCount int) *ShardedTree[T]
NewShardedWithCount constructs a sharded tree for Value models with an explicit shard count.
func NewShardedWithOperations ¶
func NewShardedWithOperations[T any](values []T, ops Operations[T]) *ShardedTree[T]
NewShardedWithOperations chooses the shard count from GOMAXPROCS.
func NewShardedWithOperationsAndCount ¶
func NewShardedWithOperationsAndCount[T any](values []T, shardCount int, ops Operations[T]) *ShardedTree[T]
NewShardedWithOperationsAndCount injects aggregation behavior and uses an explicit shard count.
func (*ShardedTree[T]) Add ¶
func (t *ShardedTree[T]) Add(index int, delta T) error
func (*ShardedTree[T]) Apply ¶
func (t *ShardedTree[T]) Apply(mutations ...Mutation[T]) error
Apply atomically applies a batch of point mutations in slice order.
All mutations are validated before locks are acquired. Every touched shard is then write-locked in ascending order, preventing deadlocks and ensuring exact readers observe either the state before the whole batch or the state after it. Fast cross-shard readers retain their documented non-snapshot semantics. An empty batch is a no-op.
func (*ShardedTree[T]) At ¶
func (t *ShardedTree[T]) At(index int) (T, error)
func (*ShardedTree[T]) ExactPrefixSum ¶
func (t *ShardedTree[T]) ExactPrefixSum(index int) (T, error)
func (*ShardedTree[T]) ExactRangeSum ¶
func (t *ShardedTree[T]) ExactRangeSum(left, right int) (T, error)
func (*ShardedTree[T]) ExactTotal ¶
func (t *ShardedTree[T]) ExactTotal() T
func (*ShardedTree[T]) Len ¶
func (t *ShardedTree[T]) Len() int
func (*ShardedTree[T]) PrefixSum ¶
func (t *ShardedTree[T]) PrefixSum(index int) (T, error)
func (*ShardedTree[T]) RangeSum ¶
func (t *ShardedTree[T]) RangeSum(left, right int) (T, error)
func (*ShardedTree[T]) Set ¶
func (t *ShardedTree[T]) Set(index int, value T) error
func (*ShardedTree[T]) ShardCount ¶
func (t *ShardedTree[T]) ShardCount() int
func (*ShardedTree[T]) Total ¶
func (t *ShardedTree[T]) Total() T
func (*ShardedTree[T]) Values ¶
func (t *ShardedTree[T]) Values() []T
type Tree ¶
type Tree[T any] struct { // contains filtered or unexported fields }
Tree stores values aggregated by injected Operations. Public indexes are zero-based; internal Fenwick indexes are one-based.
Example ¶
package main
import (
"fmt"
"github.com/Sheryorov/fenwick"
)
func main() {
ft := fenwick.NewNumeric[int64]([]int64{3, 2, 5, 1, 4})
sum, _ := ft.RangeSum(1, 3)
fmt.Println(sum)
_ = ft.Set(2, 10)
sum, _ = ft.RangeSum(1, 3)
fmt.Println(sum)
}
Output: 8 13
func NewNumeric ¶
NewNumeric constructs a tree for signed integers or floating-point values.
func NewWithOperations ¶
func NewWithOperations[T any](values []T, ops Operations[T]) *Tree[T]
NewWithOperations constructs a tree using caller-provided aggregation behavior. The input slice is copied and construction takes O(n).
func (*Tree[T]) Apply ¶
Apply atomically applies a batch of point mutations in slice order.
All mutations are validated before any value is changed. The tree lock is acquired once, so readers and writers observe either the state before the whole batch or the state after it. An empty batch is a no-op.
type Uint64 ¶
type Uint64 uint64
Uint64 is a Value wrapper for uint64 that implements arithmetic operations.