v2

package
v0.6.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2026 License: MPL-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package v2 provides a high-performance concurrent map implementation optimized for cache operations. The implementation uses sharding to minimize lock contention by dividing the map into multiple independent shards, each protected by its own read-write mutex.

The concurrent map stores string keys mapped to *cache.Item values and is designed to be thread-safe for concurrent read and write operations across multiple goroutines.

Key features:

  • Sharded design with 32 shards to reduce lock contention
  • FNV-1a hash function for efficient key distribution
  • Thread-safe operations with optimized read/write locking
  • iter.Seq2 iteration via All() for safe concurrent traversal
  • Standard map operations: Set, Get, Has, Remove, Pop, Clear, Count

Example usage:

cm := v2.New()
cm.Set("key", &cache.Item{...})
if item, ok := cm.Get("key"); ok {
    // Process item
}

Index

Constants

View Source
const (
	// ShardCount is the number of shards used by the map.
	ShardCount = 32
	// ShardCount32 is the number of shards used by the map pre-casted to uint32 to avoid performance issues.
	ShardCount32 uint32 = uint32(ShardCount)
)

Variables

This section is empty.

Functions

func Hash added in v0.4.0

func Hash(key string) uint32

Hash returns a 32-bit hash of key derived from xxhash64. Exported so other packages (e.g. the sharded eviction wrapper) can use the same hash as ConcurrentMap and route the same key to the same logical shard — preserving cache-locality when the data shard and eviction shard have different counts.

xxhash is already a direct dependency for cluster/ring.go consistent hashing; consolidating here removes the inlined FNV-1a implementation and gives ~1-3% speedup for keys longer than ~8 bytes plus better avalanche characteristics. Callers should treat the return value as opaque.

We fold the 64-bit xxhash output into 32 bits via XOR of the high and low halves — cheap, preserves all entropy, and matches what Go's standard maphash does when callers want a 32-bit slot index.

Types

type ConcurrentMap

type ConcurrentMap struct {
	// contains filtered or unexported fields
}

ConcurrentMap is a "thread" safe map of type string:*cache.Item. To avoid lock bottlenecks this map is divided into several (ShardCount) map shards.

func New

func New() ConcurrentMap

New creates a new concurrent map.

func (*ConcurrentMap) All added in v0.4.1

func (cm *ConcurrentMap) All() iter.Seq2[string, *Item]

All returns an iter.Seq2 that yields every (key, *Item) pair across all shards. Each shard is walked under its own RLock, released before moving to the next shard — concurrent writers to a different shard are not blocked.

IMPORTANT: the yielded *Item points directly into the live map. Callers MUST treat it as read-only and copy if they need to retain the value past the yield. The shard's RLock is held during yield, so a long-running consumer body will block writers to that shard. Drain into a local slice first if the consumer needs to do I/O or block.

Replaces the previous IterBuffered channel-based iterator: no fan-in goroutines, no per-shard channel allocations.

func (*ConcurrentMap) Clear

func (cm *ConcurrentMap) Clear()

Clear removes all items from map.

func (*ConcurrentMap) Count

func (cm *ConcurrentMap) Count() int

Count returns the number of items in the map.

Lock-free: each shard maintains its cardinality as an atomic.Int64 (mutated under the shard lock alongside items). Count() is the sum of the 32 atomics. The previous implementation walked all 32 shard RLocks per call, which serialized with writers and was the dominant cost in the eviction inner loop's `for backend.Count(ctx) > backend.Capacity()`.

func (*ConcurrentMap) Get

func (cm *ConcurrentMap) Get(key string) (*Item, bool)

Get retrieves an element from map under given key.

func (*ConcurrentMap) GetCopy added in v0.2.2

func (cm *ConcurrentMap) GetCopy(key string) (*Item, bool)

GetCopy retrieves a copy of the item under the given key.

func (*ConcurrentMap) GetShard

func (cm *ConcurrentMap) GetShard(key string) *ConcurrentMapShard

GetShard returns shard under given key.

func (*ConcurrentMap) Has

func (cm *ConcurrentMap) Has(key string) bool

Has checks if key is present in the map.

func (*ConcurrentMap) Pop

func (cm *ConcurrentMap) Pop(key string) (*Item, bool)

Pop removes an element from the map and returns it.

func (*ConcurrentMap) Remove

func (cm *ConcurrentMap) Remove(key string)

Remove removes the value under the specified key.

func (*ConcurrentMap) Set

func (cm *ConcurrentMap) Set(key string, value *Item)

Set sets the given value under the specified key.

func (*ConcurrentMap) Touch added in v0.2.2

func (cm *ConcurrentMap) Touch(key string) bool

Touch updates the last access time and access count for a key.

type ConcurrentMapShard

type ConcurrentMapShard struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ConcurrentMapShard is a "thread" safe string to `*cache.Item` map shard.

count tracks len(items) under the same lock as items, but as an atomic so Count() (sum of 32 shard counts) can read it without acquiring any locks. This eliminates the lock-storm in the eviction inner loop's per-iteration Count() check.

type Item added in v0.1.8

type Item struct {
	Key         string        // key of the item
	Value       any           // value of the item
	LastAccess  time.Time     // last access time
	LastUpdated time.Time     // last write/version assignment time (distributed usage)
	Size        int64         // size in bytes
	Expiration  time.Duration // expiration duration
	AccessCount uint32        // number of times the item has been accessed
	Version     uint64        // logical version (monotonic per key)
	Origin      string        // originating node id (tiebreaker)
}

Item is a struct that represents an item in the cache (v2 optimized layout). It mirrors pkg/cache.Item behavior but with minor layout tweaks for locality.

func (*Item) Expired added in v0.1.8

func (it *Item) Expired() bool

Expired reports whether the item has expired.

func (*Item) SetSize added in v0.1.8

func (it *Item) SetSize() error

SetSize computes and sets Size using fast paths and pooled encoder/buffer. This preserves original behavior (size of serialized value) but reduces allocations.

func (*Item) SizeKB added in v0.1.8

func (it *Item) SizeKB() float64

SizeKB returns the size of the Item in kilobytes.

func (*Item) SizeMB added in v0.1.8

func (it *Item) SizeMB() float64

SizeMB returns the size of the Item in megabytes.

func (*Item) Touch added in v0.1.8

func (it *Item) Touch()

Touch updates last access time and increments access count.

func (*Item) Valid added in v0.1.8

func (it *Item) Valid() error

Valid returns an error if the item is invalid, nil otherwise. Semantics match pkg/cache.Item.Valid but without atomics.

type ItemPoolManager added in v0.1.8

type ItemPoolManager struct {
	// contains filtered or unexported fields
}

ItemPoolManager manages Item object pools for memory efficiency (v2).

func NewItemPoolManager added in v0.1.8

func NewItemPoolManager() *ItemPoolManager

NewItemPoolManager creates a new ItemPoolManager with default configuration (v2).

func (*ItemPoolManager) Get added in v0.1.8

func (m *ItemPoolManager) Get() *Item

Get retrieves an Item from the pool (v2).

func (*ItemPoolManager) Put added in v0.1.8

func (m *ItemPoolManager) Put(it *Item)

Put returns an Item to the pool (v2).

type Sizer added in v0.1.8

type Sizer interface{ SizeBytes() int }

Sizer allows custom values to report their encoded size without serialization.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL