hive

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2026 License: MIT Imports: 12 Imported by: 0

README

hive

An embeddable, leaderless distributed cache for Go applications. Drop it into any Go service to share in-memory state across instances — no external infrastructure required.

node, _ := hive.NewNode(hive.Config{
    Mode:  hive.ModeCluster,
    Seeds: []string{"node1:7946"},
})
defer node.Shutdown()

cache := node.Cache()
sessions := hive.NewValueStore[Session](cache, "sessions")

sessions.Set("user:123", Session{UserID: 123, Token: "abc"})
s, err := sessions.Get("user:123")

How it works

Each instance of your application runs a Hive node. Nodes discover each other through a seed list and form a self-organizing cluster using a gossip protocol. Keys are distributed across nodes using consistent hashing, replicated according to your replication factor, and automatically redistributed when nodes join or leave.

  • Leaderless — every node is equal, no election needed
  • Self-healing — nodes that go silent are detected and their keys redistributed
  • Embeddable — no sidecar, no separate process, just a Go import
  • Minimal dependencies — uses msgpack for serialization, nothing else added to your go.mod

Installation

go get github.com/EmilioRosiles/hive

Usage

Standalone (single instance)

Good for development or single-node deployments. Data stays local, no networking.

node, err := hive.NewNode(hive.Config{})
if err != nil {
    log.Fatal(err)
}
defer node.Shutdown()

cache := node.Cache()
counters := hive.NewValueStore[int](cache, "counters")
counters.Set("visits", 42)

v, err := counters.Get("visits")
Cluster mode

Each application instance joins the same cluster by pointing at one or more seed addresses. Seeds only need to be reachable at startup — once the node has joined, membership is maintained through gossip.

node, err := hive.NewNode(hive.Config{
    Mode:     hive.ModeCluster,
    BindPort: 7946,
    Seeds:    []string{"10.0.0.1:7946", "10.0.0.2:7946"},
})

In a containerized environment, seeds are typically set via an environment variable:

seeds := strings.Split(os.Getenv("HIVE_SEEDS"), ",")

node, err := hive.NewNode(hive.Config{
    Mode:  hive.ModeCluster,
    Seeds: seeds,
})
Checking cluster state
status := node.Status()
fmt.Printf("node %s, cluster size %d\n", status.NodeID, status.Size)
for _, p := range status.Peers {
    fmt.Printf("  peer %s addr=%s alive=%v\n", p.NodeID, p.Addr, p.Alive)
}

Stores

Multiple stores can share the same node — they are namespaced views over the same underlying cluster. Obtain a Cache handle from the node and pass it to each store constructor.

cache := node.Cache()

sessions  := hive.NewValueStore[Session](cache, "sessions")
online    := hive.NewSetStore(cache, "online_users")
streams   := hive.NewHashStore[Stream](cache, "streams")
queue     := hive.NewListStore[Task](cache, "work_queue")
scores    := hive.NewZSetStore(cache, "leaderboard")

Each store type maps to a Redis-style API.

ValueStore[T]

A typed key/value store. Values are msgpack-encoded structs or scalars.

type Session struct {
    UserID int
    Token  string
}

sessions := hive.NewValueStore[Session](cache, "sessions")

// Set stores a value.
err := sessions.Set("user:123", Session{UserID: 123, Token: "abc"})

// Get retrieves and decodes a value. Errors if missing or expired.
s, err := sessions.Get("user:123")

// Del removes a key.
sessions.Del("user:123")

// Expire sets a TTL. The key is deleted automatically after the duration elapses.
sessions.Expire("user:123", 30*time.Minute)
SetStore

A distributed string set. Members can carry independent per-member TTLs, making it useful for tracking presence or short-lived memberships.

online := hive.NewSetStore(cache, "online_users")

// SAdd adds a member to the set at key.
online.SAdd("room:1", "user:123")

// SExpireMember sets a per-member TTL. Other members and the key are unaffected.
online.SExpireMember("room:1", "user:123", 30*time.Second)

// SMembers returns all live members.
members, err := online.SMembers("room:1")

