API Reference

Core API documentation for ACOR. See pkg.go.dev for the complete generated reference.

Core Types

AhoCorasickArgs

Configuration for creating an AhoCorasick instance.

type AhoCorasickArgs struct {
    Addr                            string            // Standalone Redis address (conflicts with Addrs)
    Addrs                           []string          // Sentinel or Cluster addresses (one entry still means cluster)
    RingAddrs                       map[string]string // Ring shard addresses
    MasterName                      string            // Sentinel master name
    Password                        string            // Redis password
    DB                              int               // Redis database number (default: 0; rejected with Addrs)
    DialTimeout                     time.Duration     // Connection timeout (zero: go-redis default)
    ReadTimeout                     time.Duration     // Socket read timeout (zero: go-redis default)
    WriteTimeout                    time.Duration     // Socket write timeout (zero: go-redis default)
    MaxRetries                      int               // Command retries (zero: go-redis default; -1: disabled)
    PoolSize                        int               // Connections per server (zero: go-redis default)
    Name                            string            // Collection name (required)
    Debug                           bool              // Send the default logger to stdout (ignored when Logger is set)
    Logger                          Logger            // Custom logger (nil disables logging)
    SchemaVersion                   int               // 0 or 2: V2 (default, optimized); 1: V1 (deprecated)
    EnableCache                     bool              // Local caching for Find/FindIndex (V2 only, not with Preset)
    SelfInvalidationCleanupInterval uint64            // Cleanup frequency for self-invalidation map (default: 128)
    CaseSensitive                   bool              // Enable case-sensitive matching (default: false)
    RollbackTimeout                 time.Duration     // V1 flush/rollback timeout, not the caller's ctx (default: 10s)
    Preset                          Preset            // Architecture preset (default: PresetNone)
    InvalidationPollInterval        time.Duration     // Preset version polling (zero: disabled)
}

AhoCorasick

Main type for pattern matching operations.

ac, err := acor.Create(&acor.AhoCorasickArgs{...})
defer ac.Close()

CreateContext is the same constructor with a context bounding the setup I/O (schema check and initialization write, initial keyword load):

setupCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
instance, err := acor.CreateContext(setupCtx, &acor.AhoCorasickArgs{
    Addr: "localhost:6379",
    Name: "default",
})
_ = instance
_ = err

The context bounds construction only. Canceling it afterwards does not close the instance or stop its invalidation listener — use Close for that, and the *Context methods for per-operation cancellation. The Pub/Sub subscribe is part of that listener, so it runs on the instance’s own context rather than this one.

Core Methods

Add

Add a single keyword to the collection.

count, err := ac.Add("keyword")

AddMany

Add multiple keywords in a batch.

result, err := ac.AddMany([]string{"a", "b", "c"}, nil)
// or with options:
result, err := ac.AddMany([]string{"a", "b", "c"}, &acor.BatchOptions{
    Mode: acor.BatchModeTransactional,
})

Remove

Remove a single keyword from the collection.

count, err := ac.Remove("keyword")

RemoveMany

Remove multiple keywords in a batch.

result, err := ac.RemoveMany([]string{"a", "b"}, nil)
// Pass options when transactional behavior is required.
result, err = ac.RemoveMany([]string{"c", "d"}, &acor.BatchOptions{
    Mode: acor.BatchModeTransactional,
})
_ = result
_ = err

Find

Find all matching keywords in text.

matches, err := ac.Find("sample text")
// Returns: []string{"match1", "match2", ...}

FindIndex

Find matches with their start positions.

positions, err := ac.FindIndex("sample text")
// Returns: map[string][]int{"keyword": {startPos, ...}, ...}

FindMatches

Return every occurrence in scan order with its keyword and half-open rune span [Start, End). The default includes overlapping matches; use MatchKindLeftmostLongest for non-overlapping tokenization or replacement.

