hermes

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Apr 11, 2025 License: MIT Imports: 16 Imported by: 0

README

In-Memory Data Store with Transactions and Pub/Sub

A high-performance thread-safe in-memory data store with advanced features for Go applications.

Features

  • 🧩 ACID Transactions with rollback support
  • 📡 Publish-Subscribe messaging pattern
  • ⏲ Automatic Expiration (TTL) for keys
  • ⚡ Atomic Operations (CAS, INCR/DECR, LPUSH/RPUSH)
  • 🔍 Type-Safe Operations for lists and counters
  • 📊 Built-in Logging with configurable output

Installation

go get github.com/themedef/go-hermes

Basic Usage

import (
    "context"
    "time"
    "github.com/themedef/go-hermes"
)

func main() {
    // Initialize store
    cfg := hermes.Config{
        EnableLogging:   true,
        LogFile:         "data.log",
    }
    db := hermes.NewStore(cfg)

    // Basic operations
    ctx := context.Background()
    
    // Set key with TTL
    err := db.Set(ctx, "session:123", "user_data", 3600)
    
    // Get value
    val, err := db.Get(ctx, "session:123")
    
    // Delete key
    deleted, err := db.Delete(ctx, "session:123")

    // Ensure the store is closed properly on application exit
    defer func() {
        if err := db.Close(); err != nil {
            log.Printf("Error while closing Hermes store: %v\n", err)
        }
    }()
}

STORE Documentation

Transaction Management

// Start transaction
tx := db.Transaction()

// Add operations
tx.Set(ctx, "account:1", 1000, 0)
tx.Incr(ctx, "account:1")
tx.Decr(ctx, "account:1")

// Commit transaction
if err := tx.Commit(); err != nil {
    // Handle error and rollback
    tx.Rollback()
}

TRANSACTION Documentation

Pub/Sub System

// Subscribe to channel
messages := db.Subscribe("updates")

// Receive messages
go func() {
    for msg := range messages {
        fmt.Println("Received update:", msg)
    }
}()

// Unsubscribe when done
db.Unsubscribe("updates", messages)

PUBSUB Documentation

Benchmarks

Performance tested on a single-core execution using Go's testing and runtime packages.

Operation Ops Count Time (sec) RPS (req/sec)
Get 1.000.000 0.25 4,010,652
Set 1,000,000 0.79 1,241,792

️ Test environment: 1 CPU core, TTL disabled, logging disabled.

Performance Characteristics

Operation Time Complexity Lock Type Notes
Get O(1) RLock Read-only access
Set/Delete O(1) Lock Full mutex lock
List operations O(1) Lock Head/tail ops for lists
Pub/Sub O(n) RLock n = number of subscribers
TTL Updates O(1) Lock Time complexity for map access

Performance Notes

  • Thread Safety: All operations protected by RWMutex
  • Memory Management: Automatic expired key cleanup
  • Batched Operations: Efficient flush implementation
  • Non-Blocking: Pub/Sub uses buffered channels

Important Notes:

  • Always use context for timeout/cancellation control
  • Close Pub/Sub channels when no longer needed
  • Transactions must be explicitly committed
  • Default channel buffer size: 10000 messages

License

MIT License. See LICENSE for full text.


Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrKeyNotFound          = errors.New("key not found")
	ErrKeyExpired           = errors.New("key expired")
	ErrKeyExists            = errors.New("key already exists")
	ErrInvalidType          = errors.New("invalid data type")
	ErrValueMismatch        = errors.New("value mismatch")
	ErrInvalidValueType     = errors.New("invalid value type")
	ErrContextCanceled      = errors.New("operation canceled")
	ErrInvalidTTL           = errors.New("invalid TTL value")
	ErrEmptyList            = errors.New("list is empty")
	ErrEmptyValues          = errors.New("empty value")
	ErrInvalidKey           = errors.New("invalid key")
	ErrTransactionNotActive = errors.New("transaction is not active")
	ErrTransactionFailed    = errors.New("transaction failed")
)

Functions

func BenchmarkParallelGet

func BenchmarkParallelGet()

func BenchmarkParallelSet

func BenchmarkParallelSet()

func IsContextCanceled

func IsContextCanceled(err error) bool

func IsEmptyList

func IsEmptyList(err error) bool

func IsInvalidKey

func IsInvalidKey(err error) bool

func IsInvalidTTL

func IsInvalidTTL(err error) bool

func IsInvalidType

func IsInvalidType(err error) bool

func IsInvalidValueType

func IsInvalidValueType(err error) bool

func IsKeyExists

func IsKeyExists(err error) bool

