Skip to content

C API reference

Rendered from holographic_memory.h, the header the library ships. Every symbol carries the ABI major version as a suffix, so a program built against one major version keeps working with later minor versions of the library.

Macros

HMS_ABI_VERSION

The ABI version, packed as major << 16 | minor << 8 | patch.

#define HMS_ABI_VERSION 65536

HMS_ABI_MAJOR

The ABI major version, equal to the numeric suffix of the hms1_ symbols.

#define HMS_ABI_MAJOR 1

HMS_MAX_BUFFER_BYTES

Largest single input buffer accepted, in bytes.

#define HMS_MAX_BUFFER_BYTES (1 << 30)

HMS_MAX_ARRAY_LEN

Largest element count accepted for any input array.

#define HMS_MAX_ARRAY_LEN (1 << 24)

HMS_SEARCH_SET_LEXICAL_WEIGHT

#define HMS_SEARCH_SET_LEXICAL_WEIGHT (1 << 0)

HMS_SEARCH_SET_SEMANTIC_WEIGHT

#define HMS_SEARCH_SET_SEMANTIC_WEIGHT (1 << 1)

HMS_SEARCH_SET_MIN_SEMANTIC_SCORE

#define HMS_SEARCH_SET_MIN_SEMANTIC_SCORE (1 << 2)

HMS_SEARCH_SET_BM25_K1

#define HMS_SEARCH_SET_BM25_K1 (1 << 3)

HMS_SEARCH_SET_BM25_B

#define HMS_SEARCH_SET_BM25_B (1 << 4)

HMS_OK

Success.

#define HMS_OK 0

HMS_ERR_NULL_POINTER

A required pointer argument was NULL (or a non-empty buffer had a NULL pointer).

#define HMS_ERR_NULL_POINTER 1

HMS_ERR_INVALID_ARGUMENT

An argument was malformed or out of range, or the engine rejected the request.

#define HMS_ERR_INVALID_ARGUMENT 2

HMS_ERR_INVALID_UTF8

A string argument was not valid UTF-8.

#define HMS_ERR_INVALID_UTF8 3

HMS_ERR_INVALID_HANDLE

A handle is not a live handle of the expected kind (closed, freed, or never issued).

#define HMS_ERR_INVALID_HANDLE 4

HMS_ERR_IO

An operating-system I/O failure.

#define HMS_ERR_IO 5

HMS_ERR_LOCKED

The store is open in another engine (this or another process).

#define HMS_ERR_LOCKED 6

HMS_ERR_ENCRYPTION

The encryption key is missing, wrong, or the store cannot be decrypted with it.

#define HMS_ERR_ENCRYPTION 7

HMS_ERR_CORRUPT

Stored data failed an integrity check.

#define HMS_ERR_CORRUPT 8

HMS_ERR_LIMIT_EXCEEDED

A length or count exceeds a documented limit.

#define HMS_ERR_LIMIT_EXCEEDED 9

HMS_ERR_ABI_MISMATCH

A struct_size field is smaller than the first field it must cover.

#define HMS_ERR_ABI_MISMATCH 10

HMS_ERR_PANIC

A Rust panic was caught at the boundary; the store should be considered suspect.

#define HMS_ERR_PANIC 98

HMS_ERR_INTERNAL

An unclassified engine failure.

#define HMS_ERR_INTERNAL 99

Types

hms_chunks_t

A chunking result. Opaque to C; read with hms1_chunks_count and hms1_chunks_get.

typedef struct hms_chunks_t hms_chunks_t;

hms_results_t

A search result set. Opaque to C; read with hms1_results_count and hms1_results_get.

typedef struct hms_results_t hms_results_t;

hms_store_t

An open store. Opaque to C.

typedef struct hms_store_t hms_store_t;

hms_status_t

Status returned by every fallible function. Zero is success; every failure also leaves a message readable with hms1_last_error_message on the calling thread.

typedef int32_t hms_status_t;

hms_str_t

A length-prefixed UTF-8 string. It is not NUL terminated and may contain any valid UTF-8, including NUL. As an input, ptr == NULL with len == 0 means "absent" (use the default). As an output it borrows from the handle that produced it.

