sop

package module
v1.8.8-0...-6a25a8b Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 22 Imported by: 0

README

SOP Data & Compute Platform

SOP is a Data & Compute Platform for high-performance applications and distributed storage workflows.

At its core, SOP combines an embedded storage engine, distributed coordination model, and AI/runtime tooling. It supports scaling from a single device to clustered deployments that share storage and coordination state.

Discussions CI codecov Go Reference Go Report Card

Quickstart

The fastest way to see SOP work is the in-memory B-Tree. No servers, no config:

go run ./examples/quickstart

New to SOP? Read What is SOP, in plain words.

SOP quickstart demo

Every commit runs the delivery pipeline: build, tests, container packaging (GHCR), a staging smoke test, then a human-approved promotion to production.

The SOP Ecosystem

Packed inside the library is everything you need to build next-generation distributed systems:

  • Swarm Computing Engine: A framework for distributed coordination, allowing applications to act as coherent parts of a greater whole.
  • Polyglot Storage Engine: An ACID-compliant B-Tree storage system with Caching and Erasure Coding, optimized for performance. Read the Architecture Whitepaper.
  • AI Scripting & Computing Engine: A versatile runtime that allows for creating intelligent, self-correcting workflows. See Platform Tools & Relational Intelligence.

Installation & Distribution

SOP is designed to be accessible regardless of your preferred technology stack. There are two primary ways to get the SOP Platform Suite, which includes both the SOP Code Library and the Platform Tools (Data Manager, Script VDE, AI Copilot).

Option 1: Language Packages

Best for developers who want to integrate SOP directly into their application code. Installing the package for your language automatically includes the Data Manager (sop-httpserver) and CLI tools.

Language Installation Description
Python pip install sop4py Full Python bindings with Data Manager & AI Scripts.
Go go get github.com/sharedcode/sop The core native library for maximum performance.
C# dotnet add package Sop Complete .NET Core integration.
Java Maven/Gradle (Coming Soon) Full JVM support.
Rust cargo add sop (Coming Soon) High-performance Rust bindings.

AI Copilot Configuration

The SOP Data Manager includes an embedded AI Copilot powered by LLMs (like Google Gemini). To use the Copilot features, you must configure your API key.

Setting the API Key

You can provide the API Key via the Setup Wizard (on first launch) or the configuration file. For a detailed guide on using the conversational interface, case sensitivity rules, and query examples, please refer to the AI Copilot User Guide.

Config File Add the generator configuration to your config.json file.

{
  "generator": {
    "provider": "gemini",
    "api_key": "your-api-key-here",
    "model": "gemini-2.0-flash-exp"
  },
  "port": 8080
}

Note: The Copilot requires an active internet connection to communicate with the LLM provider.

Option 2: Standalone Binary (GitHub Releases)

