{"id":50965693,"url":"https://github.com/harehare/mq-db","last_synced_at":"2026-06-18T20:01:59.588Z","repository":{"id":361846844,"uuid":"1254350256","full_name":"harehare/mq-db","owner":"harehare","description":"Markdown-specialized embedded database with interval-indexed block storage and hierarchical query support.","archived":false,"fork":false,"pushed_at":"2026-06-11T14:17:23.000Z","size":1426,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T16:12:48.913Z","etag":null,"topics":["database","markdown","mq"],"latest_commit_sha":null,"homepage":"https://mqlang.org","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/harehare.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T13:05:40.000Z","updated_at":"2026-06-11T14:20:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/harehare/mq-db","commit_stats":null,"previous_names":["harehare/mq-db"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/harehare/mq-db","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harehare%2Fmq-db","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harehare%2Fmq-db/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harehare%2Fmq-db/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harehare%2Fmq-db/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/harehare","download_url":"https://codeload.github.com/harehare/mq-db/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harehare%2Fmq-db/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34505423,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","markdown","mq"],"created_at":"2026-06-18T20:01:57.262Z","updated_at":"2026-06-18T20:01:59.579Z","avatar_url":"https://github.com/harehare.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.svg\" width=\"96\" height=\"96\" /\u003e\n\n\u003ch1\u003emq-db\u003c/h1\u003e\n\n**Markdown-specialized embedded database with interval-indexed block storage and hierarchical query support.**\n\n[![ci](https://img.shields.io/github/actions/workflow/status/harehare/mq-db/ci.yml?logo=github-actions\u0026label=ci)](https://github.com/harehare/mq-db/actions/workflows/ci.yml)\n[![audit](https://img.shields.io/github/actions/workflow/status/harehare/mq-db/audit.yml?logo=shield\u0026label=audit)](https://github.com/harehare/mq-db/actions/workflows/audit.yml)\n[![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)\n\n![demo](./assets/demo.gif)\n\n\u003c/div\u003e\n\n`mq-db` treats Markdown documents as **structured, hierarchical databases** rather than plain text. It parses Markdown into a flat block list with an **interval index** (Nested Set / Pre-Post Order), enabling O(1) section hierarchy queries. Documents can be queried with **SQL** or **[mq](https://github.com/harehare/mq)** and persisted to a compact custom page-file format.\n\n```mermaid\nflowchart TD\n    A[\"Markdown File(s)\"] --\u003e|\"CST Parser (mq-markdown)\"| B[\"Block Tree\\n(heading · paragraph · code · list …)\"]\n    B --\u003e|\"Interval Index + Secondary Indexes\"| C[\"Flat Block Vector\\n(pre/post integers)\"]\n    C --\u003e D[\"BitmapIndex\\n(block_type)\"]\n    C --\u003e E[\"BTreeIndex\\n(pre / post)\"]\n    C --\u003e F[\"HashIndex\\n(content / lang / depth)\"]\n    C --\u003e G[\"Zone Maps\\n(per-document stats)\"]\n    C --\u003e H[\"SQL Engine\\n(sqlparser — custom native evaluator)\"]\n    C --\u003e I[\"mq Engine\\n(mq-lang evaluator)\"]\n```\n\n\u003e [!IMPORTANT]\n\u003e This project is under active development and the API may change.\n\n## Features\n\n- **Flat block storage** — every Markdown element becomes a typed `Block` with row-polymorphic properties\n- **O(1) hierarchy queries** — interval index (`pre`/`post`) makes ancestor/descendant checks a single integer comparison\n- **Three-layer secondary indexes** — `BitmapIndex` (block type), `BTreeIndex` (pre/post), `HashIndex` (content/lang/depth) for fast SQL predicate pushdown\n- **Zone Maps** — per-document statistics skip irrelevant files before scanning any blocks\n- **Dual query engines** — SQL via a custom `sqlparser`-based evaluator, and `mq` via `mq-lang`\n- **DDL support** — `CREATE TABLE`, `INSERT INTO`, `DROP TABLE` for in-memory custom tables\n- **`mq()` scalar function** — run an mq program against Markdown content inline in SQL\n- **Custom page-file persistence** — 8 KB fixed pages, checksums, atomic writes\n- **CLI + interactive REPL + TUI** — full terminal experience\n\n## Installation\n\n### Using the Installation Script (Recommended)\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/harehare/mq-db/main/bin/install.sh | bash\n```\n\nThe installer will:\n- Download the latest release for your platform\n- Verify the binary with SHA256 checksum\n- Install to `~/.local/bin/`\n- Update your shell profile (bash, zsh, or fish)\n\nAfter installation, restart your terminal or run:\n```bash\nsource ~/.bashrc  # or ~/.zshrc, or ~/.config/fish/config.fish\n```\n\n### Using Cargo\n\n```bash\ncargo install mq-db\n```\n\n### From Source\n\n```bash\n# Latest Development Version\ncargo install --git https://github.com/harehare/mq-db.git\n```\n\n### Supported Platforms\n\n- **Linux**: x86_64, aarch64\n- **macOS**: x86_64 (Intel), aarch64 (Apple Silicon)\n- **Windows**: x86_64\n\n## CLI Usage\n\n### Index Markdown files\n\n```bash\nmq-db index docs/ --recursive --output store.mq-db\nmq-db index README.md DESIGN.md\nmq-db index docs/ --no-spans   # omit source spans (~21 bytes/block saved)\n```\n\n```\n  ✓ docs/DESIGN.md\n  ✓ docs/API.md\n\nIndexed 2 files → store.mq-db\n```\n\n### List indexed documents\n\n```bash\nmq-db list --db store.mq-db\nmq-db list --db store.mq-db --format json   # also: csv, tsv, markdown, html\n```\n\n```\n┌──────┬────────────────────────────────────────────────────┬────────┬──────────┐\n│   ID │ Path / Title                                       │ Blocks │ Tags     │\n├──────┼────────────────────────────────────────────────────┼────────┼──────────┤\n│    0 │ docs/DESIGN.md                                     │    142 │          │\n│    1 │ docs/API.md                                        │     87 │ api, v2  │\n└──────┴────────────────────────────────────────────────────┴────────┴──────────┘\n2 documents\n```\n\n### SQL queries\n\n```bash\nmq-db sql \"SELECT block_type, count(*) FROM blocks GROUP BY block_type\" --db store.mq-db\nmq-db sql --file query.sql --db store.mq-db           # read SQL from a file\nmq-db sql \"SELECT ...\" --db store.mq-db --format json  # also: csv, tsv, markdown, html\n```\n\n```\n┌─────────────┬──────────┐\n│ block_type  │ count(*) │\n├─────────────┼──────────┤\n│ paragraph   │ 48       │\n│ heading     │ 21       │\n│ code        │ 15       │\n└─────────────┴──────────┘\n(3 rows)\n```\n\n**Hierarchy query with `under()`** — find all content inside a specific section:\n\n```bash\nmq-db sql \"\n  SELECT b.block_type, b.content\n  FROM blocks b\n  WHERE under(b.pre, b.post,\n    (SELECT pre FROM blocks WHERE block_type = 'heading' AND content = 'Architecture'),\n    (SELECT post FROM blocks WHERE block_type = 'heading' AND content = 'Architecture'))\n  ORDER BY b.pre\n\" --db store.mq-db\n```\n\n**`mq()` scalar function** — run an mq program against Markdown content inline:\n\n```bash\nmq-db sql \"SELECT mq('.h1 | to_text', content) AS title FROM blocks WHERE block_type = 'code'\" --db store.mq-db\n```\n\n### DDL — custom in-memory tables\n\n```bash\n# Create from a SELECT result\nmq-db sql \"CREATE TABLE headings AS SELECT content, depth FROM blocks WHERE block_type = 'heading'\" --db store.mq-db\n\n# Create with explicit schema, then insert\nmq-db sql \"CREATE TABLE notes (id TEXT, body TEXT)\" --db store.mq-db\nmq-db sql \"INSERT INTO notes VALUES ('1', 'Hello world')\" --db store.mq-db\n\n# Inspect\nmq-db sql \"SHOW TABLES\" --db store.mq-db\nmq-db sql \"DESC notes\"  --db store.mq-db\n\n# Drop\nmq-db sql \"DROP TABLE notes\" --db store.mq-db\n```\n\n### mq queries\n\n```bash\nmq-db mq \".h1\" --db store.mq-db\nmq-db mq 'select(.code_lang == \"rust\")' --db store.mq-db\nmq-db mq \".h1\" --db store.mq-db --format markdown  # also: json, csv, tsv, html\n```\n\n### Interactive REPL\n\n```bash\nmq-db repl --db store.mq-db --mode sql\n```\n\n```\nmq-db  (.help for commands  .quit to exit)\nmode: sql  (.mode mq | .mode sql)\n\nsql\u003e SELECT content FROM blocks WHERE block_type = 'heading' LIMIT 3;\n┌──────────────────┐\n│ content          │\n├──────────────────┤\n│ Overview         │\n│ Architecture     │\n│ Query Engine     │\n└──────────────────┘\n(3 rows)\n\nsql\u003e .mode mq\n→ mq mode\nmq\u003e .h2\n## Architecture\n## Query Engine\n```\n\n### HTTP server\n\n```bash\nmq-db serve --db store.mq-db              # listens on 127.0.0.1:7878\nmq-db serve --db store.mq-db --port 8080  # custom port\nmq-db serve --db store.mq-db --host 0.0.0.0 --port 8080\n```\n\nThree endpoints are available:\n\n| Method | Path      | Body                   | Description                                          |\n| ------ | --------- | ---------------------- | ---------------------------------------------------- |\n| `GET`  | `/health` | —                      | `{\"status\":\"ok\",\"documents\":\u003cn\u003e}`                    |\n| `POST` | `/sql`    | `{\"query\":\"SELECT …\"}` | Execute a SQL query, returns JSON rows               |\n| `POST` | `/mq`     | `{\"code\":\".h1\"}`       | Evaluate an mq expression, returns `{\"results\":[…]}` |\n\n```bash\n# Health check\ncurl http://127.0.0.1:7878/health\n\n# SQL via HTTP\ncurl -s -X POST http://127.0.0.1:7878/sql \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"query\":\"SELECT block_type, count(*) FROM blocks GROUP BY block_type\"}'\n\n# mq via HTTP\ncurl -s -X POST http://127.0.0.1:7878/mq \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"code\":\".h1\"}'\n```\n\n### Structural linting\n\n```bash\nmq-db lint --db store.mq-db --depth 2\n```\n\n```\n✗  1 violation  (H2 immediately followed by list)\n\n  file                                      heading\n  ────────────────────────────────────────  ──────────────────────────────\n  docs/DESIGN.md                            \"Quick Start\"\n```\n\n### Statistics\n\n```bash\nmq-db stats --db store.mq-db\n```\n\n```\n  Documents  5\n  Blocks     632\n\n  Block types\n  ────────────────────────────────────────────────────────\n   ¶  paragraph    ████████████████████░░░░   241  (38%)\n   #  heading      ████████░░░░░░░░░░░░░░░░    89  (14%)\n  {}  code         ███████░░░░░░░░░░░░░░░░░    73  (12%)\n   •  list         ██████░░░░░░░░░░░░░░░░░░    58   (9%)\n\n  Code languages\n  ────────────────────────────────────────────────────────\n  {}  rust         ████████████████████████    41  (57%)\n  {}  python       ██████████░░░░░░░░░░░░░░    18  (25%)\n  {}  bash         ███████░░░░░░░░░░░░░░░░░    14  (19%)\n```\n\n### Show document structure\n\n```bash\nmq-db show 0 --db store.mq-db\n```\n\n```\n  docs/DESIGN.md\n  title   Design Document\n  blocks  142\n\n  pre   post  type               content\n  ────  ────  ────────────────   ──────────────────────────────────────────\n     0   141  heading H1         Design Document\n     2    55  heading H2         Architecture\n     4    21  paragraph          The system is built on…\n    22    37  heading H3           Query Engine\n    24    36  code                   fn main() { … }\n```\n\n### TUI\n\n```bash\nmq-db tui --db store.mq-db\n```\n\n```\n mq-db  SQL  Tab:switch  i:input  j/k:nav  d/u:scroll  q:quit\n┌─ Documents ──────────┬─ SQL ────────────────────────────────────────────────┐\n│ DESIGN.md            │ SELECT block_type, count(*) FROM blocks GROUP BY b_  │\n│   142 blocks         ├─ Results ────────────────────────────────────────────┤\n│ API.md               │ ┌─────────────┬──────────┐                           │\n│   87 blocks  API     │ │ block_type  │ count(*) │                           │\n│ README.md            │ ├─────────────┼──────────┤                           │\n│   34 blocks          │ │ paragraph   │ 48       │                           │\n└──────────────────────┴──────────────────────────────────────────────────────┘\n 5 docs  632 blocks  3 rows\n```\n\n**Keys:**\n\n| Key            | Action                   |\n| -------------- | ------------------------ |\n| `i`            | Focus query input        |\n| `Esc`          | Blur input               |\n| `Enter`        | Run query                |\n| `Tab`          | Toggle mq / SQL mode     |\n| `j` / `k`      | Navigate document list   |\n| `d` / `u`      | Scroll results down / up |\n| `g` / `G`      | Jump to top / bottom     |\n| `q` / `Ctrl+C` | Quit                     |\n\n## Library API\n\n```rust\nuse mq_db::{DocumentStore, SqlEngine, MqEngine, block::BlockType};\n\n// ── Build in memory ──────────────────────────────────────────────────────────\nlet mut store = DocumentStore::new();\nstore.add_file(\"docs/DESIGN.md\")?;\nstore.add_str(\"# Hello\\n\\n## Architecture\\n\\nDetails\\n\")?;\n\n// Chainable query API — zone-map skip + interval scope + block predicates\nlet chunks = store.query()\n    .documents(|doc| doc.zone_maps.heading_contents.contains(\"Architecture\"))\n    .under_heading(\"Architecture\", Some(2))\n    .filter(|b| matches!(b.block_type, BlockType::Paragraph | BlockType::Code))\n    .blocks();\n\n// SQL engine (custom sqlparser-based evaluator — no SQLite dependency)\nlet engine = SqlEngine::new(\u0026store)?;\nlet out = engine.execute(\n    \"SELECT content FROM blocks WHERE block_type = 'heading' ORDER BY pre\"\n)?;\nprint!(\"{}\", out.to_table());\n\n// mq engine\nlet results = MqEngine::eval_store(\".h1\", \u0026store)?;\n\n// Structural lint\nlet violations = store.query().lint_heading_followed_by(2, \u0026[BlockType::List]);\n\n// ── Persist / load ───────────────────────────────────────────────────────────\nstore.save(\"store.mq-db\")?;\n\n// Full load — all blocks read into memory, indexes built on first SqlEngine use\nlet store = DocumentStore::load(\"store.mq-db\")?;\n\n// Lazy open — catalog only; call load_all_blocks() + load_all_indexes() before SQL\nlet mut store = DocumentStore::open(\"store.mq-db\")?;\nstore.load_all_blocks()?;\nstore.load_all_indexes()?;\n\n// Catalog-only — for metadata commands (list, stats) that don't need block data\nlet store = DocumentStore::load_catalog_only(\"store.mq-db\")?;\n```\n\n## SQL Reference\n\n### Virtual schema\n\n```sql\nSELECT id, path, title, tags FROM documents;\n\nSELECT id, document_id, block_type, content, pre, post,\n       depth, lang, properties FROM blocks;\n```\n\n### Built-in functions\n\n| Function                              | Description                                |\n| ------------------------------------- | ------------------------------------------ |\n| `under(pre, post, anc_pre, anc_post)` | O(1) interval ancestor check               |\n| `mq(program, content)`                | Run an mq program against Markdown content |\n| `json_extract(json, path)`            | Extract a value from a JSON string         |\n| `count(*) / min / max / sum / avg`    | Aggregate functions                        |\n| `lower / upper / length / coalesce`   | Scalar utilities                           |\n\n### DDL statements\n\n| Statement                         | Description                                       |\n| --------------------------------- | ------------------------------------------------- |\n| `CREATE TABLE name AS SELECT …`   | Create a custom table from a query result         |\n| `CREATE TABLE name (col TYPE, …)` | Create an empty custom table with explicit schema |\n| `INSERT INTO name VALUES (…)`     | Insert a row into a custom table                  |\n| `DROP TABLE name`                 | Drop a custom table                               |\n| `SHOW TABLES`                     | List all custom tables                            |\n| `DESC name`                       | Show schema of a custom table                     |\n\n### Example queries\n\n```sql\n-- All text/code under a specific section (RAG extraction)\nSELECT b.block_type, b.content\nFROM blocks b\nWHERE under(b.pre, b.post,\n  (SELECT pre FROM blocks WHERE block_type = 'heading' AND content = 'Architecture'),\n  (SELECT post FROM blocks WHERE block_type = 'heading' AND content = 'Architecture'))\n  AND b.block_type IN ('paragraph', 'code')\nORDER BY b.pre;\n\n-- Extract H1 title from code block content via the mq() scalar function\nSELECT mq('.h1 | to_text', content) AS title\nFROM blocks\nWHERE block_type = 'code' AND lang = 'markdown';\n\n-- H2 headings immediately followed by a list (structural lint)\nSELECT d.path, h.content AS heading\nFROM blocks h\nJOIN blocks nxt ON nxt.document_id = h.document_id AND nxt.pre = h.pre + 1\nJOIN documents d ON d.id = h.document_id\nWHERE h.block_type = 'heading' AND depth = 2 AND nxt.block_type = 'list';\n\n-- Documents containing Python code\nSELECT DISTINCT d.path\nFROM documents d JOIN blocks b ON b.document_id = d.id\nWHERE b.block_type = 'code' AND lang = 'python';\n```\n\n## Architecture\n\n### Block model\n\nEvery Markdown element becomes a `Block`:\n\n```rust\nstruct Block {\n    id: u32,\n    document_id: u32,\n    block_type: BlockType,  // Heading, Paragraph, Code, List, …\n    content: String,\n    span: Option\u003cSpan\u003e,     // line/column for editor sync\n    pre: u32,               // interval index pre-order\n    post: u32,              // interval index post-order\n    properties: Properties, // row-polymorphic extra attributes\n}\n```\n\n| Block type      | Properties                                          |\n| --------------- | --------------------------------------------------- |\n| `Heading`       | `{ \"depth\": 2, \"slug\": \"architecture\" }`            |\n| `Code`          | `{ \"lang\": \"rust\", \"meta\": \"no_run\" }`              |\n| `List`          | `{ \"ordered\": false, \"level\": 1, \"checked\": null }` |\n| `Yaml` / `Toml` | parsed front-matter keys (`\"title\"`, `\"tags\"`, …)   |\n\n### Index layers\n\nmq-db applies three complementary index layers, cheapest-first.\n\n```mermaid\nflowchart LR\n    Q[\"SQL Query\"] --\u003e ZM[\"Layer 1\\nZone Maps\\n(document skip)\"]\n    ZM --\u003e|\"relevant docs\"| II[\"Layer 2\\nInterval Index\\n(section scope)\"]\n    II --\u003e|\"candidate blocks\"| SI[\"Layer 3\\nSecondary Indexes\\n(block lookup)\"]\n    SI --\u003e|\"BitmapIndex\\nBTreeIndex\\nHashIndex\"| R[\"Result Rows\"]\n    ZM --\u003e|\"skip\"| X1[\"✗ irrelevant docs\"]\n    SI --\u003e|\"no hint\"| FS[\"Full Scan\"]\n```\n\n#### Layer 1 — Zone Maps (document-level skip)\n\nBuilt once per document and stored in the `.mq-db` file. Checked before any block is read:\n\n| Field               | Skips documents where…               |\n| ------------------- | ------------------------------------ |\n| `heading_contents`  | The requested heading text is absent |\n| `code_languages`    | The requested language tag is absent |\n| `max_heading_depth` | The requested depth cannot exist     |\n| `tags`              | The tag filter cannot match          |\n\n#### Layer 2 — Interval Index (section hierarchy)\n\nHeading hierarchy encoded as `(pre, post)` pairs via Pre-Post Order (Nested Set) traversal:\n\n```mermaid\ngraph TD\n    doc[\"# Doc\\npre=0 · post=11\"]\n    secA[\"## Section A\\npre=2 · post=7\"]\n    para1[\"Paragraph\\npre=3 · post=4\"]\n    code1[\"Code\\npre=5 · post=6\"]\n    secB[\"## Section B\\npre=8 · post=11\"]\n    para2[\"Paragraph\\npre=9 · post=10\"]\n\n    doc --\u003e secA\n    doc --\u003e secB\n    secA --\u003e para1\n    secA --\u003e code1\n    secB --\u003e para2\n```\n\n`A is_under B` ↔ `B.pre \u003c A.pre AND A.post \u003c B.post` — O(1), no tree traversal.\n\n#### Layer 3 — Secondary Indexes (block-level fast lookup)\n\n| Index         | Column(s)                  | Structure              | Complexity                         |\n| ------------- | -------------------------- | ---------------------- | ---------------------------------- |\n| `BitmapIndex` | `block_type`               | Inverted list per type | O(1) key + O(k) iterate            |\n| `BTreeIndex`  | `pre`, `post`              | `BTreeMap`             | O(log n) point, O(log n + k) range |\n| `HashIndex`   | `content`, `lang`, `depth` | `HashMap`              | O(1) average                       |\n\nSQL predicate pushdown picks an `IndexHint`:\n\n```mermaid\nflowchart TD\n    P[\"SQL WHERE predicate\"]\n    P --\u003e|\"block_type = '...'\"| B[\"BitmapIndex\"]\n    P --\u003e|\"pre = N\"| BT1[\"BTreeIndex (point)\"]\n    P --\u003e|\"pre BETWEEN N AND M\"| BT2[\"BTreeIndex (range)\"]\n    P --\u003e|\"content = '...'\"| H1[\"HashIndex\"]\n    P --\u003e|\"lang = '...'\"| H2[\"HashIndex\"]\n    P --\u003e|\"depth = N\"| H3[\"HashIndex\"]\n    P --\u003e|\"other\"| FS[\"Full Scan\"]\n```\n\n### Storage format\n\nCustom 8 KB page file:\n\n```mermaid\ngraph TD\n    P0[\"Page 0 — File Header\\nmagic 0x4D514442 · version · page count\"]\n    P1[\"Page 1 — Catalog\\ndoc_id → first_block_page · num_blocks · ZoneMaps\"]\n    P2[\"Page 2+ — Block Data\\nlinked page chains · overflow pages\"]\n\n    P0 --\u003e P1 --\u003e P2\n```\n\nWrites are atomic: data goes to `\u003cpath\u003e.tmp` then renamed to `\u003cpath\u003e` on success.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharehare%2Fmq-db","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharehare%2Fmq-db","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharehare%2Fmq-db/lists"}