typedef struct {
  const uint8_t *ptr;
  size_t len;
} hms_str_t;

hms_open_options_t

Store open options. Set struct_size = sizeof(hms_open_options_t); fields past the caller's struct_size take their defaults, so a newer library accepts an older caller.

typedef struct {
  // `sizeof` of this struct as the caller compiled it.
  uint32_t struct_size;
  // Reserved; must be zero.
  uint32_t flags;
  // Encryption passphrase (UTF-8). Absent leaves encryption off. A store created with a
  // key can only be opened with the same key.
  hms_str_t encryption_key;
  // 0 default (off), 1 on, -1 off. Signs mutations with an Ed25519 key kept in the store.
  int32_t signing;
  // 0 default (off), 1 on, -1 off.
  int32_t audit;
  // Embedding space for caller-supplied embeddings. All three or none; the model and
  // revision are identifiers the store pins, the dimension is 1..=65536.
  hms_str_t embedding_model;
  hms_str_t embedding_revision;
  uint32_t embedding_dimensions;
} hms_open_options_t;

hms_search_options_t

Search options. Set struct_size = sizeof(hms_search_options_t); see hms_open_options_t for the compatibility rule. Initialise it with hms1_search_options_init; a zero-initialised struct (with struct_size set) selects every engine default.

typedef struct {
  uint32_t struct_size;
  // Bitwise OR of `HMS_SEARCH_SET_*`; a numeric field below is honoured only when its bit
  // is set (zero is a meaningful weight), so a zero-initialised struct means all defaults.
  uint32_t flags;
  // Hits to return; 0 is the engine default.
  uint32_t k;
  // Candidates gathered per list before fusion; 0 is the engine default.
  uint32_t candidate_limit;
  // JSON metadata filter; absent matches everything.
  hms_str_t filter_json;
  // Restrict to one source URI.
  hms_str_t source_uri;
  // Restrict to these document ids (`document_id_count` entries).
  const hms_str_t *document_ids;
  size_t document_id_count;
  // Query embedding for semantic or hybrid search (`embedding_len` doubles).
  const double *embedding;
  size_t embedding_len;
  // Honoured with `HMS_SEARCH_SET_LEXICAL_WEIGHT`.
  double lexical_weight;
  // Honoured with `HMS_SEARCH_SET_SEMANTIC_WEIGHT`.
  double semantic_weight;
  // Honoured with `HMS_SEARCH_SET_MIN_SEMANTIC_SCORE`.
  double min_semantic_score;
  // BM25 term-frequency saturation k1 (default 1.2, finite and nonnegative); honoured with
  // `HMS_SEARCH_SET_BM25_K1`.
  double bm25_k1;
  // BM25 length normalization b (default 0.75, in [0, 1]); honoured with
  // `HMS_SEARCH_SET_BM25_B`.
  double bm25_b;
  // `"blend"` (default) or `"rrf"`; absent is the default.
  hms_str_t fusion;
} hms_search_options_t;

hms_document_t

One document to ingest. Zero, NULL and absent-string fields take the engine defaults.

typedef struct {
  // Unique non-empty identifier, at most 4096 bytes. Re-ingesting an id replaces it.
  hms_str_t id;
  hms_str_t text;
  hms_str_t source_uri;
  hms_str_t version;
  // A JSON value (object recommended) stored with the document and returned with hits.
  hms_str_t metadata_json;
  // Words per chunk; 0 is the engine default.
  uint32_t chunk_words;
  // Overlap words between chunks; 0 is the engine default.
  uint32_t overlap_words;
  // Counts the first line's terms this many times in the first chunk (BM25 title boost);
  // 0 or 1 leaves the document unchanged.
  uint32_t title_weight;
  // 0 default (keep), 1 keep the text for retrieval, -1 index without keeping the text.
  int32_t store_text;
  // Optional row-major embeddings, `embedding_rows` x `embedding_dim` doubles, one row per
  // chunk; requires the store to be opened with an embedding space of that dimension.
  const double *embeddings;
  size_t embedding_rows;
  size_t embedding_dim;
} hms_document_t;

hms_result_t

One search hit. Strings borrow from the hms_results_t that produced it and stay valid until hms1_results_free.