func IsKeyExpired

func IsKeyExpired(err error) bool

func IsKeyNotFound

func IsKeyNotFound(err error) bool

func IsTransactionFailed

func IsTransactionFailed(err error) bool

func IsTransactionNotActive

func IsTransactionNotActive(err error) bool

func IsValueMismatch

func IsValueMismatch(err error) bool

func NewStore

func NewStore(config Config) contracts.StoreHandler

Types

type APIHandler

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

func NewAPIHandler

func NewAPIHandler(ctx context.Context, db contracts.StoreHandler) *APIHandler

func (*APIHandler) CloseAllSubscriptionsHandler

func (h *APIHandler) CloseAllSubscriptionsHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) DecrByHandler added in v1.0.1

func (h *APIHandler) DecrByHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) DecrHandler

func (h *APIHandler) DecrHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) DeleteHandler

func (h *APIHandler) DeleteHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) DropAllHandler

func (h *APIHandler) DropAllHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) ExistsHandler

func (h *APIHandler) ExistsHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) ExpireHandler added in v1.0.1

func (h *APIHandler) ExpireHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) FindByValueHandler

func (h *APIHandler) FindByValueHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) GetHandler

func (h *APIHandler) GetHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) GetSetHandler

func (h *APIHandler) GetSetHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) GetWithDetailsHandler

func (h *APIHandler) GetWithDetailsHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) HDelHandler

func (h *APIHandler) HDelHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) HExistsHandler

func (h *APIHandler) HExistsHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) HGetAllHandler

func (h *APIHandler) HGetAllHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) HGetHandler

func (h *APIHandler) HGetHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) HLenHandler

func (h *APIHandler) HLenHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) HSetHandler

func (h *APIHandler) HSetHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) IncrByHandler added in v1.0.1

func (h *APIHandler) IncrByHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) IncrHandler

func (h *APIHandler) IncrHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) LLenHandler

func (h *APIHandler) LLenHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) LPopHandler

func (h *APIHandler) LPopHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) LPushHandler

func (h *APIHandler) LPushHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) LRangeHandler

func (h *APIHandler) LRangeHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) LTrimHandler added in v1.0.1

func (h *APIHandler) LTrimHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) ListSubscriptionsHandler

func (h *APIHandler) ListSubscriptionsHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) PersistHandler added in v1.0.1

func (h *APIHandler) PersistHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) RPopHandler

func (h *APIHandler) RPopHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) RPushHandler

func (h *APIHandler) RPushHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) RenameHandler

func (h *APIHandler) RenameHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) RunServer

func (h *APIHandler) RunServer(port, prefix string, middlewares ...func(http.Handler) http.Handler)

func (*APIHandler) SAddHandler added in v1.0.1

func (h *APIHandler) SAddHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) SCardHandler added in v1.0.1

func (h *APIHandler) SCardHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) SIsMemberHandler added in v1.0.1

func (h *APIHandler) SIsMemberHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) SMembersHandler added in v1.0.1

func (h *APIHandler) SMembersHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) SRemHandler added in v1.0.1

func (h *APIHandler) SRemHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) SetCASHandler

func (h *APIHandler) SetCASHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) SetHandler

func (h *APIHandler) SetHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) SetNXHandler

func (h *APIHandler) SetNXHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) SetXXHandler

func (h *APIHandler) SetXXHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) SubscribeHandler

func (h *APIHandler) SubscribeHandler(w http.ResponseWriter, r *http.Request)

func (*APIHandler) TypeHandler

func (h *APIHandler) TypeHandler(w http.ResponseWriter, r *http.Request)

type CommandAPI

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

func (*CommandAPI) Execute

func (c *CommandAPI) Execute(ctx context.Context, parts []string) (string, error)

type Config

type Config struct {
	ShardCount       int
	CleanupInterval  time.Duration
	EnableLogging    bool
	LogFile          string
	LogBufferSize    int
	MinLevel         logger.LogLevel
	PubSubBufferSize int
}

type DB

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

func (*DB) Close

func (db *DB) Close() error

func (*DB) CloseAllSubscriptionsForKey

func (db *DB) CloseAllSubscriptionsForKey(key string)

func (*DB) Commands

func (db *DB) Commands() contracts.CommandsHandler

func (*DB) Decr

func (db *DB) Decr(ctx context.Context, key string) (int64, error)

func (*DB) DecrBy added in v1.0.1

func (db *DB) DecrBy(ctx context.Context, key string, decrement int64) (int64, error)

func (*DB) Delete

func (db *DB) Delete(ctx context.Context, key string) error

func (*DB) DropAll