// SIsMember checks membership.
ok, err := online.SIsMember("room:1", "user:123")

// SCard returns the number of live members.
n, err := online.SCard("room:1")

// SRem removes a single member.
online.SRem("room:1", "user:123")

// Del removes the entire set. Expire sets a key-level TTL.
online.Del("room:1")
online.Expire("room:1", 5*time.Minute)
HashStore[T]

A typed key/field/value store. Fields within a key carry independent TTLs, making it well-suited for tracking per-entity state with automatic eviction.

type Stream struct {
    StartedAt time.Time
    BitRate   int
}

streams := hive.NewHashStore[Stream](cache, "streams")

// HSet stores a value under key/field.
streams.HSet("user:123", "stream:abc", Stream{StartedAt: time.Now()})

// HExpireField sets a TTL on a single field. Other fields are unaffected.
streams.HExpireField("user:123", "stream:abc", 30*time.Minute)

// HGet retrieves and decodes a single field.
s, err := streams.HGet("user:123", "stream:abc")

// HGetAll retrieves all live fields under a key.
all, err := streams.HGetAll("user:123")

// HKeys returns the names of all live fields.
fields, err := streams.HKeys("user:123")

// HDel removes a single field.
streams.HDel("user:123", "stream:abc")

// Del removes the entire hash. Expire sets a key-level TTL.
streams.Del("user:123")
streams.Expire("user:123", 1*time.Hour)
ListStore[T]

A typed distributed ordered list. Elements are msgpack-encoded. Supports efficient push/pop from both ends, making it suitable for queues, stacks, and activity feeds.

type Task struct {
    ID      string
    Payload []byte
}

queue := hive.NewListStore[Task](cache, "work_queue")

// RPush appends to the tail. LPush prepends to the head.
queue.RPush("jobs", Task{ID: "t1", Payload: data})
queue.LPush("jobs", Task{ID: "t0", Payload: data})

// LPop removes and returns the head. RPop removes and returns the tail.
task, err := queue.LPop("jobs")

// LLen returns the number of elements.
n, err := queue.LLen("jobs")

// LIndex returns the element at index. Negative indices count from the tail.
last, err := queue.LIndex("jobs", -1)

// LRange returns a slice from start to stop inclusive. Negative indices supported.
page, err := queue.LRange("jobs", 0, 9)

// LSet overwrites the element at index.
queue.LSet("jobs", 0, Task{ID: "t0-updated"})

// Del removes the entire list. Expire sets a key-level TTL.
queue.Del("jobs")
queue.Expire("jobs", 1*time.Hour)
ZSetStore

A distributed sorted set. Each member is a unique string associated with a float64 score. Members are always kept in ascending score order, with ties broken lexicographically.

scores := hive.NewZSetStore(cache, "leaderboard")

// ZAdd inserts or updates member with score.
scores.ZAdd("game:1", 9500.0, "alice")
scores.ZAdd("game:1", 8200.0, "bob")

// ZScore returns the score for a member. Errors if member does not exist.
s, err := scores.ZScore("game:1", "alice")

// ZRank returns the 0-based rank in ascending order (lowest score = 0).
// ZRevRank returns the rank in descending order (highest score = 0).
rank, err := scores.ZRank("game:1", "bob")
rank, err  = scores.ZRevRank("game:1", "alice")

// ZCard returns the number of members.
n, err := scores.ZCard("game:1")

// ZRange returns members from rank start to stop inclusive.
// Negative indices count from the top (highest rank).
top3, err := scores.ZRange("game:1", -3, -1)

// ZRangeByScore returns all members with min <= score <= max in ascending order.
mid, err := scores.ZRangeByScore("game:1", 8000.0, 9000.0)

// ZRem removes a member.
scores.ZRem("game:1", "bob")

// Del removes the entire sorted set. Expire sets a key-level TTL.
scores.Del("game:1")
scores.Expire("game:1", 24*time.Hour)

ZRange and ZRangeByScore return []ZSetEntry, where each entry has Member string and Score float64.

TTL behavior