typedef struct {
  // Chunk id.
  hms_str_t id;
  hms_str_t document_id;
  // `ptr == NULL` when the document has no source URI.
  hms_str_t source_uri;
  hms_str_t version;
  // The document metadata as JSON text.
  hms_str_t metadata_json;
  // The chunk text; `ptr == NULL` when the document was stored without text.
  hms_str_t text;
  uint32_t start_byte;
  uint32_t end_byte;
  double score;
  double lexical_score;
  // NaN when the hit has no semantic score.
  double semantic_score;
} hms_result_t;

hms_stats_t

Store statistics. Set struct_size before the call; the library fills the fields the caller's struct covers.

typedef struct {
  uint32_t struct_size;
  uint32_t dimensions;
  // Vectors in the store (document chunks count as vectors).
  uint64_t vector_count;
  int32_t nsg_trained;
  int32_t ivf_trained;
  int32_t nsg_training_recommended;
  int32_t ivf_training_recommended;
  int32_t document_index_trained;
  uint32_t storage_format_version;
  uint32_t storage_segment_count;
  uint64_t document_embedding_count;
  uint64_t storage_used_bytes;
  uint64_t storage_capacity_bytes;
} hms_stats_t;

hms_security_status_t

Security status. Set struct_size before the call.

typedef struct {
  uint32_t struct_size;
  // The library was built with encryption and signing support.
  int32_t security_compiled;
  // Data at rest is encrypted with AES-256-GCM under an Argon2-derived key.
  int32_t encryption_active;
  int32_t signing_active;
  int32_t audit_active;
  int32_t differential_privacy_active;
  double epsilon;
} hms_security_status_t;

hms_chunk_t

One chunk of a document as hms1_chunk_document would split it.

typedef struct {
  hms_str_t id;
  hms_str_t text;
  uint32_t start_byte;
  uint32_t end_byte;
} hms_chunk_t;

Functions

hms1_abi_version

The ABI version the loaded library implements, packed as major << 16 | minor << 8 | patch. A caller built against HMS_ABI_VERSION is compatible when the majors are equal and the library's minor is at least the caller's.

uint32_t hms1_abi_version(void);

hms1_version

The library's own version string (the holographic-memory-c crate version), a static NUL-terminated UTF-8 string. Never NULL; never freed.

const char *hms1_version(void);

hms1_last_error_code

The code of the last failed call on this thread, or HMS_OK if the last call succeeded.

hms_status_t hms1_last_error_code(void);

hms1_last_error_message

The message of the last failed call on this thread as a NUL-terminated UTF-8 string, empty if the last call succeeded. Never NULL. The pointer stays valid until the next hms1_* call on the same thread (any call resets it); copy it if it must outlive that.

const char *hms1_last_error_message(void);

hms1_open_options_init

Fill options with the library defaults. Callers that build the struct field by field must still set struct_size.

Safety

options must be NULL or point to a writable hms_open_options_t.

void hms1_open_options_init(hms_open_options_t *options);

hms1_search_options_init

Fill options with the library defaults (all flags clear).

Safety

options must be NULL or point to a writable hms_search_options_t.

void hms1_search_options_init(hms_search_options_t *options);

hms1_store_open

Open or create the store in directory path with vectors of dimensions (1..=1000000).

A store directory is held by exactly one open handle at a time, across processes (HMS_ERR_LOCKED otherwise). options may be NULL for defaults. On success *out receives a handle that must be released with hms1_store_close; on failure *out is NULL.

Safety

path and every hms_str_t in options must be valid for their lengths; out must be writable.

hms_status_t hms1_store_open(hms_str_t path,
                             uint32_t dimensions,
                             const hms_open_options_t *options,
                             hms_store_t **out);

hms1_store_close

Flush and release a store. Calls already running on it complete first; afterwards the handle is invalid. NULL is ignored. Closing an unknown or already closed handle returns HMS_ERR_INVALID_HANDLE. If the final flush fails the handle is still released and the failure is reported.

hms_status_t hms1_store_close(hms_store_t *store);

hms1_store_ingest