Best for infrastructure administrators, DevOps, or "Data-First" users who want to set up the management console immediately. You can download the sop-httpserver executable directly from our GitHub Releases Page.

  • Universal Manager: The standalone binary acts as a central console to manage databases created by any language binding (Python, C#, Go, etc.).
  • Zero-Dependency: No language runtimes (Python/DotNet) required to run the tool itself.
  • Complete Bundle: The release archive includes not just the server binary, but also the native binaries for language bindings and essential documentation (READMEs), making it a self-contained "SOP Starter Kit".

Development Workflows: Code-First vs. Data-First

SOP supports both code-first and data-first workflows.

  • Code-first: Define stores and logic in application code, then inspect and manage them with the Data Manager.
  • Data-first: Create stores and seed data in the Data Manager, then open those stores from application code.
  • Further Reading: See Workflows Guide for the detailed workflow patterns and deployment scenarios.

SOP Data Manager & AI Suite

SOP allows you to interact with your data using the SOP Data Manager—a web-based console that includes a SQL-like query engine and an AI Copilot.

Data Manager Capabilities
  • Visual Management: Inspect B-Trees, manage Stores (Key-Value, Vector, Model), and explore the System DB.
  • Recent Progress: The HTTP server now supports signed bearer access tokens for browser and remote API clients, plus store-management fixes that preserve runtime schema metadata and reduce false structural-change validation.
  • Environment Manager: Switch between environments using portable JSON configuration files.
  • Shared Intelligence: Manage permissions and connections to share databases across the network, allowing different teams to collaborate on the same "System Knowledge" base.
Designing for AI: Relations

SOP is not just a storage engine; it is designed to be the "Long Term Memory" for AI Agents. There are two ways to model relationships so that AI Agents can intuitively navigate your data:

  1. Direct Relations (Metadata): Use this for standard One-to-Many relationships (e.g., Order.user_id -> User.id). By registering this relationship in the StoreOptions, the AI understands the detailed schema and can perform high-performance Joins automatically.
    • Pro Tip: This enables Bi-Directional Querying (Parent $\leftrightarrow$ Child) without the need for redundant "Link Stores" or double-indexing. Query "User's Orders" or "Order's User" with equal efficiency.
  2. Link Store Pattern (Advanced): Use this for Many-to-Many relationships or complex graph traversals. Create a dedicated Link Store (e.g., User_Orders) to map IDs effectively without modifying the base tables.

This structure allows AI Agents to navigate data using simple "Chain of Thought" reasoning steps (e.g., "First find the User ID, then look up their Orders") rather than struggling to generate complex SQL Joins. The SOP Data Manager provides first-class support for visualizing and debugging these relationships.

  • SQL Capabilities: Perform familiar SQL operations directly on your NoSQL B-Trees:
    • SELECT / SCAN: Filter data using rich criteria ($gt, $regex, $in).
    • JOIN: Perform high-performance connections between stores (e.g., Join 'Users' and 'Orders').
    • CRUD: Insert, Update, and Delete records via a query interface.
Storage Distribution & Redundancy

SOP separates storage responsibilities into registry/system data and user-data files.

  • Registry and system data: Configured through StoresFolders with active/passive redundancy.
  • User data files: Configured through ErasureConfigs for striping, parity, and store-level routing.
  • Further Reading: See Configuration & Tuning Guide and Operations Guide for the full storage and failover configuration model.
The System Database (SystemDB)

All SOP environments come with a built-in SystemDB. It stores platform metadata and runtime artifacts such as:

  • Scripts: Your automation workflows and compiled functions.
  • LLM Knowledge: Domain knowledge and operational guidance used by the AI runtime.
  • (Future) RBAC: Role-Based Access Control configurations for multi-user security.
Spaces & Active Memory

SOP uses Spaces as isolated semantic working sets rather than one shared monolithic vector space.

  • Domain Scope: Spaces let the runtime keep memory, retrieval, and enrichment focused on a specific domain.
  • Stateless Backend (BYOK): Credentials are supplied per request so the backend can remain stateless.
  • Further Reading: See AI Copilot & Agent Architecture and SOP AI Kit for the detailed memory and Space model.

SOP supports partitioned vector search using B-Tree-backed storage layouts that keep related vectors adjacent and allow metadata-aware scans.

For the detailed storage layout, optimization model, and vector-search tradeoffs, see SOP AI Kit, Vector Store Design, and Dynamic Vector Store Design.

Rich Key Structures (Metadata Carrier)

SOP supports complex B-Tree keys that carry metadata such as status, version, category, or routing fields.

This pattern is used across general-purpose stores and the AI/vector layers to support filtering and structural operations with minimal value reads. See Architecture Guide, SOP AI Kit, and Vector Store Design for the detailed key layouts.

AI Copilot & Scripts

The Data Manager includes an integrated AI Copilot that supports Natural Language Programming.

  • Natural Language Queries: Ask for selections, joins, and CRUD operations in plain language.
  • Script Drafting and Execution: Create, save, and run reusable workflows from the UI or command surface.
  • Hybrid Execution: Deterministic tool steps and reasoning steps can be combined in the same workflow.
  • Documentation: See AI Copilot & Agent Architecture, AI Script Architecture, and Store Orchestration Modes for runtime internals and orchestration details.

To launch the Data Manager:

# Data Manager is included in your language binding installation
sop-httpserver

Security & Enterprise Integration

SOP supports both local built-in auth and external identity-provider integration for enterprise deployments.

  • Built-in auth: the embedded HTTP server supports signed bearer access tokens, short-lived refresh renewal, and a dedicated signing secret for the hot path.
  • Enterprise directory support: the auth layer is designed to accept provider adapters for AD, Entra ID, LDAP, SAML, or OIDC without changing the core application logic.
  • Secret handling: keep SOP_SESSION_SECRET (or session_secret) in a secret manager or environment variable; do not bake signing keys into source control.
  • Remote clients: bearer tokens are suitable for CLI tools, scripts, and microservices that call the HTTP API directly over HTTPS.
  • Deployment guidance: use HTTPS in front of the HTTP server, restrict token scopes/roles, and map external identities to internal roles before granting access.

This gives IT and security teams a clear path to adopt SOP in controlled environments while keeping the runtime flexible for future provider integrations.

Reference Guides

🚀 Getting Started

Download & Installation Guide: The fastest way to get up and running with SOP.

⚡ Performance

SOP is designed for high throughput and low latency. Below are benchmark results running on a 2015 MacBook Pro (Dual-Core Intel Core i5, 8GB RAM) using the built-in benchmark tool (tools/benchmark).

Optimization Guide: Tuning SlotLength

The SlotLength parameter controls the number of items stored in each B-Tree node. Tuning this value can significantly impact performance depending on your dataset size and workload.

Configuration Used:

  • IsValueDataInNodeSegment: true (Values stored directly in leaf nodes)
  • CacheType: sop.InMemory (Persisted to disk with ACID support)
10,000 Items Benchmark

For smaller datasets, a SlotLength of 2,000 offers the best balance.

SlotLength Insert (ops/sec) Read (ops/sec) Delete (ops/sec)
1,000 107,652 136,754 40,964
2,000 132,901 142,907 50,093
3,000 135,066 137,035 49,754
4,000 123,190 122,228 48,094
5,000 132,670 126,432 47,150
100,000 Items Benchmark

For larger datasets, increasing SlotLength to 4,000 yields higher throughput.

SlotLength Insert (ops/sec) Read (ops/sec) Delete (ops/sec)
1,000 121,139 145,195 48,346
2,000 132,805 136,684 51,817
3,000 137,296 141,764 50,605
4,000 145,417 143,770 51,988
5,000 137,054 144,565 50,309

Recommendation: Start with a SlotLength of 2,000 for general use, and increase to 4,000+ for write-heavy workloads with large datasets.

Pro Tip for Massive Scale: For datasets reaching into the hundreds of billions or trillions of records, you can increase SlotLength up to 20,000. This maximizes node density, allowing a single B-Tree to manage massive amounts of data (calculated at 68% average load):

Hash Mod Value Segment Size Capacity (Key/Value Pairs)
750,000 (Max) ~3 GB 673,200,000,000 (673.2 Billion)

This enables managing petabytes of data with minimal metadata overhead. See Scalability & Limits for the full breakdown.

Why this matters

These benchmarks are running with Full ACID Transaction protection. Unlike simple Key-Value stores that optimize purely for random writes (often sacrificing order or safety), SOP provides a robust foundation for complex data access:

  • Sorted Data: Native support for ORDER BY ASC/DESC.
  • Fast Search: Efficient range scans and lookups.
  • SQL-Ready: The ordered structure supports efficient Merge Joins and complex query patterns out of the box.
  • Linear Scalability: SOP is built on SWARM (SOP exclusive) transaction technology, allowing it to scale linearly and horizontally across the network as nodes and hardware are added.
Competitive Landscape

How does SOP compare to other storage engines in the Go ecosystem?

Database Type Typical Batch Write (Ops/Sec) Key Differences
SOP B-Tree ~145,000 ACID, Ordered, SWARM Scalability
BadgerDB LSM Tree ~150,000 - 300,000 Faster writes (LSM), but requires compaction and lacks native B-Tree ordering features.
SQLite B-Tree (C) ~50,000 - 100,000 Slower due to SQL parsing overhead.
BoltDB B-Tree ~10,000 - 50,000 Slower random writes due to copy-on-write page structure.
Go map Hash Map ~10,000,000+ In-memory only. No persistence, no ACID, no ordering.

Note on SOP's Unique Value Proposition: While raw speed is comparable to top-tier engines, SOP distinguishes itself by combining features that usually don't exist together:

  • Full ACID Transactions: Guarantees safety where others might trade it for speed.
  • SWARM Technology: Unlike monolithic engines, SOP scales linearly across the network.
  • SQL-Ready Structure: Data is stored ordered, enabling ORDER BY, range scans, and efficient joins without extra indexing overhead.

Interoperability & Data Management

SOP is designed as a Universal Data Platform. Whether you are writing in Go, Python, Java, C#, or Rust, your data should be accessible, manageable, and interoperable.

1. The Universal Approach (JSONDB)

This is the standard approach used by all language bindings (Python, Java, C#, Rust) and is also available to Go developers via the jsondb package.

  • Mechanism: Data is serialized as JSON.
  • Benefit: Native Data Manager Support. Since the format is standardized, the SOP Data Manager can automatically read, write, query, and visualize your B-Trees without any extra configuration.
  • Interoperability: A B-Tree created in Python can be read by a Java app or managed by the Go-based Data Manager.
2. The Native Go Approach (Structs & Comparers)

Go developers often prefer storing native structs for maximum performance and type safety. SOP supports this fully but requires a bridge to be manageable by the generic Data Manager.

  • SOP as a Library (Code First):

    • Usage: You define custom structs and a custom comparer in Go code.
    • Pros: Maximum flexibility and performance.
    • Cons: Hidden Logic. The Data Manager cannot inherently understand your compiled sorting logic.
  • SOP as a Managed Platform (Data First):

    • Usage: You provide an IndexSpecification that describes your key fields and sorting order.
    • Pros: Full Data Manager Support. The IndexSpecification acts as the contract, allowing the UI and AI Agents to manage your data.
    • Workflow: You can use the Data Manager to create the B-Tree and define the IndexSpecification. Then, use the built-in Code Generator to generate the Go structs.
3. Spaces / Knowledge Bases (Knowledge Base Studio)

The same managed workflow extends to Spaces, which are SOP's Knowledge Base assets.

  • Author in the UI: Use the SOP Data Manager (Knowledge Base Studio) to create, curate, and refine your Spaces / Knowledge Bases without writing application code.
  • Consume in your app: Once authored, open the same Space from your Go application with the sop/ai package and use the rich KnowledgeBase API to manage, search, and digest those authored assets at runtime.
  • Best practice: Treat the Data Manager as the authoring and governance layer, and the ai package as the runtime layer that retrieves, filters, and reasons over the curated Space content inside your product.

Typical flow:

  1. Use the Data Manager to create or import a Space.
  2. Curate categories, summaries, and items in the UI.
  3. In your Go app, open the Space through ai/database / ai/memory, then use SearchKeywords or SearchSemantics to retrieve context for RAG, copilots, or domain tools.

This is how developers can keep the human-friendly authoring experience in SOP Data Manager while still embedding the resulting Knowledge Base directly into their application logic.

Bridging the Gap: From Code-First to Managed (Safe & Zero-Downtime)

SOP supports a hybrid workflow. You can start with a Code-First approach (using custom Go structs and comparers) and later make the store fully manageable by the Data Manager—without migration or downtime.

  • The Feature: Use the Data Manager's Edit Store functionality to attach an IndexSpecification or CEL expression to an existing "Code-First" store.
  • The Safety Mechanism: This operation is 100% safe but protected.
    1. Admin Unlock: For non-empty stores, these fields are locked by default. You must provide an Admin Token to unlock them, ensuring only authorized personnel can modify the schema of a live database.
    2. Metadata Only: The change only updates the Store Registry (metadata). It never touches the actual B-Tree data nodes or re-writes the data file.
    3. Non-Invasive: The underlying B-Tree structure remains identical. The Data Manager simply uses the new specification to interpret and sort the keys dynamically, matching the logic of your compiled code.
    4. Reversibility: Since the data is untouched, you can refine or remove the specification at any time.

This allows DBAs to take a "black box" store generated by application code and turn it into a transparent, queryable dataset for reporting, debugging, and AI analysis.

General Purpose & Strong Typing

SOP B-Trees are general-purpose storage engines. Similar to a Model Store, they can store "any" value type (e.g., interface{} in Go, Object in Java).

  • Dynamic Typing: You can store mixed types in the same B-Tree if your application logic supports it.
  • Strong Typing via "Seed": To enforce strong typing and enable rich Data Manager features, you should seed the B-Tree with an initial item.
    • Discovery: When you add a "seed" item (the first record), the Data Manager inspects it to discover the Key and Value types automatically.
    • Schema Enforcement: This effectively "locks in" the schema for the UI, allowing it to generate correct forms and validation rules.
    • Swarm Readiness: As noted below, this seed item also initializes the tree structure, enabling efficient "Swarm" transaction merging immediately.

See the API Cookbook for details.

SOP Data Manager

SOP includes a SOP Data Manager that provides full CRUD capabilities for B-Tree stores. It supports inspection, search, and day-to-day data management through a web UI.

  • Web UI: A modern, responsive interface for browsing B-Trees, managing stores, and visualizing data.
  • AI Copilot: Integrated directly into the UI, the AI Copilot can help you write queries (including SQL-like Joins), explain data structures, and even generate code snippets.
  • Natural Language SQL: Perform complex Selects, Joins, and CRUD operations using plain English.
  • Streaming Architecture: Results from Agents and Scripts are streamed in real-time, enabling Scripts as Views and efficient handling of large datasets with minimal memory footprint.
  • SystemDB: View and manage internal system data, including registry information and transaction logs.
  • Scripts: Record and replay complex data operations for testing or automation (now with Parameter support).

To launch the SOP Data Manager:

Development Mode (Offline / Dummy AI)

By default, the server runs in development mode. The AI Copilot and Space Management tools will use dummy/mock AI providers. This is perfect for local testing without incurring API costs.

# From the root of the repository
go run ./tools/httpserver
Production Mode (Real AI / BYOK)

To unlock the actual AI Copilot and manage Spaces (Memory Architecture), you need to start the server in Production Mode. Because SOP uses a BYOK (Bring Your Own Key) architecture, the backend remains stateless—your API keys are entered directly into the Web UI.

# From the root of the repository
go run ./tools/httpserver -production

Once running, you can enter your Embedder and LLM credentials during the Setup Wizard (Page 3), directly in the AI Chat window, or (in the future) via the Login screen.

Or use the pre-built binaries if available. See tools/httpserver/README.md for more details.

SOP AI Kit

The SOP AI Kit transforms SOP from a storage engine into a complete AI data platform.

  • Vector Store: Native support for storing and searching high-dimensional vectors.
  • RAG Agents: Build Retrieval-Augmented Generation applications with ease.
  • Scripts: A functional AI runtime for drafting and executing complex workflows.

See ai/README.md for a deep dive into the AI capabilities.

Table of contents

Swarm Computing & Concurrent Transactions

SOP supports "Swarm Computing" where multiple distributed processes or threads can concurrently modify the same B-Tree without external locks. The library handles ACID transactions, conflict detection, and merging automatically.

Important Requirement for First Commit: To enable seamless concurrent merging on a newly created B-Tree, you must pre-seed the B-Tree with at least one item in a separate, initial transaction.

  • Why? This establishes the root node and structure, preventing race conditions that can occur when multiple transactions attempt to initialize an empty tree simultaneously.
  • Bonus: As mentioned above, this seed item also allows the Data Manager to auto-discover the Key/Value types, turning your general-purpose B-Tree into a strongly-typed, manageable store.
  • Note: This requirement is simply to have at least one item in the tree. It can be a real application item or a dummy seed item.
  • Safety: Your data remains ACID-compliant. This step simply ensures the "first commit" doesn't suffer from a "random drop" race condition where one transaction's initialization overwrites another's.
  • After this single seed item is committed, the B-Tree is fully ready for high-concurrency "swarm" operations.

Cluster reboot procedure

When rebooting an entire cluster running applications that use SOP, follow this order to avoid stale locks and ensure clean recovery:

  1. Gracefully stop all apps that use SOP across the cluster.
  2. Stop the Redis service(s) used by these SOP apps.
  3. Reboot hosts if needed (or proceed directly if not).
  4. Start the Redis service(s) first and verify they are healthy.
  5. Start the apps that use SOP.

Self-Healing & Reliability

SOP includes a robust background servicer that ensures database integrity even in the face of infrastructure failures like Redis restarts.

Redis Restart Detection & Lock Resurrection

In Clustered mode (using Redis), SOP employs a minimally intrusive "on Redis restart" detector. This mechanism:

  • Detects Redis Restarts: Automatically identifies when the Redis cache has restarted or lost volatile data.
  • Resurrects Locks: If a transaction was incomplete during a Redis failure, the system automatically "resurrects" the necessary locks for the transaction's priority logs.
  • Prevents Corruption: This ensures that the registry sector does not become corrupted due to half-complete transactions.
  • Self-Healing: The background servicer automatically handles this lifecycle maintenance, keeping the database "rock solid" without manual intervention.

Note: This feature is specific to Clustered mode. In Standalone mode, the application performs a similar cleanup sweep immediately upon startup.

Notes:

  • SOP relies on Redis for coordination (locks, recovery bookkeeping). Bringing Redis up before SOP apps prevents unnecessary failovers or stale-lock handling during app startup.
  • If any node was force-killed, SOP’s stale-lock and rollback paths will repair on next write; starting Redis first ensures that path has the needed state.

Introduction

What is SOP?

Scalable Objects Persistence (SOP) is a bare metal storage engine that bakes together a set of storage related features & algorithms in order to provide the most efficient & reliable (ACID attributes of transactions) technique (known) of storage management and rich search. It brings to the application the raw muscle of "raw storage" via direct I/O communications with disk drives, bypassing the overhead of intermediate database layers.

SOP V2 core is written in Go, but provides first-class bindings for Python, Java, C#, and Rust, making it a truly universal storage solution. It can be used for storage management by applications of many types across different hardware architectures & Operating Systems (OS).

Polyglot Support

SOP is designed as a "Write Once, Run Anywhere" architecture. The core engine is compiled into a shared library (libsop.so/.dylib/.dll) which is then consumed by language-specific bindings. This ensures that all languages benefit from the same high-performance, ACID-compliant core.

For a deep dive into our multi-language architecture, see Polyglot Support.

Supported Languages
  • Go: The native core. Best for high-concurrency backend services.
  • Python (sop4py): Ideal for AI/ML, RAG applications, and data science.
  • Java (sop4j): Perfect for enterprise backends and legacy modernization.
  • C# (sop4cs): Native integration for .NET Core and Windows environments.
  • Rust (sop4rs): For systems programming and high-performance applications.

Scalability & Limits

SOP is architected to handle Petabyte-scale datasets and Trillions of objects.

  • Capacity: Up to 495 Billion items per segment (with 1,000 segments = 495 Trillion items) per Btree.
  • Throughput: Limited only by hardware (Redis Cluster + Storage I/O), not software.
  • Design: Horizontal scaling via independent storage nodes and sharded registry.

See the full analysis in Scalability & Limits.

Key Use Cases

SOP is designed to be versatile, powering everything from small embedded tools to massive enterprise clusters.

For detailed architectural patterns, deployment lifecycles, and configuration examples, see Workflows & Scenarios.

1. Standalone App (Embedded DB)
  • Scenario: Desktop apps, CLI tools, or single-node services needing rich indexing.
  • Why SOP:
    • Bare Metal Performance: Direct B-Tree indexing on disk with minimal abstraction overhead.
    • Speed: "NoCheck" transaction mode. For build-once-read-many scenarios, skip conflict checks entirely for raw, unbridled read speed.
    • Simplicity: No external database dependencies (just a local file structure).
2. Enterprise Cluster App
  • Scenario: Distributed systems requiring high availability and ACID guarantees.
  • Why SOP:
    • ACID Transactions: Two-Phase Commit (2PC) across distributed nodes.
    • Multi-Tenancy: Native support for multi-tenancy (via Directories or Keyspaces) allows multiple tenants to share the same cluster while maintaining strict data isolation.
    • Scalability: Infinite metadata scaling via Sharded Registry (FileSystem) or Cassandra tables.
    • Resilience: Registry replication (Active/Passive or Quorum) and Erasure Coding for data blobs ensure zero data loss.
    • Operational Flexibility: Choose the backend that fits your ops stack:
      • FileSystem (infs): The most versatile option. Run on Local Disk for embedded/dev use, or mount a Network Drive (NAS/S3) for infinite cluster scalability. Requires only a shared mount and Redis. It also offers stronger all-or-nothing guarantees than incfs, thanks to the Registry-on-File-System design.
      • Cassandra (incfs): "Power up" your existing Cassandra cluster with SOP. Adds full ACID Transactions, B-Tree Indexing (ordered data, range queries), and efficient large item management to Cassandra's eventual consistency model. In practice, Cassandra can still exhibit rare dual-success races on batched commits, so the filesystem-backed Registry path is the safer choice when strict atomicity matters.
3. AI Vector Database
  • Scenario: Storing and retrieving millions of vector embeddings for RAG (Retrieval-Augmented Generation) applications.
  • Why SOP:
    • Transactional & ACID: Unlike eventual-consistency vector stores, SOP provides full ACID compliance for vector operations, ensuring no data loss or "ghost" vectors.
    • Novel Storage Schema: Uses a composite key strategy (CentroidID + DistanceToCentroid) to map high-dimensional vectors onto standard B-Trees, enabling efficient range scans and transactional integrity.
    • Ideal Random Sampling: Uses a novel "Lookup Tree" indexing algorithm to generate mathematically representative centroids, ensuring high-quality clustering even on sorted or skewed datasets.
    • Self-Healing Index: Automatically optimizes clusters and tracks distribution in real-time, maintaining optimal search speeds as data grows to terabytes.
    • Flexible Deployment: Run in Standalone mode (zero dependencies, in-memory cache) or Clustered mode (Redis-backed cache for distributed scale).
4. AI Agent with Local LLM (Ollama)
  • Scenario: Privacy-focused or cost-sensitive AI agents that need to "understand" user input before searching.
  • Why SOP:
    • Embedder Agent Pattern: SOP supports a dual-agent architecture where a specialized "Nurse" agent (powered by a local LLM like Llama 3 via Ollama) translates vague user queries (e.g., "my tummy hurts") into precise clinical terms (e.g., "abdominal pain") before the main "Doctor" agent searches the vector database.
    • Zero Cost: Run the entire stack (Vector DB + LLM + Application) on a single machine without any API fees.
    • Factory Reset Kit: SOP's "Fallback Config" pattern allows you to ship a self-contained "restore disk" (JSON with raw data) that automatically rebuilds the binary B-Tree database if it's ever corrupted or deleted.
5. Blob Store (Media & Large Files)
  • Scenario: Storing and streaming massive files like 4K video, high-fidelity audio, or large datasets (1TB+).
  • Why SOP:
    • Streaming Data Store: SOP's StreamingDataStore breaks large values into manageable chunks (e.g., 20MB) automatically.
    • Partial Updates: You can update specific chunks of a large file (e.g., editing a video segment) without rewriting the entire file.
    • ACID Transactions: Even for multi-gigabyte files, SOP guarantees transactional integrity. You can upload or update massive blobs in a transaction; if it fails, it rolls back cleanly.
    • Smart Resume: Built-in support for seeking to specific chunks allows for "resume download" or "seek to timestamp" functionality out of the box.
6. AI Model Registry
  • Scenario: Managing versions of local AI models (weights, configurations) alongside the data they process.
  • Why SOP:
    • Unified Storage: Store your training data (Vectors), metadata (Registry), and model artifacts (Blobs/JSON) in one ACID-compliant system.
    • Atomic Updates: Update your model weights and the vector index they correspond to in a single transaction, preventing version mismatch.
    • Versioning: Built-in support for versioning models (e.g., "v1.0", "v1.1") using composite keys.
7. Cassandra Power-Up (Layer 2 Database)
  • Scenario: Enhancing existing Cassandra clusters with features it natively lacks.
  • Why SOP:
    • Solves the "Blob Problem": Keeps Cassandra lean by storing only metadata (Registry) in tables, while offloading heavy data (B-Tree nodes, values) to the file system or object storage. This prevents compaction issues common with large blobs.
    • Rich Indexing: Adds full B-Tree capabilities (range queries, prefix search, ordering) which are natively missing or limited in Cassandra.
    • ACID Transactions: Provides strict ACID transactions (Two-Phase Commit) on top of Cassandra's eventually consistent architecture.
    • Multi-Tenancy: Native support for Keyspaces allows logical separation of data within the same cluster.
8. Embedded Search Engine
  • Scenario: Adding "Search this wiki" or "Filter by text" features to an application without managing a separate Elasticsearch cluster.
  • Why SOP:
    • Transactional Indexing: Index documents in the same transaction as you save them. No "eventual consistency" lag.
    • BM25 Scoring: Uses industry-standard ranking algorithms for relevance.
    • Zero Ops: It's just a library. No separate process to manage or monitor.

Core Innovations

SOP breaks the mold of traditional database architectures by combining the speed of embedded systems with the scalability of distributed clusters.

1. The Unified Native Core ("Write Once, Run Everywhere")

Unlike many databases that rely on slow TCP/IP protocols for local drivers, SOP runs inside your application process.

  • Architecture: The core engine is written in Go and compiled into a high-performance Shared Library (.so / .dll).
  • Language Agnostic: Whether you use Python, C#, or Java, your application loads this engine directly into memory using FFI.
  • Zero Latency: Function calls (e.g., db.Get()) are direct memory operations, not network requests. This allows for millions of operations per second on a single node.
2. Swarm Computing Architecture

SOP is not just a storage engine; it is a coordination framework.

  • Distributed State: Nodes in a cluster don't just store data; they share System Knowledge.
  • Virtual Execution: The "OS" of the swarm allows you to run distributed workflows where logic moves to the data, rather than moving data to the logic.
  • Linear Scalability: Add more nodes to increase both storage capacity (Storage Nodes) and processing power (Compute Nodes) linearly.
3. Rich Key Structures (Metadata-Carrying Keys)

Standard Key-Value stores treat keys as opaque strings. SOP treats them as First-Class Objects.

  • Complex Keys: You can use complex structs (e.g., {Region, Dept, EmployeeID}) as keys.
  • "Ride-on" Data: Critical metadata (like Version, Deleted flags, or CentroidID for vectors) is physically stored in the B-Tree Key node.
    • Performance: Operations like "List all non-deleted items" scan only the lightweight index, avoiding the expensive I/O of fetching the full data payload.
    • Consistency: This metadata serves as the source of truth for ACID transactions.
4. Hybrid AI Compute & Scripting (Self-Correcting)

SOP combines an AI-facing scripting engine with explicit execution controls.

  • Deterministic Workflows: Multi-step reasoning can be captured as reusable scripts after validation.
  • Memory and Repair: Runtime memory and repair patterns support iterative correction across asks.
  • Operational Safety: Tool execution remains local and constrained by the application runtime.
  • Further Reading: See AI Copilot & Agent Architecture and AI Script Architecture for the full runtime model.
5. Granular Durability & RAID

Moving beyond simple replication, SOP brings hardware-level reliability concepts into software.

  • Erasure Coding: Split large objects (Blobs) across multiple physical drives or network locations with parity, ensuring data survival even if multiple drives fail.
  • Store-Level RAID: You can configure redundancy policies per-store. Your "Logs" store can be ephemeral (fast, low safety), while your "Financials" store uses Reed-Solomon Erasure Coding (maximum safety) on the same cluster.

For a deeper dive into the system's design and package structure (including the Public vs. Internal split), please see the Architecture Guide.

For configuration options and performance tuning, see the Configuration Guide.

For operational best practices (failover, backups), see the Operational Guide.

For code examples, check out the API Cookbook.

See Summary for additional implementation notes and storage-engine details.

The Database Abstraction

SOP provides a high-level database package that simplifies configuration and management of your storage artifacts.

  • Unified Entry Point: Manage B-Trees, Vector Stores, and Model Registries from a single Database instance.
  • Deployment Modes:
    • Standalone: Uses in-memory caching and local storage. Ideal for single-node apps or development.
    • Clustered: Uses Redis for distributed caching and coordination. Ideal for production clusters.
  • Simplified Transactions: db.BeginTransaction handles the complexity of configuring caching and replication for you.

Quick start

SOP is a NoSQL-like key/value storage engine with built-in indexing and transactions. You only need Go to start (Redis is optional for distributed setups).

  1. Plan your environment
  • Ensure sufficient disk capacity for your datasets. SOP stores on local filesystems and can replicate across drives.
  1. Prerequisites
  • Go 1.26.4 or later (module requires go 1.26.4)
  • (Optional) Redis (recent version) - required only for distributed/cluster mode or if using Redis-backed caching. Note: Redis is NOT used for data storage, just for coordination & to offer built-in caching.
  1. Install and run Redis (Optional)
  • If using distributed features, install Redis locally or point to your cluster.
  1. Add SOP to your Go app
  • Import package:
    • github.com/sharedcode/sop/database (Recommended: Unified entry point for B-Trees, Vector Stores, and AI Models)
    • github.com/sharedcode/sop/ai (AI Toolkit: Vector Database, Agents, and RAG)
    • github.com/sharedcode/sop/infs (Low-level: Direct access to filesystem-backed B-Trees)
  • Repo path: https://github.com/sharedcode/sop
  1. Initialize and start coding
  • Use the database package to initialize your environment.
    // Initialize (Standalone or Clustered)
    opts := sop.DatabaseOptions{
        Type:          sop.Standalone,
        StoresFolders: []string{"/var/lib/sop"},
    }
    
    // Start a Transaction
    tx, _ := database.BeginTransaction(ctx, opts, sop.ForWriting)
    
    // Open a Store (B-Tree, Vector, or Model)
    users, _ := database.NewBtree[string, string](ctx, opts, "users", tx, nil)
    
    // Perform Operations
    users.Add(ctx, "user1", "John Doe")
    
    // Commit
    tx.Commit(ctx)
    
  1. Deploy
  • Ship your app and SOP along your usual release flow (binary or container). If you expose SOP via a microservice, choose REST/gRPC as needed.
  1. Permissions
  • Ensure the process user has RW permissions on the target data directories/drives. SOP uses DirectIO and filesystem APIs with 4096-byte sector alignment.

Tip: Using Python? See “SOP for Python” below.

Lifecycle: failures, failover, reinstate, EC auto-repair

SOP is designed to keep your app online through common storage failures.

  • Blob store with EC: B-tree nodes and large blobs are stored using Erasure Coding (EC). Up to the configured parity, reads/writes continue even when some drives are offline. When failures exceed parity, writes roll back (no failover is generated) and reads may require recovery.
  • Registry and StoreRepository: These metadata files use Active/Passive replication. Only I/O errors on Registry/StoreRepository can generate a failover. On a failover, SOP flips to the passive path and continues. When you restore the failed drive, reinstate it as the passive side; SOP will fast‑forward any missing deltas and return it to rotation.
  • Auto‑repair: With EC repair enabled, after replacing a failed blob drive, SOP reconstructs missing shards automatically and restores full redundancy in the background.

See the detailed lifecycle guide (failures, observability, reinstate/fast‑forward, and drive replacement) in GO_CORE_ENGINE.md: https://github.com/SharedCode/sop/blob/master/docs/GO_CORE_ENGINE.md#lifecycle-failures-failover-reinstate-and-ec-auto-repair

Also see Operational caveats: https://github.com/SharedCode/sop/blob/master/docs/GO_CORE_ENGINE.md#operational-caveats

For planned maintenance, see Cluster reboot procedure: Cluster reboot procedure.

Transaction idle maintenance (onIdle) & priority rollback sweeps

Each write or read transaction opportunistically invokes an internal onIdle() path at the start (Begin()). This lightweight pass performs two independent maintenance tasks:

  1. Priority rollback sweeps (Lock Resurrection): Resurrects lost locks for interrupted higher-priority transactions by consulting per‑transaction priority log (.plg) files. This allows transactions to "self-heal" by enabling stale detection and rollback as necessary.

    • Cluster-wide coordination: This task is coordinated across the entire cluster (or all threads in standalone mode). Only one worker "wins" and performs the sweep at any given time, ensuring no redundant processing. This prevents unnecessary "swarm overload" on these onIdle services.
    • Restart fast path: On application start (in embedded mode), SOP triggers a one‑time sweep of all priority logs immediately, ignoring age. This accelerates recovery of any half‑committed writes that were waiting for the periodic window. In Clustered mode, a global coordinator ensures that only one process in the entire cluster pings the Redis 'notrestarted' flag and performs the actual lock resurrection service if needed.
    • Periodic path: Absent a restart, one worker periodically processes aged logs. Base interval is 5 minutes. If the previous sweep found work, a shorter 2 minute backoff is used to drain backlog faster. Intervals are governed by two atomically updated globals: lastPriorityOnIdleTime (Unix ms) and priorityLogFound (0/1 flag).
    • Rule: Priority logs older than 5 minutes are considered "abandoned" and are rolled back by this servicer.
    • Concurrency: A mutex plus atomic timestamp prevents overlapping sweeps; only one goroutine performs a rollback batch at a time even under high Begin() concurrency.
    • Rationale: Using onIdle piggybacks maintenance on natural transaction flow without a dedicated background goroutine, simplifying embedding into host applications that manage their own scheduling.
  2. Expired transaction log cleanup: Removes obsolete commit/rollback artifacts (B-Tree node pages and data value pages).

    • Cluster-wide coordination: Like priority sweeps, this task is coordinated cluster-wide. Only one worker wins the right to perform the cleanup for a given interval (regular or accelerated).
    • Intervals:
      • 4 Hours (Default): B-Tree nodes and data pages modified in a transaction are temporary until the commit updates the Registry. Since the Registry is the source of truth for ACID transactions, cleaning up these temporary artifacts can be done at a "luxury of time" pace (4 hours) without affecting data integrity.
      • 5 Minutes (Accelerated): If recent activity suggests potential pending cleanup (e.g., known rollbacks), the interval accelerates to 5 minutes to reclaim space faster.
    • Timing uses an atomic lastOnIdleRunTime.

Thread safety: Earlier versions used unsynchronized globals; these now use atomic loads/stores (sync/atomic) to eliminate race detector warnings when tests force timer rewinds. Tests that manipulate timing (to speed up sweep scenarios) reset the atomic counters instead of writing plain globals.

Operational impact: You generally do not need to call anything explicitly—just ensure transactions continue to flow. If you embed SOP in a service that may become read‑only idle for long stretches but you still want prompt rollback of higher‑priority interruptions, periodically issue a lightweight read transaction to trigger onIdle.

Testing notes: Unit tests rewind lastPriorityOnIdleTime and priorityLogFound (atomically) to force immediate sweep execution; this pattern is acceptable only in test code. Production code should never reset these values manually.

Prerequisites

  • Go 1.26.4+
  • OS: macOS, Linux, or Windows.
    • Architectures: x64 (AMD64/Intel64) and ARM64 (Apple Silicon/Linux aarch64).
  • (Optional) Redis server (local or cluster) - for distributed coordination
  • Data directories on disks you intend SOP to use (4096-byte sector size recommended)

Running Integration Tests

You can run the SOP's integration tests from "infs" package using the following docker commands: NOTE: you need docker desktop running in your host machine for this to work. Go to the sop root folder, e.g. cd ~/sop, where sop is the folder where you cloned from github.

  1. Build the docker image: docker build -t mydi .
  2. Run the docker image in a container: docker run mydi
  • Where "mydi" is the name of the docker image, you can use another name of your choice.

The docker image will be built with alpine (linux) and Redis server in it. Copy the SOP source codes to it. Setup target data folder and environment variable that tells the unit tests of the data folder path. On docker run, the shell script ensures that the Redis server is up & running then run the ("infs" package's integration) test files.

You can pattern how the test sets the (datapath) env't variable so you can run the same integration tests in your host machine, if needed, and yes, you need Redis running locally for this to work. See https://github.com/SharedCode/sop/blob/master/Dockerfile and https://github.com/SharedCode/sop/blob/master/docker-entrypoint.sh for more details.

If you’re using VS Code, there are ready-made tasks:

  • Docker: Build and Test — builds image mydi
  • Docker: Run Tests — runs tests in the container

Testing (unit, integration, stress)

Run tests locally without Docker using build tags:

  • Unit tests (fast): go test ./...
  • Integration tests (require Redis running on localhost and a writable data folder):
    • Set environment variable datapath to your data directory (defaults to a local path if unset).
    • Run: go test -tags=integration ./infs/integrationtests
  • Stress tests (long-running): go test -timeout 2h -tags=stress ./infs/stresstests/...

VS Code tasks provided:

  • Go: Test (Unit)
  • Go: Test (Integration)
  • Go: Test (Stress)
  • Go: Test (Unit + Integration) runs both in sequence

CI note: GitHub Actions runs unit tests on pushes/PRs; a nightly/manual job runs the stress suite with -tags=stress.

Usability

See details here: https://github.com/sharedcode/sop/blob/master/docs/GO_CORE_ENGINE.md#usability

SOP API Discussions

See details here: https://github.com/sharedcode/sop/blob/master/docs/GO_CORE_ENGINE.md#simple-usage

SOP for Python (sop4py)

See details here: https://github.com/sharedcode/sop/tree/master/jsondb/python#readme Check out the [Python Cookbook](jsondb/python/COOKBOOK.md) for code recipes.

SOP for AI Kit

SOP includes a comprehensive AI toolkit for building local, privacy-first expert systems. - **AI Documentation**: [ai/README.md](ai/README.md) - Overview of the AI module, Vector Store, and Agent framework. - **AI Tutorial**: [ai/TUTORIAL.md](ai/TUTORIAL.md) - Step-by-step guide to building the "Doctor & Nurse" expert system.

Timeouts and deadlines

SOP commits are governed by two bounds:

  • The caller context (deadline/cancellation)
  • The transaction maxTime (commit max duration)

The commit ends when the earlier of these two is reached. Internal lock TTLs use maxTime to ensure locks are bounded even if the caller cancels early.

Recommendation: If you want replication/log cleanup to complete under the same budget, set your context deadline to at least maxTime plus a small grace period.

Reliability & Integrity

SOP implements a "Rock Solid" storage strategy ensuring data integrity and consistency across failures.

Checksums (CRC32)

Every data block written to disk is protected by a CRC32 checksum.

  • Implementation: fs/marshaldata.go
  • Mechanism: The marshalData function appends a crc32.ChecksumIEEE to every block. unmarshalData validates this checksum on read, returning an error if data corruption (bit rot) is detected.
  • Zero-Copy Optimization: Sparse (all-zero) blocks are optimized to skip checksum calculation while maintaining validity.
Rollbacks (COW & Priority Logs)

SOP uses a robust rollback mechanism to recover from crashes or power failures during a transaction.

  • Implementation: fs/hashmap.cow.go
  • Copy-On-Write (COW): Before modifying a registry sector, SOP creates a .cow backup file (createCow). If a crash occurs, the next accessor detects the COW file, verifies its integrity (using the embedded CRC32), and restores the original state (restoreFromCow).
  • Priority Logs: Transaction logs (.plg) track in-flight transactions. The onIdle maintenance process scans these logs to identify and roll back abandoned or expired transactions, ensuring the system returns to a consistent state.
Unified Locking (Cross-Platform)

SOP employs a "Redis-assisted, Storage-anchored" locking model that works consistently across operating systems (Linux, Windows, macOS).

  • Storage Anchors: Exclusive access to storage sectors is enforced via claim markers on the disk itself, using standard filesystem APIs with 4096-byte sector alignment (DirectIO). This ensures that even if Redis (the coordination layer) is lost, the physical data remains protected by the filesystem's atomic guarantees.
  • Redis Coordination: Redis is used for high-speed, ephemeral locking to reduce contention.
  • Cross-Platform Consistency: By relying on standard file I/O and sector alignment rather than OS-specific locking primitives (like flock vs LockFile), SOP guarantees identical locking behavior on all supported platforms.

Coordination model (OOA) and safety

Coordination model: Redis-assisted, storage-anchored

SOP uses Redis for fast, ephemeral coordination and the filesystem for durable sector claims. Redis locks provide low-latency contention detection; per-sector claim markers on storage enforce exclusive access for CUD operations. This hybrid keeps coordination responsive without coupling correctness to Redis durability.

Why this is safe (despite Redis tail loss/failover)
  • Locks are advisory; correctness is anchored in storage-sector claims and idempotent commit/rollback.
  • On Redis restart, SOP detects it and performs cleanup sweeps (clearing stale sector claims) before resuming.
  • Time-bounded lock TTLs, takeover checks, and rollback paths ensure progress without split-brain.
  • Priority logs and deterministic rollback let workers resume or repair safely after interruptions.
Operational properties
  • Decentralized: no leader or quorum; any node can coordinate on a sector independently.
  • Horizontally scalable: sharded by registry sectors; no global hot spots.
  • No single point of failure: loss of Redis state slows coordination briefly but doesn't corrupt data.
  • Low latency: lock checks and claim writes are O(1) on hot path; no multi-round consensus.
When Redis is unavailable
  • Writes that need exclusivity will wait/fail fast; storage remains consistent.
  • On recovery, restart sweeps clear stale sector claims; workers resume.
Comparison to Paxos-style consensus
  • SOP avoids global consensus, leader election, and replicated logs—lower coordination latency and cost.
  • Better horizontal scaling for partitioned workloads (per-sector independence).
  • No SPOF in the coordination layer; failover is trivial and stateless.
  • If you need a globally ordered, cross-region commit log, consensus is still the right tool; SOP targets high-throughput, partition-aligned coordination. But then again, SOP is not a coordination engine, it is a storage engine. Its internal piece for coordination, e.g. - of handle (virtual ID) Registry, is what was described here.
TL;DR

SOP builds a fast, decentralized coordination layer using Redis only for ephemeral locks and relies on storage-anchored sector claims for correctness. It scales out naturally and avoids consensus overhead while remaining safe under failover.

Clustered Mode Compatibility

In Clustered Mode, SOP uses Redis to coordinate transactions across multiple nodes. This allows many machines to participate in data management for the same Database/B-Tree files on disk while maintaining ACID guarantees.

Note: The database files generated in Standalone and Clustered modes are fully compatible. You can switch between modes as needed but make sure if switching to Standalone mode, that there is only one process that writes to the database files.

Community & support

Contributing & license

  • Contributing guide: see CONTRIBUTING.md
  • Code of Conduct: see CODE_OF_CONDUCT.md
  • License: MIT, see LICENSE

Documentation

Overview

Package sop defines the core interfaces, types, and helpers used across the SOP codebase. It provides transactions, store options and metadata, key/handle abstractions, and shared error codes. Concrete backends live in subpackages such as fs (filesystem), cassandra, and redis, while higher-level features include B-Trees and streaming data helpers. It is designed to be extensible and modular, allowing for various storage backends to be implemented while sharing a common interface. This package is intended for internal use within the SOP project and is not meant for external use. It is a foundational package that other components build upon. It is not intended to be used directly by end-users, but rather serves as a base for more specific implementations and utilities in the SOP ecosystem. It is a foundational package that other components build upon. It is not intended to be used directly by end-users, but rather serves as a base for more specific implementations and utilities in the SOP ecosystem.

See `infs.package` for a concrete implementation of a File System-based store with built-in Redis caching.

Package sop contains SOP integration code for Redis, Cassandra & Kafka (in_red_c).

Index

Constants

View Source
const (
	// Unknown represents an unspecified error condition.
	Unknown ErrorCode = iota
	// LockAcquisitionFailure indicates failure to acquire a required lock.
	LockAcquisitionFailure
	// FileIOError represents file I/O related errors, e.g. encountered by BlobStore (w/ & w/o EC).
	// This should not generate Failover event because BlobStore errors are either handled internally for no EC
	// or by EC replication feature.
	FileIOError
	// FailoverQualifiedError marks an error that qualifies the operation for failover handling.
	FailoverQualifiedError = 77 + iota
	// FileIOErrorFailoverQualified represents file I/O related errors.
	FileIOErrorFailoverQualified
	// RestoreRegistryFileSectorFailure indicates a failure while restoring a registry file sector.
	RestoreRegistryFileSectorFailure
)
View Source
const (
	RoleAdmin = "Admin"
	RoleUser  = "User"
	RoleGuest = "Guest"
)
View Source
const ContextPriorityLogIgnoreAge contextKey = "plg_ignore_age"

ContextPriorityLogIgnoreAge signals priority log GetBatch to ignore age filter when true.

View Source
const (
	// HandleSizeInBytes is the size, in bytes, of a Handle structure when encoded.
	HandleSizeInBytes = 62
)

Variables

View Source
var (
	ErrSystemReadOnly = errors.New("system knowledge bases are read-only")
	ErrQuotaExceeded  = errors.New("quota exceeded")
	ErrUnauthorized   = errors.New("unauthorized access")
)
View Source
var Now = time.Now

Now returns the current time. It is a var to allow tests to override time.Now for determinism.

View Source
var RetryStartDuration = 1 * time.Second

RetryStartDuration is the initial duration for the Fibonacci backoff. It is exported to allow tests to reduce the wait time.

View Source
var Version = strings.TrimSpace(versionFile)

Version is the current version of the SOP library/application.

Functions

func Authorize

func Authorize(ctx context.Context, access ResourceAccess, action Action) bool

func CanPerformAction

func CanPerformAction(ctx context.Context, resourceName string, access ResourceAccess, action Action) bool

CanPerformAction checks if the current context has permission to perform the action on the resource. It returns a boolean, making it ideal for UI visibility toggles like IsReadOnly.

func CheckPolicy

func CheckPolicy(ctx context.Context, resourceName string, access ResourceAccess, action Action) error

CheckPolicy evaluates the three-layer RBAC model and returns an error if access is denied. It is useful when you need to know exactly *why* access was denied.

func ConfigureLogging

func ConfigureLogging()

ConfigureLogging sets up the global default logger with a TextHandler and configures the log level based on the SOP_LOG_LEVEL environment variable. It defaults to Info level if not specified.

This function should be called by the application at startup if it wants to use the default SOP logging configuration.

func ContextWithAuth

func ContextWithAuth(ctx context.Context, auth AuthContext) context.Context

func EnforcePolicy

func EnforcePolicy(ctx context.Context, resourceName string, access ResourceAccess, action Action) error

EnforcePolicy checks the policy and returns an error if the action is not allowed. Use CanPerformAction for a boolean result (e.g. for adjusting UI states).

func FlattenForSchema

func FlattenForSchema(key any, value any) map[string]any

FlattenForSchema converts key and value of any type into a flat map[string]any suitable for schema inference. Uses JSON marshaling to handle structs. NOTE: InferSchemaFromTypes is preferred when type information is available.

func FormatRegistryTable

func FormatRegistryTable(name string) string

FormatRegistryTable formats a store name into a registry table name by adding an _r suffix.

func FormatSchema

func FormatSchema(schema map[string]string) string

FormatSchema formats a schema map as a sorted string like "{field: type, ...}".

func GetAllBlueprints

func GetAllBlueprints() map[string]AssetBlueprint

GetAllBlueprints returns a cloned map of the system-wide blueprints

func HandleLockAcquisitionFailure

func HandleLockAcquisitionFailure(ctx context.Context, err error,
	rollbackFunc func(context.Context, UUID) error,
	unlockFunc func(context.Context, []*LockKey) error) error

HandleLockAcquisitionFailure checks if the error is a LockAcquisitionFailure and if so, attempts to rollback the blocking transaction using the provided rollbackFunc. If rollback succeeds, it takes over the lock and releases it using unlockFunc. Returns nil if the failure was handled (lock taken over and released), otherwise returns the original error.

func InferSchema

func InferSchema(item map[string]any) map[string]string

InferSchema inspects a map and returns a simplified type definition (e.g. {"id": "uuid", "age": "number"}).

func InferSchemaType

func InferSchemaType(v any) string

InferSchemaType returns a string representation of the type of a value for schema inference.

func InferType

func InferType(v any) (string, bool)

InferType returns the simplified type name (e.g. "string", "int", "uuid") and whether it's an array. This is used for UI display and loose type checking.

func IsFailoverQualifiedIOError

func IsFailoverQualifiedIOError(err error) bool

IsFailoverQualifiedIOError reports whether an error indicates the active drive/filesystem is unhealthy in a way that warrants immediate failover to the passive drive.

This is distinct from ShouldRetry: retryable/transient errors should be retried first, while this function targets permanent/media/FS/device conditions where staying on the current drive is counterproductive.

Notes:

  • It includes common POSIX errno values available on macOS/Linux/BSD.
  • For Linux-specific errno that may not exist on other platforms as named constants, numeric values are used via syscall.Errno to remain portable (they will simply never match on platforms that don't produce them).
  • EFBIG is intentionally excluded per current SOP usage (registry/store repo use small files).

func IsSystemReadOnly

func IsSystemReadOnly(resourceName string) bool

IsSystemReadOnly returns true if the specified resource is a core system resource that must remain read-only to prevent destructive actions by any user.

func RandomSleep

func RandomSleep(ctx context.Context)

RandomSleep sleeps for a random duration between 20ms and 80ms to stagger retries.

func RandomSleepWithUnit

func RandomSleepWithUnit(ctx context.Context, unit time.Duration)

RandomSleepWithUnit sleeps for a random multiple (1..4) of the provided unit duration. Useful to jitter conflicting transactions and reduce contention.

func RegisterAssetRBAC

func RegisterAssetRBAC(blueprint AssetBlueprint)

RegisterAssetRBAC ensures that new Assets declare their UI footprint and execution logic cleanly

func RegisterL2CacheFactory

func RegisterL2CacheFactory(ct L2CacheType, f L2CacheFactory)

RegisterL2CacheFactory registers a cache factory for a given type.

func Retry

func Retry(ctx context.Context, task func(ctx context.Context) error, gaveUpTask func(ctx context.Context)) error

Retry executes task with Fibonacci backoff up to 5 retries. If retries are exhausted, gaveUpTask is invoked (when not nil) and the final error is returned.

func SetDefaultCacheConfig

func SetDefaultCacheConfig(cacheDuration StoreCacheConfig)

SetDefaultCacheConfig assigns the global default cache configuration used when a store does not override it.

func SetJitterRNG

func SetJitterRNG(r *rand.Rand)

SetJitterRNG overrides the RNG used for sleep jitter. Useful for deterministic tests.

func SetLogLevel

func SetLogLevel(level slog.Level)

SetLogLevel sets the logging level for the logger configured by ConfigureLogging.

func ShouldRetry

func ShouldRetry(err error) bool

ShouldRetry reports whether the error is retryable (non-nil and not a known permanent failure).

func Sleep

func Sleep(ctx context.Context, sleepTime time.Duration)

Sleep blocks for the specified duration or until the context is done, whichever happens first.

func TimedOut

func TimedOut(ctx context.Context, name string, startTime time.Time, maxTime time.Duration) error

TimedOut returns an error if the context is done or if the elapsed time since startTime exceeds maxTime.

Types

type Action

type Action string
const (
	ActionRead     Action = "read"
	ActionWrite    Action = "write"
	ActionDelete   Action = "delete"
	ActionList     Action = "list"
	ActionAISelect Action = "ai_select"
)

type AssetBlueprint

type AssetBlueprint struct {
	AssetType   string   // e.g., "space", "store", "agent"
	Description string   // Human-readable context
	Endpoints   []string // UI API endpoints related to this asset
	Actions     []Action // Capabilities: Read, Write, Delete, Execute

	// Evaluator executes the actual permission check for a specific asset instance or context
	Evaluator func(ctx context.Context, entitlementCtx EntitlementContext, action Action) bool
}

AssetBlueprint defines the RBAC footprint for a specific module or asset type.

func GetAssetBlueprint

func GetAssetBlueprint(assetType string) (AssetBlueprint, bool)

GetAssetBlueprint looks up the evaluator instructions by alias

type AuthContext

type AuthContext struct {
	UserID   string
	Roles    []string
	IsSystem bool
}

func GetAuthFromContext

func GetAuthFromContext(ctx context.Context) AuthContext

type BlobStore

type BlobStore interface {
	// GetOne fetches a blob by ID from a blob table.
	GetOne(ctx context.Context, blobTable string, blobID UUID) ([]byte, error)
	// Add inserts blobs.
	Add(ctx context.Context, blobs []BlobsPayload[KeyValuePair[UUID, []byte]]) error
	// Update modifies existing blobs.
	Update(ctx context.Context, blobs []BlobsPayload[KeyValuePair[UUID, []byte]]) error
	// Remove deletes blobs by ID.
	Remove(ctx context.Context, blobsIDs []BlobsPayload[UUID]) error
}

BlobStore defines CRUD operations for binary blobs that are too large for typical databases and are stored in external systems (e.g., S3, filesystem, Cassandra partitions).

type BlobsPayload

type BlobsPayload[T UUID | KeyValuePair[UUID, []byte]] struct {
	// BlobTable is the blob store table name (or base filesystem path).
	BlobTable string
	// Blobs holds either IDs (for deletes) or ID+data pairs (for upserts).
	Blobs []T
}

BlobsPayload is a request/response envelope for blob operations.

type BundledResponse

type BundledResponse struct {
	Data     interface{}               `json:"data"`
	RBAC     ContextRBACMap            `json:"rbac,omitempty"`
	ItemRBAC map[string]ContextRBACMap `json:"item_rbac,omitempty"`
}

BundledResponse represents the standard JSON payload structure containing both the domain data and the paired RBAC map.

type CloseableCache

type CloseableCache interface {
	L2Cache
	io.Closer
}

CloseableCache is a Cache that also implements io.Closer for explicit lifecycle control.

type ContextRBACMap

type ContextRBACMap map[UICapability]bool

ContextRBACMap represents the UI-consumable map format representing capabilities for a given context: (Capability -> bool)

func ResolveRBACMap

func ResolveRBACMap(ctx context.Context, assetType string, entitlementCtx EntitlementContext, getLocalAccess func() ResourceAccess) ContextRBACMap

ResolveRBACMap evaluates the dynamic AssetBlueprint for a functional context (e.g., current space/store), delegating to the core evaluator.

type DatabaseOptions

type DatabaseOptions struct {
	// StoresFolders specifies the folders for replication.
	// If more than one folder, i.e. - one for Active drive/folder,
	// & another for Passive drive/folder, Registry replication is enabled.
	StoresFolders []string `json:"stores_folders,omitempty"`
	// ErasureConfig specifies the erasure coding configuration for Blob store replication.
	ErasureConfig map[string]ErasureCodingConfig `json:"erasure_config,omitempty"`
	// Keyspace to be used for the transaction (Cassandra).
	Keyspace string `json:"keyspace,omitempty"`
	// CacheType specifies the type of cache to use (e.g. InMemory, Redis).
	CacheType L2CacheType `json:"cache_type"`
	// RedisConfig specifies the Redis configuration when CacheType is Redis.
	RedisConfig *RedisCacheConfig `json:"redis_config,omitempty"`
	// Registry hash modulo value used for hashing.
	RegistryHashModValue int `json:"registry_hash_mod,omitempty"`

	// Type specifies the database type (Standalone or Clustered).
	// This is a convenience field that sets the default CacheType.
	Type DatabaseType `json:"type"`

	// EnableObfuscation specifies if this database should be obfuscated when accessed by AI tools.
	// This is a runtime-only field and is not persisted to JSON.
	EnableObfuscation bool `json:"-"`
}

DatabaseOptions holds the configuration for the database.

func (DatabaseOptions) CopyTo

func (do DatabaseOptions) CopyTo(transOptions *TransactionOptions)

Copy Database Options to Transaction Options.

func (DatabaseOptions) GetDatabaseType

func (do DatabaseOptions) GetDatabaseType() DatabaseType

func (DatabaseOptions) IsCassandraHybrid

func (do DatabaseOptions) IsCassandraHybrid() bool

func (DatabaseOptions) IsEmpty

func (do DatabaseOptions) IsEmpty() bool

IsEmpty returns true if database config is considered empty, i.e. - missing folder is primary. A Database should always have folder(s) where Registry data files are/will be stored.

func (DatabaseOptions) IsReplicated

func (do DatabaseOptions) IsReplicated() bool

func (*DatabaseOptions) SetDatabaseType

func (do *DatabaseOptions) SetDatabaseType(t DatabaseType)

type DatabaseType

type DatabaseType int
const (
	// Standalone mode uses an in-memory cache for coordination (locks, etc.).
	// It is appropriate for standalone or embedded applications running in a single process.
	Standalone DatabaseType = iota
	// Clustered mode uses Redis for coordination (locks, etc.).
	// It allows hosting multiple application instances across a network, properly orchestrated by SOP.
	Clustered
)

type EndpointContext

type EndpointContext string

EndpointContext represents an API endpoint representing a grouping of assets.

const (
	EndpointSpacesList EndpointContext = "/api/spaces"
	EndpointStoresList EndpointContext = "/api/stores"
	EndpointItemsList  EndpointContext = "/api/spaces/items"
)

type EntitlementContext

type EntitlementContext struct {
	AssetID    string
	Database   string
	IsSystemDB bool
	UserRole   string
	UserID     string
}

EntitlementContext holds the request scope parameters necessary for granular RBAC evaluation.

type ErasureCodingConfig

type ErasureCodingConfig struct {
	// DataShardsCount is the number of data shards.
	DataShardsCount int `json:"data_shards_count"`
	// ParityShardsCount is the number of parity shards.
	ParityShardsCount int `json:"parity_shards_count"`
	// BaseFolderPathsAcrossDrives lists the drive base paths where data and parity shard files are stored.
	BaseFolderPathsAcrossDrives []string `json:"base_folder_paths_across_drives"`

	// RepairCorruptedShards indicates whether to attempt automatic repair when corrupted shards are detected.
	// Auto-repair can be expensive; applications can disable it to prioritize throughput and handle drive
	// failures via external workflows.
	RepairCorruptedShards bool `json:"repair_corrupted_shards"`
}

ErasureCodingConfig defines per-blob-table erasure coding settings, including shard counts, storage locations, and optional automatic shard repair.

type ErrTimeout

type ErrTimeout struct {
	// Name is a short label for the operation (e.g., "transaction", "lockFileBlockRegion").
	Name string
	// MaxTime is the maximum duration allowed for the operation when applicable.
	MaxTime time.Duration
	// Cause is the underlying timeout/cancellation cause, typically a context error.
	Cause error
}

ErrTimeout is returned when an operation exceeds its allowed time budget.

Semantics:

  • If a context cancellation or deadline triggered the timeout, Cause carries the original context error (context.Canceled or context.DeadlineExceeded). Unwrap() returns that Cause so errors.Is(err, context.DeadlineExceeded) works.
  • If the operation-specific maximum duration triggered the timeout, Cause may be nil; MaxTime contains the configured bound for the operation.

This enables callers to branch on timeouts consistently while preserving the original context semantics when applicable.

func (ErrTimeout) Error

func (e ErrTimeout) Error() string

func (ErrTimeout) Unwrap

func (e ErrTimeout) Unwrap() error

Unwrap exposes the underlying cause (e.g., context.DeadlineExceeded) for errors.Is/As.

type Error

type Error struct {
	Code     ErrorCode
	Err      error
	UserData any
}

Error is a SOP-specific error carrying a code, the wrapped error and optional user data.

func (Error) Error

func (e Error) Error() string

Error implements the error interface by formatting the code, user data, and wrapped error details.

type ErrorCode

type ErrorCode int

ErrorCode enumerates SOP error categories used across packages.

type Handle

type Handle struct {
	// LogicalID is the stable identifier of the entity.
	LogicalID UUID
	// PhysicalIDA is one of the two physical IDs supported.
	PhysicalIDA UUID
	// PhysicalIDB is the second physical ID supported.
	PhysicalIDB UUID
	// IsActiveIDB indicates whether PhysicalIDB is currently the active ID.
	IsActiveIDB bool
	// Version is the current state version (active ID, final deleted state).
	Version int32
	// WorkInProgressTimestamp stores the millisecond timestamp of the inactive ID (or non-final deleted state).
	WorkInProgressTimestamp int64
	// IsDeleted marks a logical delete.
	IsDeleted bool
}

Handle holds a logical ID and its two physical IDs (A and B) used to implement ACID-safe swaps. SOP uses Handle to quickly switch between node versions and to support logical deletes.

func NewHandle

func NewHandle(id UUID) Handle

NewHandle creates a new Handle with the provided logical ID. PhysicalIDA is initialized to the same value.

func (*Handle) AllocateID

func (h *Handle) AllocateID() UUID

AllocateID generates a new UUID and assigns it to the available physical slot. If both A and B are already in use, NilUUID is returned.

func (*Handle) ClearInactiveID

func (h *Handle) ClearInactiveID()

ClearInactiveID resets the inactive physical ID to NilUUID and clears the WIP timestamp.

func (*Handle) FlipActiveID

func (h *Handle) FlipActiveID()

FlipActiveID switches the active physical ID from A to B or B to A.

func (Handle) GetActiveID

func (h Handle) GetActiveID() UUID

GetActiveID returns the currently active UUID (either PhysicalIDA or PhysicalIDB).

func (Handle) GetInActiveID

func (h Handle) GetInActiveID() UUID

GetInActiveID returns the currently inactive physical UUID.

func (*Handle) HasID

func (h *Handle) HasID(id UUID) bool

HasID reports whether the provided UUID matches either physical ID A or B.

func (Handle) IsAandBinUse

func (h Handle) IsAandBinUse() bool

IsAandBinUse reports whether both physical IDs A and B are populated.

func (*Handle) IsEmpty

func (x *Handle) IsEmpty() bool

IsEmpty reports whether all Handle fields are zero values (no IDs, not deleted, zero version and timestamps).

func (*Handle) IsEqual

func (x *Handle) IsEqual(y *Handle) bool

IsEqual reports whether two Handle instances are equal ignoring the Version field.

func (*Handle) IsExpiredInactive

func (h *Handle) IsExpiredInactive() bool

IsExpiredInactive reports whether the inactive ID has expired based on a fixed window.

type KeyValuePair

type KeyValuePair[TK any, TV any | []byte] struct {
	// Key is the key part in the pair.
	Key TK
	// Value is the value part in the pair.
	Value TV
}

KeyValuePair represents a pair of key and value, commonly used for blob operations where the key may differ from the blob ID.

type KeyValueStore

type KeyValueStore[TK any, TV any] interface {
	// Fetch retrieves entries by keys from the remote storage subsystem.
	Fetch(context.Context, string, []TK) KeyValueStoreResponse[KeyValuePair[TK, TV]]
	// FetchLargeObject retrieves a single large entry by key.
	FetchLargeObject(context.Context, string, TK) (TV, error)
	// Add inserts entries.
	Add(context.Context, string, []KeyValuePair[TK, TV]) KeyValueStoreResponse[KeyValuePair[TK, TV]]
	// Update modifies existing entries.
	Update(context.Context, string, []KeyValuePair[TK, TV]) KeyValueStoreResponse[KeyValuePair[TK, TV]]
	// Remove deletes entries by keys.
	Remove(context.Context, string, []TK) KeyValueStoreResponse[TK]
}

KeyValueStore defines CRUD operations for a generic key-value backend with optional partial success semantics.

type KeyValueStoreItemActionResponse

type KeyValueStoreItemActionResponse[T any] struct {
	Payload T
	Error   error
}

KeyValueStoreItemActionResponse is the per-item response including payload and error for a CRUD action.

type KeyValueStoreResponse

type KeyValueStoreResponse[T any] struct {
	// Details contains per-item action results.
	Details []KeyValueStoreItemActionResponse[T]
	// Error is a summary error if at least one action failed.
	Error error
}

KeyValueStoreResponse aggregates per-item results and an optional summary error.

type L2Cache

type L2Cache interface {
	// Inherit Locking interface.
	Locker

	// Implement to return the CacheType.
	GetType() L2CacheType

	// Set upserts a value under a key, and specifies when it will expire or disappear from L2 cache.
	Set(ctx context.Context, key string, value string, expiration time.Duration) error
	// Get returns: found(bool), value(string), err(error from backend).
	Get(ctx context.Context, key string) (bool, string, error)
	// GetEx returns found(bool), value(string), err using TTL/sliding expiration semantics.
	GetEx(ctx context.Context, key string, expiration time.Duration) (bool, string, error)

	// IsRestarted reports whether the cache backend (e.g., Redis) has restarted since the last check.
	// Implementations should return true once per backend restart event per-process and false otherwise.
	IsRestarted(ctx context.Context) bool

	// SetStruct upserts a struct value under a key.
	SetStruct(ctx context.Context, key string, value interface{}, expiration time.Duration) error
	// SetStructs upserts multiple struct values under the given keys in a single round trip (pipelined).
	SetStructs(ctx context.Context, keys []string, values []interface{}, expiration time.Duration) error
	// GetStruct fetches a struct value; first return indicates success (false for not found or error).
	GetStruct(ctx context.Context, key string, target interface{}) (bool, error)
	// GetStructEx fetches a struct value with TTL/sliding expiration semantics.
	GetStructEx(ctx context.Context, key string, target interface{}, expiration time.Duration) (bool, error)
	// GetStructs fetches multiple struct values with optional TTL/sliding expiration semantics.
	// If expiration > 0, it behaves like GetStructEx for each key (pipelined).
	// If expiration <= 0, it behaves like GetStruct but batched (e.g. MGET).
	GetStructs(ctx context.Context, keys []string, targets []interface{}, expiration time.Duration) ([]bool, error)
	// Delete removes objects by keys; returns whether all keys were deleted.
	Delete(ctx context.Context, keys []string) (bool, error)
	// Ping checks connectivity to the cache backend.
	Ping(ctx context.Context) error

	// Clear purges the entire cache database.
	Clear(ctx context.Context) error
}

L2Cache abstracts an out-of-process cache (e.g., Redis) and its locking facilities.

func GetL2Cache

func GetL2Cache(options TransactionOptions) L2Cache

GetL2Cache gets the cache (client) for the specified type. It returns nil if no factory is registered for that type.

type L2CacheFactory

type L2CacheFactory func(TransactionOptions) L2Cache

L2CacheFactory defines the function signature for creating a cache client.

type L2CacheType

type L2CacheType int

L2CacheType defines the type of cache to use.

const (
	// Default represents no (L2) caching.
	NoCache L2CacheType = iota
	// InMemory represents an in-memory cache.
	InMemory
	// Redis represents a Redis cache.
	Redis
)

type LockKey

type LockKey struct {
	Key         string
	LockID      UUID
	IsLockOwner bool
}

LockKey represents a lockable cache key along with ownership metadata.

type Locker

type Locker interface {
	// FormatLockKey creates a lock key name from an arbitrary string.
	FormatLockKey(k string) string
	// CreateLockKeys builds LockKey objects from a set of key names.
	CreateLockKeys(keys []string) []*LockKey
	// CreateLockKeysForIDs builds LockKey objects for ID tuples (e.g., Transaction ID scoped locks).
	CreateLockKeysForIDs(keys []Tuple[string, UUID]) []*LockKey

	// IsLockedTTL reports whether all keys are locked and refreshes TTL with the provided duration.
	IsLockedTTL(ctx context.Context, duration time.Duration, lockKeys []*LockKey) (bool, error)

	// Lock attempts to lock all keys; returns success, lock owner UUID, and any error encountered.
	Lock(ctx context.Context, duration time.Duration, lockKeys []*LockKey) (bool, UUID, error)
	// DualLock attempts to lock all keys; returns success, lock owner UUID, and any error encountered.
	// It calls Lock then IsLocked to ensure the lock is acquired and persisted.
	DualLock(ctx context.Context, duration time.Duration, lockKeys []*LockKey) (bool, UUID, error)
	// IsLocked reports whether all keys are currently locked.
	IsLocked(ctx context.Context, lockKeys []*LockKey) (bool, error)
	// IsLockedByOthers reports whether the keys are locked by other processes.
	IsLockedByOthers(ctx context.Context, lockKeyNames []string) (bool, error)
	// IsLockedByOthersTTL reports whether the keys are locked by other processes and refreshes TTL with the provided duration.
	IsLockedByOthersTTL(ctx context.Context, lockKeyNames []string, duration time.Duration) (bool, error)
	// Unlock releases a set of keys.
	Unlock(ctx context.Context, lockKeys []*LockKey) error
}

Locker defines lightweight lock management facade.

type ManageStore

type ManageStore interface {
	// CreateStore creates the store(s) container (e.g., a filesystem folder).
	CreateStore(context.Context, string) error
	// RemoveStore removes the store(s) container (e.g., a filesystem folder).
	RemoveStore(context.Context, string) error
}

ManageStore declares lifecycle operations for creating and removing store containers (e.g., folders).

type RedisCacheConfig

type RedisCacheConfig struct {
	// Address is the host:port of the Redis server/cluster.
	Address string `json:"address"`
	// Password is the password used to authenticate.
	Password string `json:"password"`
	// DB is the database index to select.
	DB int `json:"db"`
	// URL is the connection string (e.g. redis://user:pass@host:port/db).
	// If provided, it overrides Address, Password, and DB.
	URL string `json:"url,omitempty"`
	// DialTimeout specifies the timeout for connecting to Redis.
	DialTimeout time.Duration `json:"dial_timeout,omitempty"`
	// ReadTimeout specifies the timeout for reading from Redis.
	ReadTimeout time.Duration `json:"read_timeout,omitempty"`
	// WriteTimeout specifies the timeout for writing to Redis.
	WriteTimeout time.Duration `json:"write_timeout,omitempty"`
	// MaxRetries is the maximum number of retries before giving up on Redis connection.
	MaxRetries int `json:"max_retries,omitempty"`
}

RedisCacheConfig holds configuration for connecting to a Redis server or cluster.

type Registry

type Registry interface {
	// Get fetches Handles (given logical IDs) from registry table(s).
	Get(context.Context, []RegistryPayload[UUID]) ([]RegistryPayload[Handle], error)
	// Add inserts Handles into registry table(s).
	Add(context.Context, []RegistryPayload[Handle]) error
	// Update modifies Handles across registry table(s) and acquires cache locks for each Handle.
	Update(ctx context.Context, handles []RegistryPayload[Handle]) error
	// UpdateNoLocks updates Handles in an active transaction where locks were pre-acquired by the transaction manager.
	UpdateNoLocks(ctx context.Context, allOrNothing bool, storesHandles []RegistryPayload[Handle]) error
	// Remove deletes Handles (given logical IDs) from registry table(s).
	Remove(context.Context, []RegistryPayload[UUID]) error

	// Replicate performs post-commit replication of blobs/data to passive targets.
	Replicate(ctx context.Context, newRootNodesHandles, addedNodesHandles, updatedNodesHandles, removedNodesHandles []RegistryPayload[Handle]) error
}

Registry provides CRUD and replication operations for virtual ID management that back SOP's ACID workflow. All methods accept and/or return batches.

type RegistryPayload

type RegistryPayload[T Handle | UUID] struct {
	// RegistryTable is the table (or namespace) where the virtual IDs are stored or fetched.
	RegistryTable string

	// BlobTable is the paired blob table (or base filesystem path) used during Rollback and Commit.
	BlobTable string
	// CacheDuration specifies Redis cache duration.
	CacheDuration time.Duration
	// IsCacheTTL enables Redis TTL (sliding expiration) semantics when true.
	IsCacheTTL bool

	// IDs contains the virtual IDs (or Handles) to manage.
	IDs []T
}

RegistryPayload represents a request/response payload to manage or fetch Handles/UUIDs in a registry table. T can be either Handle (for writes) or UUID (for reads/deletes).

func ExtractLogicalIDs

func ExtractLogicalIDs(storeHandles []RegistryPayload[Handle]) []RegistryPayload[UUID]

ExtractLogicalIDs converts a slice of RegistryPayload[Handle] to RegistryPayload[UUID] by mapping LogicalID.

type Relation

type Relation struct {
	SourceFields []string `json:"source_fields"`
	TargetStore  string   `json:"target_store"`
	TargetFields []string `json:"target_fields"`
}

Relation describes a foreign key relationship to another store.

type ResourceAccess

type ResourceAccess struct {
	Visibility Visibility          `json:"visibility"`
	OwnerID    string              `json:"owner_id,omitempty"`
	Roles      map[string][]string `json:"roles,omitempty"`
	Users      map[string][]string `json:"users,omitempty"`
}

type SchemaInferenceResult

type SchemaInferenceResult struct {
	// Flat schema without prefixes for LLM correlation with Relations
	Schema map[string]string
	// Fields that belong to the Key
	KeyFields []string
	// Fields that belong to the Value
	ValueFields []string
}

SchemaInferenceResult contains flat schema with field lists for LLM understanding.

func InferSchemaFromTypes

func InferSchemaFromTypes(key any, value any) SchemaInferenceResult

InferSchemaFromTypes uses reflection to directly inspect the types of key and value. Returns flat schema format without prefixes for better LLM understanding and correlation with Relations.

type SinglePhaseTransaction

type SinglePhaseTransaction struct {
	SopPhaseCommitTransaction TwoPhaseCommitTransaction
	// contains filtered or unexported fields
}

SinglePhaseTransaction wraps a TwoPhaseCommitTransaction providing an end-user friendly API and optional participation of other two-phase commit transactions.

func (*SinglePhaseTransaction) AddPhasedTransaction

func (t *SinglePhaseTransaction) AddPhasedTransaction(otherTransaction ...TwoPhaseCommitTransaction)

AddPhasedTransaction registers additional two-phase commit participants.

func (*SinglePhaseTransaction) Begin

Begin starts the wrapped transaction and any registered participants.

func (*SinglePhaseTransaction) Close

func (t *SinglePhaseTransaction) Close() error

Close calls Close on the wrapped transaction implementation.

func (*SinglePhaseTransaction) Commit

Commit executes phase 1 on all participants and then phase 2; on error, Rollback is invoked.

func (*SinglePhaseTransaction) CommitMaxDuration

func (t *SinglePhaseTransaction) CommitMaxDuration() time.Duration

CommitMaxDuration returns the configured commit duration cap from the underlying implementation.

func (*SinglePhaseTransaction) GetID

func (t *SinglePhaseTransaction) GetID() UUID

GetID returns the transaction ID.

func (*SinglePhaseTransaction) GetMode

GetMode returns the transaction mode.

func (*SinglePhaseTransaction) GetPhasedTransaction

func (t *SinglePhaseTransaction) GetPhasedTransaction() TwoPhaseCommitTransaction

GetPhasedTransaction returns the wrapped two-phase commit transaction.

func (*SinglePhaseTransaction) GetStores

func (t *SinglePhaseTransaction) GetStores(ctx context.Context) ([]string, error)

GetStores delegates to the wrapped transaction to list available stores.

func (*SinglePhaseTransaction) HasBegun

func (t *SinglePhaseTransaction) HasBegun() bool

HasBegun reports whether the transaction has started.

func (*SinglePhaseTransaction) OnCommit

func (t *SinglePhaseTransaction) OnCommit(callback func(ctx context.Context) error)

OnCommit registers a callback to be executed after a successful commit.

func (*SinglePhaseTransaction) Rollback

func (t *SinglePhaseTransaction) Rollback(ctx context.Context) error

Rollback aborts the transaction and attempts to rollback all participants, returning the last error if any.

type StoreCacheConfig

type StoreCacheConfig struct {
	// RegistryCacheDuration controls caching for registry objects.
	RegistryCacheDuration time.Duration `json:"registry_cache_duration"`
	// IsRegistryCacheTTL enables sliding TTL for registry cache.
	IsRegistryCacheTTL bool `json:"is_registry_cache_ttl"`
	// NodeCacheDuration controls caching for nodes.
	NodeCacheDuration time.Duration `json:"node_cache_duration"`
	// IsNodeCacheTTL enables sliding TTL for node cache.
	IsNodeCacheTTL bool `json:"is_node_cache_ttl"`
	// ValueDataCacheDuration controls caching for the item Value part when globally cached.
	ValueDataCacheDuration time.Duration `json:"value_data_cache_duration"`
	// IsValueDataCacheTTL enables sliding TTL for value data cache.
	IsValueDataCacheTTL bool `json:"is_value_data_cache_ttl"`
	// StoreInfoCacheDuration controls caching for StoreInfo records.
	StoreInfoCacheDuration time.Duration `json:"store_info_cache_duration"`
	// IsStoreInfoCacheTTL enables sliding TTL for store info cache.
	IsStoreInfoCacheTTL bool `json:"is_store_info_cache_ttl"`
}

StoreCacheConfig declares cache durations and TTL flags for store artifacts.

func GetDefaultCacheConfig

func GetDefaultCacheConfig() StoreCacheConfig

GetDefaultCacheConfig returns the global default cache configuration.

func NewStoreCacheConfig

func NewStoreCacheConfig(cacheDuration time.Duration, isCacheTTL bool) *StoreCacheConfig

NewStoreCacheConfig returns a StoreCacheConfig with uniform cache durations and TTL settings applied. If cacheDuration is between 1ns and 5 minutes, it will be clamped to 5 minutes. TTL is disabled when duration is zero.

type StoreInfo

type StoreInfo struct {
	// Name is the short store name.
	Name string `json:"name" minLength:"1" maxLength:"128"`
	// SlotLength is the number of items per node.
	SlotLength int `json:"slot_length" min:"2" max:"20000"`
	// IsUnique enforces uniqueness on the key of key/value items.
	IsUnique bool `json:"is_unique"`
	// Description optionally describes the store.
	Description string `json:"description" maxLength:"1000"`
	// RegistryTable is the registry table name.
	RegistryTable string `json:"registry_table" minLength:"1" maxLength:"140"`
	// BlobTable defines the target Erasure Coding (EC) configuration to use.
	// The Database Options contain an EC configuration map keyed by a name, and
	// this field's value is used to look up a match. If no matching entry is found,
	// it falls back to the default EC config (which uses an empty string key "").
	BlobTable string `json:"blob_table" minLength:"1" maxLength:"300"`
	// RootNodeID is the root B-Tree node identifier.
	RootNodeID UUID `json:"root_node_id"`
	// Count is the total number of items persisted.
	Count int64 `json:"count"`
	// CountDelta is used internally to reconcile Count updates; it should not be persisted.
	CountDelta int64 `json:"-"`
	// Timestamp is the add/update time in milliseconds.
	Timestamp int64 `json:"timestamp"`
	// IsValueDataInNodeSegment stores the Value within the node segment when true.
	IsValueDataInNodeSegment bool `json:"is_value_data_in_node_segment"`
	// IsValueDataActivelyPersisted persists Value separately on Add/Update when true.
	IsValueDataActivelyPersisted bool `json:"is_value_data_actively_persisted"`
	// IsValueDataGloballyCached enables Redis caching of Value data when true.
	IsValueDataGloballyCached bool `json:"is_value_data_globally_cached"`
	// LeafLoadBalancing enables distribution to sibling nodes when capacity allows.
	LeafLoadBalancing bool `json:"leaf_load_balancing"`
	// CacheConfig overrides global cache settings per store.
	CacheConfig StoreCacheConfig `json:"cache_config"`

	// MapKeyIndexSpecification contains a CEL or index specification used by the comparer.
	MapKeyIndexSpecification string `json:"mapkey_index_spec"`

	// CELexpression specifies the CEL expression used as comparer for keys.
	CELexpression string `json:"cel_expression,omitempty"`

	// IsPrimitiveKey hints the Python binding which JSON B-Tree to instantiate on open.
	// This is an internal feature and only needed to be managed by code when using (dynamic typed) languages like Python.
	IsPrimitiveKey bool `json:"is_primitive_key"`

	// Relations describes foreign key relationships to other stores.
	Relations []Relation `json:"relations,omitempty"`

	// Schema stores field types without prefixes for LLM correlation with Relations.
	// Format: {"key": "string", "first_name": "string", "age": "number"}
	Schema map[string]string `json:"schema,omitempty"`

	// KeyFields lists the field names that are part of the Key.
	// Example: ["key"] for primitive keys, ["id", "timestamp"] for composite keys
	KeyFields []string `json:"key_fields,omitempty"`

	// ValueFields lists the field names that are part of the Value.
	// Example: ["first_name", "age", "email"] for the value object
	ValueFields []string `json:"value_fields,omitempty"`

	// CustomData stores optional arbitrary configuration for the store.
	// It is intentionally flexible for integration-specific extensions.
	CustomData map[string]any `json:"custom_data,omitempty"`

	// For internal use only. Code can use this as hint.
	NeedsMetaDataSave bool `json:"-"`

	// Version allows versioning of the store info payload for future upgrades.
	Version string `json:"version,omitempty"`
}

StoreInfo describes a B-Tree store configuration and runtime state persisted in the backend.

func NewStoreInfo

func NewStoreInfo(si StoreOptions) *StoreInfo

NewStoreInfo creates and normalizes a StoreInfo based on StoreOptions, applying default naming and cache policy.

func (*StoreInfo) DeleteCustomData

func (si *StoreInfo) DeleteCustomData(key string) bool

DeleteCustomData removes a value for the given key from CustomData.

func (*StoreInfo) GetCustomData

func (si *StoreInfo) GetCustomData(key string) (any, bool)

GetCustomData returns the value for the given key from CustomData.

func (*StoreInfo) GetCustomDataMap

func (si *StoreInfo) GetCustomDataMap() map[string]any

GetCustomDataMap returns a copy of the CustomData map.

func (StoreInfo) IsCompatible

func (s StoreInfo) IsCompatible(b StoreInfo) bool

IsCompatible reports whether two StoreInfo configurations are compatible for merge/attach semantics.

func (StoreInfo) IsEmpty

func (s StoreInfo) IsEmpty() bool

IsEmpty reports whether the StoreInfo has zero values; an empty StoreInfo means the B-Tree does not yet exist.

func (*StoreInfo) SetCustomData

func (si *StoreInfo) SetCustomData(key string, value any)

SetCustomData stores a value under the given key in CustomData.

func (*StoreInfo) SetCustomDataMap

func (si *StoreInfo) SetCustomDataMap(data map[string]any)

SetCustomDataMap replaces the full CustomData map with a copy.

func (*StoreInfo) ValueDataSize

func (si *StoreInfo) ValueDataSize() ValueDataSize

Interpolates back into ValueDataSize

type StoreOptions

type StoreOptions struct {
	// Name is the short name of the store.
	Name string
	// SlotLength is the number of items that can be stored in a node.
	SlotLength int
	// IsUnique enforces uniqueness on keys.
	IsUnique bool
	// IsValueDataInNodeSegment stores Value data within the B-Tree node segment when true.
	// Smaller Value data benefits from this for locality; bigger data should be stored separately.
	// If true, IsValueDataActivelyPersisted and IsValueDataGloballyCached are ignored.
	IsValueDataInNodeSegment bool
	// IsValueDataActivelyPersisted persists Value data to a separate partition on Add/Update and expects
	// IsValueDataInNodeSegment to be false.
	IsValueDataActivelyPersisted bool
	// IsValueDataGloballyCached enables Redis caching for Value data when IsValueDataInNodeSegment is false.
	IsValueDataGloballyCached bool
	// LeafLoadBalancing allows distributing items to sibling nodes when there is capacity to avoid splits.
	LeafLoadBalancing bool
	// Description is an optional text describing the store.
	Description string
	// BlobStoreBaseFolderPath specifies a base folder path when using the filesystem blob store.
	BlobStoreBaseFolderPath string
	// DisableBlobStoreFormatting uses the store name directly as the blob store name (useful for S3-like systems).
	DisableBlobStoreFormatting bool
	// DisableRegistryStoreFormatting uses the store name directly as the registry store name.
	DisableRegistryStoreFormatting bool
	// CacheConfig overrides global cache durations and TTL behavior per store.
	CacheConfig *StoreCacheConfig

	// CELexpression specifies the CEL expression used as comparer for keys.
	CELexpression string
	// MapKeyIndexSpecification contains a CEL or index specification used by the comparer.
	MapKeyIndexSpecification string
	// IsPrimitiveKey hints Python bindings which JSON B-Tree type to instantiate during Open.
	IsPrimitiveKey bool
	// Relations describes foreign key-like relationships.
	Relations []Relation
	// CustomData stores optional arbitrary configuration for the store.
	CustomData map[string]any
}

StoreOptions contains configuration fields used when creating a B-Tree store.

func ConfigureStore

func ConfigureStore(storeName string, uniqueKey bool, slotLength int, description string, valueDataSize ValueDataSize, blobStoreBaseFolderPath string) StoreOptions

ConfigureStore returns StoreOptions tuned according to the expected ValueDataSize. Choose carefully: mismatched size can hurt performance by over/under caching or persisting. blobStoreBaseFolderPath is used only for filesystem blob storage as a base directory.

type StoreRepository

type StoreRepository interface {
	// Get retrieves store info by name(s).
	Get(context.Context, ...string) ([]StoreInfo, error)
	// GetWithTTL retrieves store info using TTL/sliding cache semantics.
	GetWithTTL(context.Context, bool, time.Duration, ...string) ([]StoreInfo, error)
	// GetAll lists all store names available in the backend.
	GetAll(context.Context) ([]string, error)
	// Add creates new store info entries and related tables (registry/blob).
	Add(context.Context, ...StoreInfo) error
	// Remove deletes store info by name and drops related tables.
	Remove(context.Context, ...string) error

	// Update modifies store info and reconciles Count using CountDelta.
	Update(context.Context, []StoreInfo) ([]StoreInfo, error)
	// Replicate performs post-commit replication of updated data managed by the repository.
	Replicate(context.Context, []StoreInfo) error
}

StoreRepository specifies CRUD and replication methods for StoreInfo records.

type TaskRunner

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

TaskRunner is a thin wrapper around errgroup.Group that carries a context for convenience. Consider using errgroup directly in new code.

func NewTaskRunner

func NewTaskRunner(ctx context.Context, maxThreadCount int) *TaskRunner

NewTaskRunner creates a new TaskRunner. maxThreadCount > 0 limits the number of concurrent goroutines.

func (*TaskRunner) GetContext

func (tr *TaskRunner) GetContext() context.Context

GetContext returns the TaskRunner's context.

func (*TaskRunner) Go

func (tr *TaskRunner) Go(task func() error)

Go runs the provided task function in a new goroutine managed by the underlying errgroup.

func (*TaskRunner) Wait

func (tr *TaskRunner) Wait() error

Wait waits for all launched tasks to complete and returns the first encountered error, if any.

type Transaction

type Transaction interface {
	// Begin starts the transaction.
	Begin(ctx context.Context) error
	// Commit finalizes the transaction.
	Commit(ctx context.Context) error
	// Rollback aborts the transaction.
	Rollback(ctx context.Context) error
	// HasBegun reports whether the transaction has started.
	HasBegun() bool

	// GetPhasedTransaction returns the underlying two-phase commit transaction for orchestration with other systems.
	GetPhasedTransaction() TwoPhaseCommitTransaction
	// AddPhasedTransaction registers external two-phase commit participants.
	AddPhasedTransaction(otherTransaction ...TwoPhaseCommitTransaction)

	// GetStores lists all available B-Tree stores from the backend.
	GetStores(ctx context.Context) ([]string, error)

	// Close releases any resources associated with the transaction.
	Close() error

	// GetID returns the transaction ID.
	GetID() UUID

	// CommitMaxDuration returns the configured maximum duration for commit operations.
	// Effective runtime limit is min(ctx deadline, CommitMaxDuration()).
	CommitMaxDuration() time.Duration

	// OnCommit registers a callback to be executed after a successful commit.
	OnCommit(callback func(ctx context.Context) error)
}

Transaction defines end-user-facing transactional operations.

func NewTransaction

func NewTransaction(mode TransactionMode,
	twoPhaseCommitTrans TwoPhaseCommitTransaction) (Transaction, error)

NewTransaction constructs a Transaction wrapper around a TwoPhaseCommitTransaction. mode controls permissions. When logging is true, lower layers may record commit steps to aid recovery and cleanup of expired resources.

type TransactionLog

type TransactionLog interface {
	// PriorityLog returns the priority logger implementation.
	PriorityLog() TransactionPriorityLog
	// Add appends a transaction log entry.
	Add(ctx context.Context, tid UUID, commitFunction int, payload []byte) error
	// Remove deletes all logs for a transaction.
	Remove(ctx context.Context, tid UUID) error

	// GetOne returns the oldest hour bucket (older than 1 hour) and its logs for cleanup distribution.
	GetOne(ctx context.Context) (UUID, string, []KeyValuePair[int, []byte], error)

	// GetOneOfHour returns the available cleanup logs for a specific hour bucket.
	GetOneOfHour(ctx context.Context, hour string) (UUID, []KeyValuePair[int, []byte], error)

	// NewUUID generates a UUID suitable for the logging backend (e.g., time-based in Cassandra).
	NewUUID() UUID
}

TransactionLog persists transaction steps and provides job-distribution accessors for cleanup tasks.

type TransactionMode

type TransactionMode int

TransactionMode enumerates the supported transaction behaviors.

const (
	// NoCheck disallows any changes and skips read-version checks during commit.
	NoCheck TransactionMode = iota
	// ForWriting allows modifications to B-Tree stores within the transaction.
	ForWriting
	// ForReading disallows modifications; read-only.
	ForReading
)

type TransactionOptions

type TransactionOptions struct {
	// StoresFolders specifies the folders for replication.
	StoresFolders []string `json:"stores_folders,omitempty"`
	// ErasureConfig specifies the erasure coding configuration for replication.
	ErasureConfig map[string]ErasureCodingConfig `json:"erasure_config,omitempty"`
	// Keyspace to be used for the transaction (Cassandra).
	Keyspace string `json:"keyspace,omitempty"`
	// CacheType specifies the type of cache to use (e.g. InMemory, Redis).
	CacheType L2CacheType `json:"cache_type"`
	// RedisConfig specifies the Redis configuration when CacheType is Redis.
	RedisConfig *RedisCacheConfig `json:"redis_config,omitempty"`
	// Registry hash modulo value used for hashing.
	RegistryHashModValue int `json:"registry_hash_mod,omitempty"`

	// Transaction Mode can be Read-only or Read-Write.
	Mode TransactionMode `json:"mode"`
	// Transaction maximum "commit" time. Acts as the commit window cap and lock TTL.
	MaxTime time.Duration `json:"max_time"`
}

func (TransactionOptions) GetDatabaseOptions

func (to TransactionOptions) GetDatabaseOptions() DatabaseOptions

GetDatabaseOptions returns the DatabaseOptions subset from TransactionOptions.

func (TransactionOptions) IsCassandraHybrid

func (to TransactionOptions) IsCassandraHybrid() bool

func (TransactionOptions) IsReplicated

func (to TransactionOptions) IsReplicated() bool

type TransactionPriorityLog

type TransactionPriorityLog interface {
	// IsEnabled reports whether priority logging is enabled.
	IsEnabled() bool
	// Add appends a priority log for a transaction.
	Add(ctx context.Context, tid UUID, payload []byte) error
	// Remove deletes priority log file of a transaction.
	Remove(ctx context.Context, tid UUID) error
	// Get retrieves priority log details for a transaction.
	Get(ctx context.Context, tid UUID) ([]RegistryPayload[Handle], error)

	// GetBatch fetches up to batchSize of the oldest (older than 2 minutes) priority logs for processing.
	GetBatch(ctx context.Context, batchSize int) ([]KeyValuePair[UUID, []RegistryPayload[Handle]], error)

	// ProcessNewer iterates over all priority logs newer than 5 mins and invokes the processor callback for each.
	ProcessNewer(ctx context.Context, processor func(tid UUID, payload []RegistryPayload[Handle]) error) error

	// LogCommitChanges writes a special commit-change log used during drive reinstate for replication.
	LogCommitChanges(ctx context.Context, stores []StoreInfo, newRootNodesHandles, addedNodesHandles, updatedNodesHandles, removedNodesHandles []RegistryPayload[Handle]) error
}

TransactionPriorityLog records prioritised transaction logs used for recovery and replication workflows.

type Tuple

type Tuple[T1 any, T2 any] struct {
	// First is the first element of the pair.
	First T1
	// Second is the second element of the pair.
	Second T2
}

Tuple represents an ordered pair of two generic values when Key/Value semantics are not desired.

type TwoPhaseCommitTransaction

type TwoPhaseCommitTransaction interface {
	// Begin starts the transaction.
	Begin(ctx context.Context) error
	// Phase1Commit performs the first phase (prepare) of the commit.
	Phase1Commit(ctx context.Context) error
	// Phase2Commit performs the second phase (finalize) of the commit.
	Phase2Commit(ctx context.Context) error
	// Rollback aborts the transaction and may be provided an error cause.
	Rollback(ctx context.Context, err error) error
	// HasBegun reports whether the transaction has started.
	HasBegun() bool
	// GetMode returns the configured TransactionMode.
	GetMode() TransactionMode

	// GetStores lists all available B-Tree stores from the backend.
	GetStores(ctx context.Context) ([]string, error)

	// Close releases any resources associated with the transaction implementation.
	Close() error

	// GetID returns the transaction ID.
	GetID() UUID

	// CommitMaxDuration returns the configured maximum duration for commit operations.
	// Effective runtime limit is min(ctx deadline, CommitMaxDuration()).
	CommitMaxDuration() time.Duration

	// OnCommit registers a callback to be executed after a successful commit.
	OnCommit(callback func(ctx context.Context) error)
}

TwoPhaseCommitTransaction defines infrastructure-facing two-phase commit operations.

type UICapability

type UICapability string

UICapability represents the UI-friendly permission key (e.g., "can_edit", "can_delete")

const (
	UICapabilityRead     UICapability = "can_read"
	UICapabilityEdit     UICapability = "can_edit"
	UICapabilityDelete   UICapability = "can_delete"
	UICapabilityAISelect UICapability = "can_ai_select"
)

func ActionToUICapability

func ActionToUICapability(action Action) UICapability

ActionToUICapability maps an internal Action to the UI consumable Capability string

type UUID

type UUID uuid.UUID

UUID is a thin wrapper over github.com/google/uuid.UUID to keep SOP decoupled from the external package.

var NilUUID UUID

NilUUID is the zero-value UUID.

func NewUUID

func NewUUID() UUID

NewUUID returns a new randomly generated UUID. It retries on error with a 1ms backoff up to 10 times and panics only if all attempts fail (which should never happen under normal conditions).

func ParseUUID

func ParseUUID(id string) (UUID, error)

ParseUUID converts a string to a UUID. It returns an error if the input is not a valid UUID.

func (UUID) Compare

func (x UUID) Compare(y UUID) int

Compare compares two UUIDs and returns -1 if x < y, 1 if x > y, and 0 if they are equal.

func (UUID) IsNil

func (id UUID) IsNil() bool

IsNil reports whether the UUID equals the zero-value UUID.

func (UUID) MarshalText

func (id UUID) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (UUID) Split

func (id UUID) Split() (uint64, uint64)

Split returns the high and low 64-bit parts of the UUID.

func (UUID) String

func (id UUID) String() string

String returns the canonical string representation of the UUID.

func (*UUID) UnmarshalText

func (id *UUID) UnmarshalText(b []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

type ValueDataSize

type ValueDataSize int

ValueDataSize categorizes the expected size of Value data to guide configuration helpers.

const (
	// SmallData indicates small Value data that can be stored within the node segment.
	SmallData ValueDataSize = iota
	// MediumData indicates medium Value data that should be stored in a separate segment.
	MediumData
	// BigData indicates large Value data stored separately, actively persisted and typically not globally cached.
	BigData
)

type Visibility

type Visibility string
const (
	VisibilityPublic  Visibility = "public"
	VisibilityPrivate Visibility = "private"
	VisibilitySystem  Visibility = "system"
)

Directories

Path Synopsis
adapters
cassandra module
redis module
ai module
bindings
main command
Package btree provides the core B-Tree data structure and algorithms used by SOP.
Package btree provides the core B-Tree data structure and algorithms used by SOP.
Package cache contains in-process MRU/L1 cache implementations and utilities used by SOP.
Package cache contains in-process MRU/L1 cache implementations and utilities used by SOP.
Package cel provides a small wrapper around CEL expression compilation and evaluation used to compare map-based keys within SOP components.
Package cel provides a small wrapper around CEL expression compilation and evaluation used to compare map-based keys within SOP components.
cmd
sop-daemon command
testpb command
Package common contains shared transaction and B-tree management helpers used by SOP.
Package common contains shared transaction and B-tree management helpers used by SOP.
Package encoding provides pluggable marshal/unmarshal helpers used by SOP.
Package encoding provides pluggable marshal/unmarshal helpers used by SOP.
Package main demonstrates Gemini 3.1 Pro optimizations integration.
Package main demonstrates Gemini 3.1 Pro optimizations integration.
interop_indexes command
interop_jsondb command
multi_redis command
multi_redis_url command
quickstart command
Quickstart: the smallest possible SOP program.
Quickstart: the smallest possible SOP program.
relations_demo command
swarm_clustered command
fs
Package fs contains filesystem-backed implementations used by SOP.
Package fs contains filesystem-backed implementations used by SOP.
erasure
The decoder reverses the process done by "encoder.go"
The decoder reverses the process done by "encoder.go"
incfs module
infs module
Package inmemory provides in-memory implementations of selected SOP backends, primarily for tests and lightweight scenarios.
Package inmemory provides in-memory implementations of selected SOP backends, primarily for tests and lightweight scenarios.
internal
inredck
Package inredck contains the common kernel for Redis-based SOP implementations.
Package inredck contains the common kernel for Redis-based SOP implementations.
jsondb module
search module
Package streamingdata is part of the internal baseline and is unsupported for public use.
Package streamingdata is part of the internal baseline and is unsupported for public use.
tools
benchmark command
httpserver command

Jump to

Keyboard shortcuts

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