All stores support two levels of TTL:

  • Key-level TTL (Expire) — deletes the entire key when it elapses
  • Field-level TTL (SExpireMember, HExpireField) — evicts a single member or field independently, without affecting other members or the key itself. If all members/fields expire, the key is cleaned up automatically.

Configuration

hive.Config{
    // Unique identifier for this node.
    // Auto-generated if empty.
    NodeID string

    // ModeStandalone (default) or ModeCluster.
    Mode Mode

    // Address to bind the peer communication port to.
    // Default: "0.0.0.0"
    BindAddr string

    // Port for peer communication.
    // Default: 7946
    BindPort int

    // Seed peer addresses (host:port) used to bootstrap cluster membership.
    // Required when Mode is ModeCluster.
    Seeds []string

    // Number of nodes that store a copy of each key.
    // Higher values improve fault tolerance but increase write overhead.
    // Must be <= cluster size. Default: 1
    ReplicationFactor int

    // Maximum memory this node intends to use, in bytes.
    // Controls two things: capacity enforcement (writes are rejected once the
    // limit is reached) and keyspace allocation (nodes with more memory receive
    // proportionally more vnodes on the hash ring, and therefore more keys).
    // Default: total system memory
    MemLimit uint64

    // How often this node sends heartbeats to peers.
    // Default: 3s
    GossipInterval time.Duration

    // Number of peers contacted per gossip round.
    // Default: 3
    GossipFanout int

    // How long to wait after a topology change before rebalancing.
    // Prevents cascading migrations when multiple nodes join or leave at once.
    // Default: 500ms
    RebalanceDebounce time.Duration

    // How often the cluster janitor runs to evict expired store entries
    // and remove dead peer tombstones from the membership table.
    // Default: 30s
    CleanupInterval time.Duration

    // Verbosity of internal log output written to stderr.
    // nil defaults to slog.LevelError (quiet).
    // Set to &slog.LevelInfo or &slog.LevelDebug for more detail.
    LogLevel *slog.Level
}

Consistency model

Hive is an ephemeral, eventually consistent cache.

  • Reads and writes go to the key's primary owner as determined by consistent hashing
  • Replication is asynchronous — replicas may be briefly behind the primary
  • When a network partition heals and keys are redistributed, Hive uses last-write-wins (LWW) conflict resolution: every stored entry carries a nanosecond-precision write timestamp (writeAt), and rebalance only overwrites a local copy if the incoming entry is strictly newer. This prevents split-brain partitions from silently clobbering fresher data.
  • There is no durability — a node restart loses its local data. Surviving replicas retain their copies

This makes Hive well-suited for session caches, rate-limit counters, presence tracking, leaderboards, job queues, and other short-lived shared state where occasional staleness is acceptable.

Data types

Values must be serializable by msgpack:

  • All fields you want preserved must be exported
  • Pointers, slices, maps, and structs are all supported

Architecture notes

Gossip and failure detection

Membership state is propagated using a gossip protocol. Every node periodically sends its view of the cluster to a random subset of peers (GossipFanout). Each outgoing heartbeat carries an incarnation number — a monotonically increasing counter seeded with the current Unix timestamp when the node starts. Seeding from wall time means a restarted node's first heartbeat carries a higher incarnation than any stale dead rumor about it, allowing it to rejoin without manual intervention.

A peer's state is updated only when the incoming incarnation is strictly higher than what is locally known. This prevents stale gossip from overwriting fresh state and avoids the clock-skew problems that arise from comparing wall-clock timestamps directly across machines.

Nodes that fail to respond to a heartbeat are marked dead immediately. Their keys are redistributed after RebalanceDebounce to allow the cluster to stabilize before migrating data.

Virtual nodes and memory-proportional keyspace

The hash ring uses virtual nodes (vnodes) to distribute keyspace. Each node's vnode count is derived from its MemLimit relative to the rest of the cluster: a node with twice the memory of its peers owns roughly twice as much keyspace. This means data naturally flows toward nodes with more capacity without any manual weighting.

Janitor

A background janitor runs every CleanupInterval and performs two tasks:

  1. Expired entry eviction — scans the local store and removes entries whose TTL has elapsed
  2. Tombstone cleanup — removes dead peer records from the membership table once they are no longer needed for gossip convergence