matches, err := ac.FindMatches("classic class", &acor.MatchOptions{
    Kind:      acor.MatchKindLeftmostLongest,
    WholeWord: true,
})
_ = matches
_ = err
type Match struct {
    Keyword string
    Start   int // Rune offset, inclusive
    End     int // Rune offset, exclusive
}

type MatchOptions struct {
    Kind      MatchKind
    WholeWord bool
    WordRune  func(rune) bool // Optional whole-word predicate
}

const (
    MatchKindOverlapping MatchKind = iota // Default
    MatchKindLeftmostLongest
)

WholeWord uses letters, digits, combining marks, and underscores as word runes. Set WordRune when those defaults do not fit the input script.

Contains

Report whether any keyword occurs, stopping at the first match.

found, err := ac.Contains("sample text")

FindStream

Scan an io.Reader without buffering the whole input. Matches include overlaps, retain rune offsets across reads, and arrive in scan order. Returning false from the callback stops the scan.

err := ac.FindStream(strings.NewReader("sample text"), func(match acor.Match) bool {
    _ = match
    return true
})
_ = err

Streaming does not apply whole-word or leftmost-longest filtering because those modes require buffering. Use FindMatches for bounded strings that need those options.

FindMany

Find matches in multiple texts.

matches, err := ac.FindMany([]string{"text1", "text2"})
// Returns: map[string][]string{"text1": {"kw", ...}, ...} (keyed by input text)

FindParallel

Find matches using parallel processing.

matches, err := ac.FindParallel(largeText, &acor.ParallelOptions{
    Workers:   4,
    Boundary:  acor.ChunkBoundaryWord,
})

Keywords longer than ParallelOptions.Overlap can be missed at chunk boundaries. Set Overlap to at least the longest expected keyword.

FindIndexParallel

Find start positions using the same parallel chunking options.

positions, err := ac.FindIndexParallel(largeText, acor.DefaultParallelOptions())

Info

Get collection statistics.

info, err := ac.Info()
// Returns: &AhoCorasickInfo{Keywords: N, Nodes: M, Preset: ..., MemoryBytes: ..., TrieDepth: ...}

CacheStats

Get local cache statistics. Unlike Info, this performs no Redis I/O, so it is cheap enough to scrape on a timer.

stats := ac.CacheStats()
// Returns: CacheStats{Hits: N, Misses: M, Rebuilds: R, RebuildDuration: ..., LastInvalidationLag: ...}

The counters are per instance and per process — scrape every instance in a fleet. See Monitoring for how to read them, including why Rebuilds does not equal Misses and why LastInvalidationLag carries clock skew.

Flush

Clear all data from the collection.

err := ac.Flush()

Close

Close the Redis connection.

err := ac.Close()

AhoCorasickInfo

Statistics about an Aho-Corasick instance.

type AhoCorasickInfo struct {
    Keywords    int    // Number of keywords
    Nodes       int    // Number of trie nodes (states)
    Preset      Preset // Architecture preset (internal default sentinel in original mode)
    MemoryBytes int64  // Estimated memory usage in bytes (zero in original mode)
    TrieDepth   int    // Maximum trie depth (zero in original mode)
}

CacheStats (type)

A snapshot of one instance’s local cache activity. Returned by CacheStats(), never constructed by callers — fields may be added inside v1.

type CacheStats struct {
    Hits                uint64        // Reads served without rebuilding the automaton
    Misses              uint64        // Reads that waited for a rebuild
    Rebuilds            uint64        // Automaton builds (starts at 1 in Preset mode)
    RebuildDuration     time.Duration // Cumulative build time, excluding Redis I/O
    LastInvalidationLag time.Duration // Last peer invalidation delay (Preset/EnableCache only; carries clock skew)
}

Preset

Architecture presets for the preset-optimized Redis engine.