func (db *DB) DropAll(ctx context.Context) error

func (*DB) Exists

func (db *DB) Exists(ctx context.Context, key string) (bool, error)

func (*DB) Expire added in v1.0.1

func (db *DB) Expire(ctx context.Context, key string, ttl int) (bool, error)

func (*DB) FindByValue

func (db *DB) FindByValue(ctx context.Context, value interface{}) ([]string, error)

func (*DB) Get

func (db *DB) Get(ctx context.Context, key string) (interface{}, error)

func (*DB) GetRawEntry added in v1.0.1

func (db *DB) GetRawEntry(ctx context.Context, key string) (types.Entry, error)

func (*DB) GetSet

func (db *DB) GetSet(ctx context.Context, key string, newValue interface{}, ttl int) (interface{}, error)

func (*DB) GetWithDetails

func (db *DB) GetWithDetails(ctx context.Context, key string) (interface{}, int, error)

func (*DB) HDel

func (db *DB) HDel(ctx context.Context, key string, field string) error

func (*DB) HExists

func (db *DB) HExists(ctx context.Context, key string, field string) (bool, error)

func (*DB) HGet

func (db *DB) HGet(ctx context.Context, key string, field string) (interface{}, error)

func (*DB) HGetAll

func (db *DB) HGetAll(ctx context.Context, key string) (map[string]interface{}, error)

func (*DB) HLen

func (db *DB) HLen(ctx context.Context, key string) (int, error)

func (*DB) HSet

func (db *DB) HSet(ctx context.Context, key string, field string, value interface{}, ttl int) error

func (*DB) Incr

func (db *DB) Incr(ctx context.Context, key string) (int64, error)

func (*DB) IncrBy added in v1.0.1

func (db *DB) IncrBy(ctx context.Context, key string, increment int64) (int64, error)

func (*DB) LLen

func (db *DB) LLen(ctx context.Context, key string) (int, error)

func (*DB) LPop

func (db *DB) LPop(ctx context.Context, key string) (interface{}, error)

func (*DB) LPush

func (db *DB) LPush(ctx context.Context, key string, values ...interface{}) error

func (*DB) LRange

func (db *DB) LRange(ctx context.Context, key string, start, end int) ([]interface{}, error)

func (*DB) LTrim added in v1.0.1

func (db *DB) LTrim(ctx context.Context, key string, start, stop int) error

func (*DB) ListSubscriptions

func (db *DB) ListSubscriptions() []string

func (*DB) Logger

func (db *DB) Logger() contracts.LoggerHandler

func (*DB) Persist added in v1.0.1

func (db *DB) Persist(ctx context.Context, key string) (bool, error)

func (*DB) RPop

func (db *DB) RPop(ctx context.Context, key string) (interface{}, error)

func (*DB) RPush

func (db *DB) RPush(ctx context.Context, key string, values ...interface{}) error

func (*DB) Rename

func (db *DB) Rename(ctx context.Context, oldKey, newKey string) error

func (*DB) RestoreRawEntry added in v1.0.1

func (db *DB) RestoreRawEntry(ctx context.Context, key string, e types.Entry) error

func (*DB) SAdd added in v1.0.1

func (db *DB) SAdd(ctx context.Context, key string, members ...interface{}) error

func (*DB) SCard added in v1.0.1

func (db *DB) SCard(ctx context.Context, key string) (int, error)

func (*DB) SIsMember added in v1.0.1

func (db *DB) SIsMember(ctx context.Context, key string, member interface{}) (bool, error)

func (*DB) SMembers added in v1.0.1

func (db *DB) SMembers(ctx context.Context, key string) ([]interface{}, error)

func (*DB) SRem added in v1.0.1

func (db *DB) SRem(ctx context.Context, key string, members ...interface{}) error

func (*DB) Set

func (db *DB) Set(ctx context.Context, key string, value interface{}, ttl int) error

func (*DB) SetCAS

func (db *DB) SetCAS(ctx context.Context, key string, oldValue, newValue interface{}, ttl int) error

func (*DB) SetNX

func (db *DB) SetNX(ctx context.Context, key string, value interface{}, ttl int) (bool, error)

func (*DB) SetXX

func (db *DB) SetXX(ctx context.Context, key string, value interface{}, ttl int) (bool, error)

func (*DB) Subscribe

func (db *DB) Subscribe(key string) chan string

func (*DB) Transaction

func (db *DB) Transaction() contracts.TransactionHandler

func (*DB) Type

func (db *DB) Type(ctx context.Context, key string) (interface{}, error)

func (*DB) Unsubscribe

func (db *DB) Unsubscribe(key string, ch chan string)