Split-brain recovery

Each stored entry carries a writeAt timestamp (Unix nanoseconds, set at the time of the write). When rebalancing after a partition heals, incoming entries are written only if their writeAt is strictly newer than the local copy. This last-write-wins strategy ensures the most recently written value survives without requiring coordination between nodes.

Operational notes

Ports — each node needs its BindPort reachable by all other nodes. In Docker/Kubernetes, expose and map the port explicitly.

Seeds — at least one seed must be reachable when a node starts. Seeds do not need to be stable or permanent — any alive cluster member works.

Replication factor — keep it ≤ the minimum expected cluster size. A factor of 2 with a 2-node cluster means every node holds every key.

Graceful shutdown — calling node.Shutdown() announces the departure to peers so they can redistribute keys immediately.

Memory limitsMemLimit affects both write rejection and ring weight. Nodes that exceed their limit return an error on write; they do not evict existing entries to make room. Use TTLs on keys that should not accumulate indefinitely.

License

MIT

Documentation

Overview

Package hive provides an embeddable, leaderless distributed cache for Go applications. Any Go application can include a Hive node to participate in a self-organizing cluster that shares in-memory state across instances without external infrastructure.

Basic usage:

node, err := hive.NewNode(hive.Config{
    Mode:  hive.ModeCluster,
    Seeds: []string{"node1:7946", "node2:7946"},
})
if err != nil {
    log.Fatal(err)
}
defer node.Shutdown()

cache := node.Cache()
sessions := hive.NewValueStore[Session](cache, "sessions")
users    := hive.NewValueStore[User](cache, "users")

sessions.Set("abc", mySession)
val, err := sessions.Get("abc")

Index

Constants

This section is empty.

Variables

View Source
var ErrCapacityExceeded = store.ErrCapacityExceeded

ErrCapacityExceeded is returned by write operations when the node has reached its configured MemLimit. Scale the cluster horizontally to add capacity.

View Source
var ErrNotFound = cluster.ErrNotFound

ErrNotFound is returned by Get operations when the key or field does not exist or has expired.

Functions

This section is empty.

Types

type Cache

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

Cache is a handle to the cluster's data layer obtained from a Node. It is the entry point for store constructors and cluster-wide operations.

type ClusterStatus

type ClusterStatus struct {
	Config
	Peers []cluster.PeerInfo
	Size  int
}

ClusterStatus is a point-in-time snapshot of cluster membership.

type Config

type Config struct {
	// NodeID is a unique identifier for this node.
	// Defaults to a generated UUID if empty.
	NodeID string

	// Mode controls standalone vs cluster operation.
	// Defaults to ModeStandalone.
	Mode Mode

	// BindAddr is the address this node listens on for peer communication.
	// Defaults to "0.0.0.0".
	BindAddr string

	// BindPort is the port this node listens on for peer communication.
	// Defaults to 7946.
	BindPort int

	// Seeds is a list of peer addresses (host:port) used to bootstrap
	// cluster membership. At least one reachable seed is required when
	// Mode is ModeCluster.
	Seeds []string

	// ReplicationFactor is the number of nodes that should hold a copy
	// of each key. Must be <= cluster size. Defaults to 1.
	ReplicationFactor int

	// MemLimit is the maximum memory this node intends to use, in bytes.
	// It is used to compute the node's virtual node count on the hash ring:
	// nodes with more memory receive proportionally more keyspace.
	// A value of 0 uses the default of 100 virtual nodes.
	MemLimit uint64

	// GossipInterval is how often this node sends heartbeats to peers.
	// Defaults to 1s.
	GossipInterval time.Duration

	// GossipFanout is how many peers receive each heartbeat round.
	// Defaults to 3.
	GossipFanout int

	// RebalanceDebounce is the delay after a topology change before
	// rebalancing starts, to let the cluster stabilize.
	// Defaults to 500ms.
	RebalanceDebounce time.Duration

	// CleanupInterval is how often the cluster janitor runs to evict dead peer
	// tombstones and expired store entries.
	// Default: 30s
	CleanupInterval time.Duration

	// LogLevel controls the verbosity of internal log output.
	// nil defaults to slog.LevelError (quiet). Set explicitly to enable
	// more verbose output, e.g. &slog.LevelInfo or &slog.LevelDebug.
	LogLevel *slog.Level
}