const (
    PresetNone            Preset = iota // Zero value (unset) — falls through to original V1/V2 mode
    PresetSpeed                         // Full DFA + flat array — max speed, higher memory
    PresetBalanced                      // Double-Array Trie + Banded DFA — best speed-to-memory ratio
    PresetMemoryEfficient               // Map-based + Bloom filter — min memory, slower search
)

Redis-Backed Engine with Presets

Redis-backed Aho-Corasick that combines Redis persistence with a local preset-optimized automaton. Writes go to Redis atomically (V2 Lua scripts with optimistic locking); reads hit the local engine with no Redis I/O. Created via the unified Create API with Preset set.

ac, err := acor.Create(&acor.AhoCorasickArgs{
    Addr:          "localhost:6379",
    Name:          "my-collection",
    Preset:        acor.PresetBalanced,
    CaseSensitive: false,
})
defer ac.Close()

AhoCorasickArgs (Preset field)

The AhoCorasickArgs struct includes a Preset field for the engine mode:

type AhoCorasickArgs struct {
    // ... standard Redis connection fields ...
    Preset         Preset // Architecture preset: PresetSpeed, PresetBalanced, PresetMemoryEfficient
    // ... other fields ...
}

Preset-Optimized Redis Methods

// Create
ac, err := acor.Create(&acor.AhoCorasickArgs{
    Addr:   "localhost:6379",
    Name:   "my-collection",
    Preset: acor.PresetBalanced,
})

// Add/Remove
added, err := ac.Add("keyword")      // (int, error)
removed, err := ac.Remove("keyword") // (int, error)

// Find (0 RTT on hot path — reads from local engine)
matches, err := ac.Find("text")       // ([]string, error)
positions, err := ac.FindIndex("text") // (map[string][]int, error)
spans, err := ac.FindMatches("text", nil) // ([]Match, error)
found, err := ac.Contains("text")          // (bool, error)

// Info
info, err := ac.Info()   // (*AhoCorasickInfo, error)

// Flush
err := ac.Flush()

// Close
err := ac.Close()

Context Variants

Operations that may perform Redis I/O also accept an explicit context.Context: AddContext, RemoveContext, FindContext, FindIndexContext, FindMatchesContext, ContainsContext, FindStreamContext, FlushContext, InfoContext, SuggestContext, SuggestIndexContext, AddManyContext, RemoveManyContext, FindManyContext, FindParallelContext, and FindIndexParallelContext.

matches, err := ac.FindMatchesContext(ctx, text, nil)

Suggest Methods

Suggest

Get prefix suggestions.

suggestions, err := ac.Suggest("pre")

SuggestIndex

Get suggestions with positions.

positions, err := ac.SuggestIndex("pre")

Batch Operations

BatchOptions

type BatchOptions struct {
    Mode BatchMode // BestEffort (default) or Transactional
}

BatchResult

type BatchResult struct {
    Added   []string       // Successfully added keywords
    Removed []string       // Successfully removed keywords
    Failed  []KeywordError // Keywords that failed with their errors
    Skipped []string       // Duplicate adds or absent removes
}

KeywordError

type KeywordError struct {
    Keyword string
    Error   error
}

Parallel Options

ParallelOptions

type ParallelOptions struct {
    Workers   int           // Concurrent goroutines (default: runtime.NumCPU())
    ChunkSize int           // Target chunk size in characters (default: 1000)
    Boundary  ChunkBoundary // How chunks are split (default: ChunkBoundaryWord)
    Overlap   int           // Overlap characters between chunks (default: 50)
}

DefaultParallelOptions

Returns parallel options with sensible defaults:

opts := acor.DefaultParallelOptions()
matches, err := ac.FindParallel(text, opts)

ChunkBoundary

const (
    ChunkBoundaryWord     ChunkBoundary = iota // Split at whitespace (default)
    ChunkBoundarySentence                       // Split at sentence boundaries (. ! ?)
    ChunkBoundaryLine                           // Split at newlines
)