synapse

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2025 License: MIT Imports: 7 Imported by: 0

README

Synapse 🧠

A high-performance, generic similarity-based cache for Go with intelligent sharding and pluggable eviction policies.

GoVersion License Zero Dependencies Go Reference Go Report Card

Overview

Synapse is a thread-safe, context-aware cache that goes beyond traditional key-value storage by supporting similarity-based lookups. When an exact key match isn't found, Synapse can find the "closest" matching key based on a configurable similarity function and threshold.

Key Features
  • 🎯 Similarity-Based Lookups: Find approximate matches when exact keys don't exist
  • 🔧 Generic Types: Fully type-safe with Go generics (1.18+)
  • ⚡ High Performance: Automatic sharding distributes load across multiple concurrent-safe partitions
  • 🧩 Pluggable Similarity Functions: Define custom similarity algorithms for your use case
  • ♻️ Eviction Policies: Currently supports LRU with more policies coming soon
  • ⏰ TTL Support: Automatic expiration of cache entries
  • 🏷️ Namespace Isolation: Partition cache entries by namespace via context
  • 🔒 Thread-Safe: Lock-free reads and efficient write locking per shard
  • 📊 Metadata Support: Attach custom metadata to cache entries
  • 🔌 Context-Aware: Full context.Context integration for cancellation and values

Installation

go get github.com/kolosys/synapse

Quick Start

package main

import (
    "context"
    "fmt"
    "strings"

    "github.com/kolosys/synapse"
    "github.com/kolosys/synapse/eviction"
)

func stringSimilarity(a, b string) float64 {
    a, b = strings.ToLower(a), strings.ToLower(b)
    if a == b {
        return 1.0
    }
    minLen := min(len(a), len(b))
    matches := 0
    for i := 0; i < minLen; i++ {
        if a[i] == b[i] {
            matches++
        } else {
            break
        }
    }
    return float64(matches) / float64(max(len(a), len(b)))
}

func main() {
    ctx := context.Background()

    cache := synapse.New[string, string](
        synapse.WithMaxSize(1000),
        synapse.WithShards(16),
        synapse.WithThreshold(0.7),
        synapse.WithEviction(eviction.NewLRU(1000)),
    )

    cache.WithSimilarity(stringSimilarity)

    cache.Set(ctx, "user:alice", "Alice's data")
    cache.Set(ctx, "user:bob", "Bob's data")

    if value, found := cache.Get(ctx, "user:alice"); found {
        fmt.Println("Exact match:", value)
    }

    value, key, score, found := cache.GetSimilar(ctx, "user:ali")
    if found {
        fmt.Printf("Similar match: %s (key: %s, score: %.2f)\n", value, key, score)
    }
}

API Reference

Core Methods
  • New[K, V](opts ...Option) *Cache[K, V] - Create a new cache instance
  • Get(ctx context.Context, key K) (V, bool) - Retrieve value by exact key match
  • Set(ctx context.Context, key K, value V) error - Store a key-value pair
  • GetSimilar(ctx context.Context, key K) (V, K, float64, bool) - Find most similar key above threshold
  • Delete(ctx context.Context, key K) bool - Remove a key from the cache
  • Len() int - Get total number of entries across all shards
  • WithSimilarity(fn SimilarityFunc[K]) *Cache[K, V] - Set similarity function
Configuration Options
Option Description Default
WithShards(n) Number of shards (1-256) 16
WithMaxSize(size) Maximum number of entries 1000
WithThreshold(t) Similarity threshold (0.0-1.0) 0.8
WithEviction(policy) Eviction policy nil
WithTTL(duration) Time-to-live for entries 0 (no expiration)
WithStats(enable) Enable statistics tracking false
Context Functions
  • WithNamespace(ctx context.Context, namespace string) context.Context - Add namespace to context
  • GetNamespace(ctx context.Context) string - Retrieve namespace from context
  • WithMetadata(ctx context.Context, key string, value any) context.Context - Add metadata to context
  • GetMetadata(ctx context.Context, key string) (any, bool) - Retrieve metadata from context

Examples

Basic Cache Operations
ctx := context.Background()
cache := synapse.New[string, int]()

cache.Set(ctx, "key1", 42)
if value, found := cache.Get(ctx, "key1"); found {
    fmt.Println("Value:", value)
}

cache.Delete(ctx, "key1")
size := cache.Len()
cache := synapse.New[string, string]()
cache.WithSimilarity(func(a, b string) float64 {
    // Return similarity score between 0.0 and 1.0
    return computeSimilarity(a, b)
})

cache.Set(ctx, "apple", "A fruit")
cache.Set(ctx, "application", "A software program")

value, matchedKey, score, found := cache.GetSimilar(ctx, "app")
if found {
    fmt.Printf("Found: %s (matched: %s, similarity: %.2f)\n", value, matchedKey, score)
}
Namespace Isolation
cache := synapse.New[string, string]()

ctx1 := synapse.WithNamespace(context.Background(), "tenant1")
ctx2 := synapse.WithNamespace(context.Background(), "tenant2")

cache.Set(ctx1, "config", "tenant1's config")
cache.Set(ctx2, "config", "tenant2's config")

if value, found := cache.Get(ctx1, "config"); found {
    fmt.Println(value) // Output: tenant1's config
}
TTL Expiration
cache := synapse.New[string, string](
    synapse.WithTTL(5 * time.Minute),
)

cache.Set(ctx, "temp-key", "temporary value")
// Entry expires after 5 minutes
Eviction Policy
import "github.com/kolosys/synapse/eviction"