Config holds all configuration for a Hive node.

type HashStore

type HashStore[T any] struct {
	// contains filtered or unexported fields
}

HashStore is a typed key/field/value store backed by a Cache. Keys are namespaced as {name}:h:{key} to prevent collisions with other stores on the same node.

streams := hive.NewHashStore[Stream](cache, "streams")
streams.HSet("user:123", "stream:abc", Stream{StartedAt: time.Now()})
streams.HExpireField("user:123", "stream:abc", 30*time.Minute)

func NewHashStore

func NewHashStore[T any](cache *Cache, name string) *HashStore[T]

NewHashStore creates a typed hash store backed by cache. name is used as the namespace — use a distinct name per hash type.

func (*HashStore[T]) Del

func (h *HashStore[T]) Del(key string) error

Del removes the entire hash at key.

func (*HashStore[T]) Expire

func (h *HashStore[T]) Expire(key string, ttl time.Duration) error

Expire sets a key-level TTL. The entire hash is deleted after ttl elapses.

func (*HashStore[T]) HDel

func (h *HashStore[T]) HDel(key, field string) error

HDel removes field from the hash at key.

func (*HashStore[T]) HExpireField

func (h *HashStore[T]) HExpireField(key, field string, ttl time.Duration) error

HExpireField sets a TTL on a single field. The field is evicted after ttl elapses without affecting other fields or the key itself.

func (*HashStore[T]) HGet

func (h *HashStore[T]) HGet(key, field string) (T, error)

HGet retrieves and decodes the value stored under key/field. Returns an error if the key or field does not exist or has expired.

func (*HashStore[T]) HGetAll

func (h *HashStore[T]) HGetAll(key string) (map[string]T, error)

HGetAll retrieves and decodes all live fields under key. Results are returned as alternating field/value pairs, same as Redis HGETALL.

func (*HashStore[T]) HKeys

func (h *HashStore[T]) HKeys(key string) ([]string, error)

HKeys returns the names of all live fields under key.

func (*HashStore[T]) HSet

func (h *HashStore[T]) HSet(key, field string, value T) error

HSet encodes value using msgpack and stores it under key/field.

func (*HashStore[T]) HSetWithTTL

func (h *HashStore[T]) HSetWithTTL(key, field string, value T, ttl time.Duration) error

HSetWithTTL encodes value and stores it under key/field with a per-field TTL.

type ListStore

type ListStore[T any] struct {
	// contains filtered or unexported fields
}

ListStore[T] is a distributed ordered list backed by a Cache. Each element is msgpack-encoded. Keys are namespaced as {name}:l:{key}.

queue := hive.NewListStore[Task](cache, "work_queue")
queue.RPush("jobs", task)
job, err := queue.LPop("jobs")

func NewListStore

func NewListStore[T any](cache *Cache, name string) *ListStore[T]

NewListStore creates a list store backed by cache. name is used as the namespace — use a distinct name per list.

func (*ListStore[T]) Del

func (l *ListStore[T]) Del(key string) error

Del removes the entire list at key.

func (*ListStore[T]) Expire

func (l *ListStore[T]) Expire(key string, ttl time.Duration) error

Expire sets a key-level TTL. The entire list is deleted after ttl elapses.

func (*ListStore[T]) LIndex

func (l *ListStore[T]) LIndex(key string, index int) (T, error)

LIndex returns the element at index. Negative indices count from the tail. Returns ErrNotFound if the index is out of bounds.

func (*ListStore[T]) LLen

func (l *ListStore[T]) LLen(key string) (int, error)

LLen returns the number of elements in the list at key.

func (*ListStore[T]) LPop

func (l *ListStore[T]) LPop(key string) (T, error)

LPop removes and returns the head element. Returns ErrNotFound if the list is empty.

func (*ListStore[T]) LPush

