ACOR Documentation

Redis-Backed Engine

The preset-optimized Redis mode (enabled via Preset on AhoCorasickArgs) combines Redis persistence with a local preset-optimized automaton. Redis is the source of truth; reads hit the local engine with no Redis I/O on the hot path.

When to Use

Architecture

                    Write Path
Instance A ──Add()──▶ Lua Script (optimistic lock) ──▶ Redis
                                                  
                       Pub/Sub invalidate ◀────────┘
                            
Instance B ◀────────────────┘
      
      └─ ensureValid() ──▶ reload from Redis ──▶ rebuild local engine

                    Read Path
Instance A ──Find()──▶ local engine (0 RTT)

Quick Start

package main

import (
    "fmt"
    "github.com/skyoo2003/acor/pkg/acor"
)

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

    added, err := ac.Add("hello")
    if err != nil {
        panic(err)
    }
    fmt.Printf("Added: %d\n", added)

    matches, err := ac.Find("hello world")
    if err != nil {
        panic(err)
    }
    fmt.Println(matches) // [hello]
}

AhoCorasickArgs (Preset field)

The AhoCorasickArgs struct includes a Preset field for selecting the local engine architecture:

type AhoCorasickArgs struct {
    // ... Addr, Addrs, RingAddrs, Password, DB, Name ...
    Preset         Preset       // Architecture preset (default: PresetBalanced)
    CaseSensitive   bool         // Enable case-sensitive matching (default: false)
    // ... other fields ...
}

All standard Redis topologies are supported (Standalone, Sentinel, Cluster, Ring) via the connection fields on AhoCorasickArgs.

Preset Selection

The same architecture presets are available:

PresetUse Case
PresetSpeedLatency-critical, memory available
PresetBalancedDefault — best speed-to-memory ratio
PresetMemoryEfficientMillions of patterns, memory constrained
PresetUltimateMaximum throughput production systems

API Reference

// 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)

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

// Flush and Close
err := ac.Flush()
err := ac.Close()

Comparison with AhoCorasick

FeatureAhoCorasick (no Preset)AhoCorasick (with Preset)
Read latency3 RTT (V2) or cached0 RTT (local engine)
Write latencyLua scriptLua script + optimistic lock
Cross-instance syncPub/Sub cache invalidationPub/Sub engine rebuild
SchemaV1 or V2V2 only
PresetsN/ASpeed, Balanced, MemoryEfficient, Ultimate
Suggest/SuggestIndexYesNo
Batch operationsYesNo
Parallel matchingYesNo

Use a Preset-optimized AhoCorasick when you need the fastest possible reads in a distributed setup and can accept the V2-only constraint.

Next Steps