lucisearch 0.8.0

Embeddable, in-process search engine — the SQLite/DuckDB of Elasticsearch
Documentation
// Obsidian [[wikilinks]] in doc comments are intentional — they link to
// design and reference docs in docs/. Rustdoc doesn't understand them.
#![allow(rustdoc::broken_intra_doc_links)]

//! `luci` — embeddable, in-process search engine.
//!
//! The SQLite/DuckDB of Elasticsearch: link it in, open a file, search.
//! Indexing JSON documents, term/BM25/vector search, segment merge, and
//! persistence all live in this one crate, organized into modules that
//! mirror the former workspace crates (`core`, `mapping`, `storage`,
//! `analysis`) plus the engine subsystems.
//!
//! See [[luci|engineering vision]], [[architecture-overview]], and
//! [[architecture-segment-layout]] for the design.

// Former leaf crates, now modules.
pub mod analysis;
pub mod core;
pub mod mapping;
pub mod storage;

// Engine subsystems (formerly luci-index).
pub mod agg;
pub mod columnar;
pub mod inverted;
pub mod ip;
pub mod query;
pub mod search;
pub mod segment;
pub mod spatial;
pub mod store;
pub mod vector;

pub mod deletion;
pub mod index;
pub mod merge;
pub mod merge_policy;
pub mod reader;
pub mod writer;

// Top-level re-exports for the high-frequency API surface, so the common
// types stay one path deep (`luci::Index`, `luci::Mapping`, `luci::LuciError`).
pub use crate::core::{
    DocId, FieldId, LuciError, Result, ScoreMode, Scorer, SegmentId, TwoPhaseIterator,
};
pub use crate::index::Index;
pub use crate::mapping::{
    DynamicMode, FieldMapping, FieldType, Mapping, MappingBuilder, QuantizationType,
};

/// Configure the global thread pool for parallel search.
///
/// Must be called before any search operation. Can only be called once
/// per process — subsequent calls return an error.
///
/// If not called, rayon defaults to the number of available CPUs
/// (or the `RAYON_NUM_THREADS` environment variable).
pub fn set_num_threads(num_threads: usize) -> Result<()> {
    rayon::ThreadPoolBuilder::new()
        .num_threads(num_threads)
        .build_global()
        .map_err(|e| LuciError::InvalidQuery(format!("failed to set thread pool: {e}")))
}