func (l *ListStore[T]) LPush(key string, value T) error

LPush prepends value to the head of the list at key.

func (*ListStore[T]) LRange

func (l *ListStore[T]) LRange(key string, start, stop int) ([]T, error)

LRange returns elements from start to stop inclusive. Negative indices are supported. Out-of-range bounds are clipped silently.

func (*ListStore[T]) LSet

func (l *ListStore[T]) LSet(key string, index int, value T) error

LSet overwrites the element at index. Returns ErrNotFound if out of bounds.

func (*ListStore[T]) RPop

func (l *ListStore[T]) RPop(key string) (T, error)

RPop removes and returns the tail element. Returns ErrNotFound if the list is empty.

func (*ListStore[T]) RPush

func (l *ListStore[T]) RPush(key string, value T) error

RPush appends value to the tail of the list at key.

type Mode

type Mode int

Mode controls how the node participates in the cluster.

const (
	// ModeStandalone runs as a single local node with no clustering.
	// Useful for development or single-instance deployments.
	ModeStandalone Mode = iota

	// ModeCluster runs as a peer node that discovers and joins other nodes.
	ModeCluster
)

type Node

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

Node is a single member of the Hive cluster. Create one per application instance via NewNode. Multiple stores can share a single Node.

func NewNode

func NewNode(cfg Config) (*Node, error)

NewNode creates and starts a Hive node with the given configuration. In ModeCluster the node will attempt to contact Seeds and join the cluster. In ModeStandalone the node operates as a local in-memory cache only.

func (*Node) Cache

func (n *Node) Cache() *Cache

Cache returns a handle to the cluster's data layer. Pass it to store constructors (NewValueStore, NewSetStore, NewHashStore). Multiple stores can share the same Cache.

func (*Node) Shutdown

func (n *Node) Shutdown() error

Shutdown gracefully stops the node, announcing departure to peers before closing all connections and stopping background workers.

func (*Node) Status

func (n *Node) Status() ClusterStatus

Status returns a snapshot of the current cluster state.

type SetStore

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

SetStore is a distributed string set backed by a Cache. Keys are namespaced as {name}:s:{key} to prevent collisions with other stores on the same node.

online := hive.NewSetStore(cache, "online_users")
online.SAdd("room:1", "user:123")
online.SExpireMember("room:1", "user:123", 30*time.Second)

func NewSetStore

func NewSetStore(cache *Cache, name string) *SetStore

NewSetStore creates a set store backed by cache. name is used as the namespace — use a distinct name per set.

func (*SetStore) Del

func (s *SetStore) Del(key string) error

Del removes the entire set at key.

func (*SetStore) Expire

func (s *SetStore) Expire(key string, ttl time.Duration) error

Expire sets a key-level TTL. The entire set is deleted after ttl elapses.

func (*SetStore) SAdd

func (s *SetStore) SAdd(key, member string) error

SAdd adds member to the set at key with no expiry.

func (*SetStore) SCard

func (s *SetStore) SCard(key string) (int, error)

SCard returns the number of live members in the set at key.

func (*SetStore) SExpireMember

func (s *SetStore) SExpireMember(key, member string, ttl time.Duration) error

SExpireMember sets a TTL on a single member. The member is evicted after ttl elapses without affecting other members or the key itself.

func (*SetStore) SIsMember

func (s *SetStore) SIsMember(key, member string) (bool, error)

SIsMember reports whether member exists in the set at key and has not expired.

func (*SetStore) SMembers

func (s *SetStore) SMembers(key string) ([]string, error)

SMembers returns all live members of the set at key.

func (*SetStore) SRem

func (s *SetStore) SRem(key, member string) error

SRem removes member from the set at key.

type ValueStore

type ValueStore[T any] struct {
	// contains filtered or unexported fields
}

ValueStore is a typed key/value store backed by a Cache. Keys are namespaced as {name}:v:{key} to prevent collisions with other stores on the same node.

sessions := hive.NewValueStore[Session](cache, "sessions")
users    := hive.NewValueStore[User](cache, "users")

func NewValueStore

func NewValueStore[T any](cache *Cache, name string) *ValueStore[T]