Ingest count documents as one atomic batch: either all become visible or none do. chunk_counts, if not NULL, receives the number of chunks of each document and must hold count entries. An empty batch succeeds and does nothing. At most 16777216 documents per call; each document is bounded by the engine (8 MiB of text).

Safety

documents must point to count valid hms_document_t whose strings and embeddings are valid for their lengths for the duration of the call.

hms_status_t hms1_store_ingest(hms_store_t *store,
                               const hms_document_t *documents,
                               size_t count,
                               uint32_t *chunk_counts);

Search the store for query (hybrid lexical BM25 plus, with an embedding, semantic). options may be NULL for defaults. On success *out receives a result set to release with hms1_results_free; it is NULL on failure. Concurrent searches are safe.

Safety

query, options and the strings it points to must be valid for their lengths; out must be writable.

hms_status_t hms1_store_search(hms_store_t *store,
                               hms_str_t query,
                               const hms_search_options_t *options,
                               hms_results_t **out);

hms1_results_count

Number of hits. NULL counts as zero.

Safety

results must be NULL or a live result set.

size_t hms1_results_count(const hms_results_t *results);

hms1_results_get

Read hit index into out. The strings borrow from results until it is freed.

Safety

results must be a live result set and out writable.

hms_status_t hms1_results_get(const hms_results_t *results, size_t index, hms_result_t *out);

hms1_results_free

Release a result set and every string borrowed from it. NULL is ignored.

Safety

results must be NULL or a result set not yet freed.

void hms1_results_free(hms_results_t *results);

hms1_store_delete

Delete a document and all its chunks. *deleted (optional) receives 1 if it existed. Deleting an absent id succeeds with *deleted == 0.

Safety

id must be valid for its length; deleted NULL or writable.

hms_status_t hms1_store_delete(hms_store_t *store, hms_str_t id, int32_t *deleted);

hms1_store_stats

Read store statistics into out; set out->struct_size first.

Safety

out must be writable for out->struct_size bytes (at most sizeof(hms_stats_t) are written).

hms_status_t hms1_store_stats(hms_store_t *store, hms_stats_t *out);

hms1_store_security_status

Read the store's security status into out; set out->struct_size first. Encryption is reported as active only for a store that was opened with an encryption key.

Safety

As hms1_store_stats.

hms_status_t hms1_store_security_status(hms_store_t *store, hms_security_status_t *out);

hms1_store_flush

Flush all state to durable storage.

hms_status_t hms1_store_flush(hms_store_t *store);

hms1_store_compact

Rewrite the transaction log without superseded and deleted records, reclaiming space. Safe alongside concurrent searches and ingests.

hms_status_t hms1_store_compact(hms_store_t *store);

hms1_store_maintain

Train any index whose configured threshold has been reached. Idempotent.

hms_status_t hms1_store_maintain(hms_store_t *store);

hms1_store_snapshot

Write a verified point-in-time copy of the store to the new directory destination, which must not exist and must not lie inside the store. Mutations wait for the copy. The copy appears atomically only after its framing and checksums verify, and is an ordinary store: open it with the same encryption key. Reads are not blocked.

Safety

destination must be valid for its length.

hms_status_t hms1_store_snapshot(hms_store_t *store, hms_str_t destination);

hms1_chunk_document

Split a document into the chunks ingest would store, without touching any store. document supplies id, text, chunk_words and overlap_words. On success *out receives a chunk set to release with hms1_chunks_free.

Safety

document must point to a valid hms_document_t; out must be writable.

hms_status_t hms1_chunk_document(const hms_document_t *document, hms_chunks_t **out);

hms1_chunks_count

Number of chunks. NULL counts as zero.

Safety

chunks must be NULL or a live chunk set.

size_t hms1_chunks_count(const hms_chunks_t *chunks);

hms1_chunks_get

Read chunk index into out; strings borrow from chunks until it is freed.

Safety

chunks must be a live chunk set and out writable.

hms_status_t hms1_chunks_get(const hms_chunks_t *chunks, size_t index, hms_chunk_t *out);

hms1_chunks_free

Release a chunk set. NULL is ignored.

Safety

chunks must be NULL or a chunk set not yet freed.

void hms1_chunks_free(hms_chunks_t *chunks);