type Transaction

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

func (*Transaction) Commit

func (t *Transaction) Commit() error

func (*Transaction) Decr

func (t *Transaction) Decr(ctx context.Context, key string) error

func (*Transaction) DecrBy added in v1.0.1

func (t *Transaction) DecrBy(ctx context.Context, key string, decrement int64) error

func (*Transaction) Delete

func (t *Transaction) Delete(ctx context.Context, key string) error

func (*Transaction) Exists

func (t *Transaction) Exists(ctx context.Context, key string) (bool, error)

func (*Transaction) Expire added in v1.0.1

func (t *Transaction) Expire(ctx context.Context, key string, ttl int) error

func (*Transaction) FindByValue

func (t *Transaction) FindByValue(ctx context.Context, value interface{}) ([]string, error)

func (*Transaction) Get

func (t *Transaction) Get(ctx context.Context, key string) (interface{}, error)

func (*Transaction) GetSet

func (t *Transaction) GetSet(ctx context.Context, key string, newValue interface{}, ttl int) (interface{}, error)

func (*Transaction) GetWithDetails

func (t *Transaction) GetWithDetails(ctx context.Context, key string) (interface{}, int, error)

func (*Transaction) HDel

func (t *Transaction) HDel(ctx context.Context, key, field string) error

func (*Transaction) HExists

func (t *Transaction) HExists(ctx context.Context, key, field string) (bool, error)

func (*Transaction) HGet

func (t *Transaction) HGet(ctx context.Context, key, field string) (interface{}, error)

func (*Transaction) HGetAll

func (t *Transaction) HGetAll(ctx context.Context, key string) (map[string]interface{}, error)

func (*Transaction) HLen

func (t *Transaction) HLen(ctx context.Context, key string) (int, error)

func (*Transaction) HSet

func (t *Transaction) HSet(ctx context.Context, key, field string, value interface{}, ttl int) error

func (*Transaction) Incr

func (t *Transaction) Incr(ctx context.Context, key string) error

func (*Transaction) IncrBy added in v1.0.1

func (t *Transaction) IncrBy(ctx context.Context, key string, increment int64) error

func (*Transaction) LLen

func (t *Transaction) LLen(ctx context.Context, key string) (int, error)

func (*Transaction) LPop

func (t *Transaction) LPop(ctx context.Context, key string) (interface{}, error)

func (*Transaction) LPush

func (t *Transaction) LPush(ctx context.Context, key string, values ...interface{}) error

func (*Transaction) LRange

func (t *Transaction) LRange(ctx context.Context, key string, start, end int) ([]interface{}, error)

func (*Transaction) LTrim added in v1.0.1

func (t *Transaction) LTrim(ctx context.Context, key string, start, stop int) error

func (*Transaction) Persist added in v1.0.1

func (t *Transaction) Persist(ctx context.Context, key string) error

func (*Transaction) RPop

func (t *Transaction) RPop(ctx context.Context, key string) (interface{}, error)

func (*Transaction) RPush

func (t *Transaction) RPush(ctx context.Context, key string, values ...interface{}) error

func (*Transaction) Rename

func (t *Transaction) Rename(ctx context.Context, oldKey, newKey string) error

func (*Transaction) Rollback

func (t *Transaction) Rollback() error

func (*Transaction) SAdd added in v1.0.1

func (t *Transaction) SAdd(ctx context.Context, key string, members ...interface{}) error

func (*Transaction) SCard added in v1.0.1

func (t *Transaction) SCard(ctx context.Context, key string) (int, error)

func (*Transaction) SIsMember added in v1.0.1

func (t *Transaction) SIsMember(ctx context.Context, key string, member interface{}) (bool, error)

func (*Transaction) SMembers added in v1.0.1

func (t *Transaction) SMembers(ctx context.Context, key string) ([]interface{}, error)

func (*Transaction) SRem added in v1.0.1

func (t *Transaction) SRem(ctx context.Context, key string, members ...interface{}) error

func (*Transaction) Set

func (t *Transaction) Set(ctx context.Context, key string, value interface{}, ttl int) error

func (*Transaction) SetCAS

func (t *Transaction) SetCAS(ctx context.Context, key string, oldValue, newValue interface{}, ttl int) error

func (*Transaction) SetNX

func (t *Transaction) SetNX(ctx context.Context, key string, value interface{}, ttl int) error

func (*Transaction) SetXX

func (t *Transaction) SetXX(ctx context.Context, key string, value interface{}, ttl int) error

func (*Transaction) Type

func (t *Transaction) Type(ctx context.Context, key string) (interface{}, error)

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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