NewValueStore creates a typed value store backed by cache. name is used as the namespace — use a distinct name per value type.

func (*ValueStore[T]) Del

func (s *ValueStore[T]) Del(key string) error

Del removes key from the store.

func (*ValueStore[T]) Expire

func (s *ValueStore[T]) Expire(key string, ttl time.Duration) error

Expire sets a TTL on key. The entry is deleted automatically after ttl elapses.

func (*ValueStore[T]) Get

func (s *ValueStore[T]) Get(key string) (T, error)

Get retrieves and decodes the value stored under key. Returns an error if the key does not exist or has expired.

func (*ValueStore[T]) Set

func (s *ValueStore[T]) Set(key string, value T) error

Set encodes value using msgpack and stores it under key.

type ZSetEntry

type ZSetEntry struct {
	Member string
	Score  float64
}

ZSetEntry is a member/score pair returned by ZRange and ZRangeByScore.

type ZSetStore

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

ZSetStore is a distributed sorted set backed by a Cache. Members are unique strings each associated with a float64 score. The set is always kept in ascending score order (ties broken lexicographically). Keys are namespaced as {name}:z:{key}.

scores := hive.NewZSetStore(cache, "leaderboard")
scores.ZAdd("game:1", 9500.0, "alice")
top, _ := scores.ZRange("game:1", -3, -1)

func NewZSetStore

func NewZSetStore(cache *Cache, name string) *ZSetStore

NewZSetStore creates a sorted-set store backed by cache.

func (*ZSetStore) Del

func (z *ZSetStore) Del(key string) error

Del removes the entire sorted set at key.

func (*ZSetStore) Expire

func (z *ZSetStore) Expire(key string, ttl time.Duration) error

Expire sets a key-level TTL. The entire sorted set is deleted after ttl elapses.

func (*ZSetStore) ZAdd

func (z *ZSetStore) ZAdd(key string, score float64, member string) error

ZAdd inserts or updates member with score.

func (*ZSetStore) ZCard

func (z *ZSetStore) ZCard(key string) (int, error)

ZCard returns the number of members.

func (*ZSetStore) ZRange

func (z *ZSetStore) ZRange(key string, start, stop int) ([]ZSetEntry, error)

ZRange returns members from rank start to rank stop inclusive. Negative indices count from the end (highest rank). Out-of-range bounds are clipped silently.

func (*ZSetStore) ZRangeByScore

func (z *ZSetStore) ZRangeByScore(key string, min, max float64) ([]ZSetEntry, error)

ZRangeByScore returns all members with min <= score <= max in ascending order.

func (*ZSetStore) ZRank

func (z *ZSetStore) ZRank(key, member string) (int, error)

ZRank returns the 0-based rank of member in ascending score order (lowest = 0). Returns ErrNotFound if member does not exist.

func (*ZSetStore) ZRem

func (z *ZSetStore) ZRem(key, member string) error

ZRem removes member. No-op if member does not exist.

func (*ZSetStore) ZRevRank

func (z *ZSetStore) ZRevRank(key, member string) (int, error)

ZRevRank returns the 0-based rank in descending score order (highest = 0). Returns ErrNotFound if member does not exist.

func (*ZSetStore) ZScore

func (z *ZSetStore) ZScore(key, member string) (float64, error)

ZScore returns the score for member. Returns ErrNotFound if member does not exist.

Directories

Path Synopsis
internal
cluster
Package cluster manages the node's membership in the Hive cluster, including peer tracking, consistent hashing, data routing, and rebalancing.
Package cluster manages the node's membership in the Hive cluster, including peer tracking, consistent hashing, data routing, and rebalancing.
ring
Package ring implements a consistent hash ring with virtual nodes.
Package ring implements a consistent hash ring with virtual nodes.
store
Package store provides a thread-safe, sharded in-memory store with TTL support.
Package store provides a thread-safe, sharded in-memory store with TTL support.
sys
transport
Package transport handles peer-to-peer communication between Hive nodes.
Package transport handles peer-to-peer communication between Hive nodes.

Jump to

Keyboard shortcuts

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