lru := eviction.NewLRU(1000)
cache := synapse.New[string, string](
    synapse.WithMaxSize(1000),
    synapse.WithEviction(lru),
)

Architecture

Synapse uses sharding to distribute keys across multiple partitions, reducing lock contention and improving concurrent performance. Each shard operates independently with its own:

  • sync.RWMutex for thread-safe access
  • Hash map for O(1) exact lookups
  • Key slice for similarity searches
  • Eviction policy tracker

Exact lookups (Get) route to a single shard using FNV-1a hashing. Similarity searches (GetSimilar) search across all shards sequentially, respecting context cancellation.

Performance

  • Exact lookups: O(1) average case per shard
  • Similarity search: O(n) per shard where n is the number of keys
  • Sharding: More shards improve concurrency but increase overhead
  • Recommendation: Start with 16 shards, adjust based on workload

Each cache entry stores the key, value, timestamps, access count, expiration time, metadata map, and namespace string. Plan capacity based on your key/value sizes.

License

MIT License - see LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetMetadata

func GetMetadata(ctx context.Context, key string) (any, bool)

GetMetadata retrieves a metadata value from the context

func GetNamespace

func GetNamespace(ctx context.Context) string

GetNamespace retrieves the namespace from the context

func WithMetadata

func WithMetadata(ctx context.Context, key string, value any) context.Context

WithMetadata adds metadata to the context

func WithNamespace

func WithNamespace(ctx context.Context, namespace string) context.Context

WithNamespace adds a namespace to the context

Types

type Cache

type Cache[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Cache is a generic similarity-based cache with sharding

func New

func New[K comparable, V any](opts ...Option) *Cache[K, V]

New creates a new cache with the given options

func (*Cache[K, V]) Delete

func (c *Cache[K, V]) Delete(ctx context.Context, key K) bool

Delete removes a key from the cache

func (*Cache[K, V]) Get

func (c *Cache[K, V]) Get(ctx context.Context, key K) (V, bool)

Get retrieves a value by exact key match

func (*Cache[K, V]) GetSimilar

func (c *Cache[K, V]) GetSimilar(ctx context.Context, key K) (V, K, float64, bool)

GetSimilar finds the most similar key above the threshold

func (*Cache[K, V]) Len

func (c *Cache[K, V]) Len() int

Len returns the total number of entries in the cache

func (*Cache[K, V]) Set

func (c *Cache[K, V]) Set(ctx context.Context, key K, value V) error

Set stores a value

func (*Cache[K, V]) Stats added in v0.3.0

func (c *Cache[K, V]) Stats() Stats

Stats returns aggregated statistics from all shards Returns zero values if stats are not enabled

func (*Cache[K, V]) WithSimilarity

func (c *Cache[K, V]) WithSimilarity(fn SimilarityFunc[K]) *Cache[K, V]

WithSimilarity sets the similarity function for the cache

type Entry

type Entry[K comparable, V any] struct {
	Key         K
	Value       V
	CreatedAt   time.Time
	AccessedAt  time.Time
	AccessCount uint64
	ExpiresAt   time.Time
	Metadata    map[string]any
	Namespace   string
}

Entry represents a cache entry with metadata

func (*Entry[K, V]) IsExpired

func (e *Entry[K, V]) IsExpired() bool

IsExpired checks if the entry has expired

func (*Entry[K, V]) Touch

func (e *Entry[K, V]) Touch()

Touch updates the access time and increments access count

type EvictionPolicy

type EvictionPolicy = eviction.EvictionPolicy

EvictionPolicy is re-exported from the eviction package

type Option

type Option func(*Options)

Option is a function that modifies Options

func WithEviction

func WithEviction(policy EvictionPolicy) Option

WithEviction sets the eviction policy

func WithMaxSize

func WithMaxSize(size int) Option

WithMaxSize sets the maximum cache size

func WithShards

func WithShards(n int) Option

WithShards sets the number of shards

func WithStats

func WithStats(enable bool) Option

WithStats enables statistics tracking

func WithTTL

func WithTTL(ttl time.Duration) Option

WithTTL sets the time-to-live for cache entries

func WithThreshold

func WithThreshold(t float64) Option

WithThreshold sets the similarity threshold

type Options

type Options struct {
	NumShards           int
	MaxSize             int
	SimilarityThreshold float64
	EvictionPolicy      EvictionPolicy
	TTL                 time.Duration
	EnableStats         bool
}

Options contains configuration options for the cache

type Shard

type Shard[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Shard represents a single shard of the cache

type Similarity

type Similarity[K comparable] interface {
	// Score computes the similarity score between two keys
	// Returns a value between 0.0 and 1.0
	Score(a, b K) float64

	// Threshold returns the minimum similarity score for a match
	Threshold() float64
}

Similarity is an interface for similarity computation

func NewSimilarity

func NewSimilarity[K comparable](fn SimilarityFunc[K], threshold float64) Similarity[K]

NewSimilarity creates a Similarity from a SimilarityFunc

type SimilarityFunc

type SimilarityFunc[K comparable] func(a, b K) float64

SimilarityFunc is a function type that computes similarity between two keys It should return a score between 0.0 (completely different) and 1.0 (identical)

type Stats added in v0.3.0

type Stats struct {
	Hits            uint64
	Misses          uint64
	Sets            uint64
	Deletes         uint64
	SimilarSearches uint64
	SimilarHits     uint64
	Evictions       uint64
	Expired         uint64
}

Stats contains cache performance statistics

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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