diff --git a/Cargo.lock b/Cargo.lock index 42f27d1..6cd0527 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,12 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -91,7 +85,6 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "tantivy", "tempfile", "thiserror", "tokio", @@ -129,17 +122,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -204,12 +186,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "bincode" version = "2.0.1" @@ -236,15 +212,6 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" -[[package]] -name = "bitpacking" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a7139abd3d9cebf8cd6f920a389cf3dc9576172e32f4563f188cae3c3eb019" -dependencies = [ - "crunchy", -] - [[package]] name = "blake3" version = "1.8.5" @@ -268,43 +235,12 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bon" -version = "3.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47dbe92550676ee653353c310dfb9cf6ba17ee70396e1f7cf0a2020ad49b2fe" -dependencies = [ - "bon-macros", - "rustversion", -] - -[[package]] -name = "bon-macros" -version = "3.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519bd3116aeeb42d5372c29d982d16d0170d3d4a5ed85fc7dd91642ffff3c67c" -dependencies = [ - "darling", - "ident_case", - "prettyplease", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - [[package]] name = "bumpalo" version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.11.1" @@ -318,17 +254,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", - "jobserver", - "libc", "shlex", ] -[[package]] -name = "census" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" - [[package]] name = "cfg-if" version = "1.0.4" @@ -423,55 +351,12 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - [[package]] name = "crypto-common" version = "0.1.7" @@ -482,40 +367,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "darling" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" -dependencies = [ - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" -dependencies = [ - "darling_core", - "quote", - "syn", -] - [[package]] name = "dashmap" version = "6.1.0" @@ -530,16 +381,6 @@ dependencies = [ "parking_lot_core", ] -[[package]] -name = "deranged" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -dependencies = [ - "powerfmt", - "serde_core", -] - [[package]] name = "digest" version = "0.10.7" @@ -551,18 +392,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "downcast-rs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - [[package]] name = "equivalent" version = "1.0.2" @@ -579,12 +408,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "fastdivide" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afc2bd4d5a73106dd53d10d73d3401c2f32730ba2c0b93ddb888a8983680471" - [[package]] name = "fastrand" version = "2.4.1" @@ -609,12 +432,6 @@ dependencies = [ "spin", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "foldhash" version = "0.1.5" @@ -630,16 +447,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs4" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8640e34b88f7652208ce9e88b1a37a2ae95227d84abec377ccd3c5cfeb141ed4" -dependencies = [ - "rustix", - "windows-sys 0.59.0", -] - [[package]] name = "fsevent-sys" version = "4.1.0" @@ -664,17 +471,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" -[[package]] -name = "futures-macro" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "futures-sink" version = "0.3.32" @@ -694,7 +490,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", - "futures-macro", "futures-sink", "futures-task", "pin-project-lite", @@ -724,18 +519,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi 5.3.0", - "wasip2", -] - [[package]] name = "getrandom" version = "0.4.2" @@ -744,7 +527,7 @@ checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", - "r-efi 6.0.0", + "r-efi", "wasip2", "wasip3", ] @@ -761,8 +544,6 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "allocator-api2", - "equivalent", "foldhash", ] @@ -787,12 +568,6 @@ dependencies = [ "digest", ] -[[package]] -name = "htmlescape" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" - [[package]] name = "http" version = "1.4.0" @@ -910,15 +685,6 @@ dependencies = [ "tower-service", ] -[[package]] -name = "hyperloglogplus" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "621debdf94dcac33e50475fdd76d34d5ea9c0362a834b9db08c3024696c1fbe3" -dependencies = [ - "serde", -] - [[package]] name = "iana-time-zone" version = "0.1.65" @@ -949,12 +715,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "indexmap" version = "2.14.0" @@ -993,31 +753,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - [[package]] name = "js-sys" version = "0.3.98" @@ -1062,24 +803,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" -[[package]] -name = "levenshtein_automata" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" - [[package]] name = "libc" version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -1101,21 +830,6 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" -[[package]] -name = "lru" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown 0.15.5", -] - -[[package]] -name = "lz4_flex" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373f5eceeeab7925e0c1098212f2fbc4d416adec9d35051a6ab251e824c1854a" - [[package]] name = "matchers" version = "0.2.0" @@ -1131,42 +845,18 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" -[[package]] -name = "measure_time" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51c55d61e72fc3ab704396c5fa16f4c184db37978ae4e94ca8959693a235fc0e" -dependencies = [ - "log", -] - [[package]] name = "memchr" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" -[[package]] -name = "memmap2" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" -dependencies = [ - "libc", -] - [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "mio" version = "1.2.0" @@ -1179,12 +869,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "murmurhash32" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b" - [[package]] name = "nanorand" version = "0.7.0" @@ -1194,16 +878,6 @@ dependencies = [ "getrandom 0.2.17", ] -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "notify" version = "8.2.0" @@ -1240,12 +914,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "num-conv" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" - [[package]] name = "num-traits" version = "0.2.19" @@ -1253,7 +921,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -1268,21 +935,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "oneshot" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269bca4c2591a28585d6bf10d9ed0332b7d76900a1b02bec41bdc3a2cdcda107" - -[[package]] -name = "ownedbytes" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fbd56f7631767e61784dc43f8580f403f4475bd4aaa4da003e6295e1bab4a7e" -dependencies = [ - "stable_deref_trait", -] - [[package]] name = "parking_lot" version = "0.12.5" @@ -1331,27 +983,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "pkg-config" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - [[package]] name = "prettyplease" version = "0.2.37" @@ -1380,78 +1011,12 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - [[package]] name = "r-efi" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" -[[package]] -name = "rand" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "rand_distr" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" -dependencies = [ - "num-traits", - "rand", -] - -[[package]] -name = "rayon" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "redox_syscall" version = "0.5.18" @@ -1509,22 +1074,6 @@ dependencies = [ "serde", ] -[[package]] -name = "rust-stemmers" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" -dependencies = [ - "serde", - "serde_derive", -] - -[[package]] -name = "rustc-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" - [[package]] name = "rustix" version = "1.1.4" @@ -1686,15 +1235,6 @@ dependencies = [ "libc", ] -[[package]] -name = "sketches-ddsketch" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6f73aeb92d671e0cc4dca167e59b2deb6387c375391bc99ee743f326994a2b" -dependencies = [ - "serde", -] - [[package]] name = "slab" version = "0.4.12" @@ -1726,12 +1266,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - [[package]] name = "strsim" version = "0.11.1" @@ -1761,152 +1295,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -[[package]] -name = "tantivy" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502915c7381c5cb2d2781503962610cb880ad8f1a0ca95df1bae645d5ebf2545" -dependencies = [ - "aho-corasick", - "arc-swap", - "base64", - "bitpacking", - "bon", - "byteorder", - "census", - "crc32fast", - "crossbeam-channel", - "downcast-rs", - "fastdivide", - "fnv", - "fs4", - "htmlescape", - "hyperloglogplus", - "itertools", - "levenshtein_automata", - "log", - "lru", - "lz4_flex", - "measure_time", - "memmap2", - "once_cell", - "oneshot", - "rayon", - "regex", - "rust-stemmers", - "rustc-hash", - "serde", - "serde_json", - "sketches-ddsketch", - "smallvec", - "tantivy-bitpacker", - "tantivy-columnar", - "tantivy-common", - "tantivy-fst", - "tantivy-query-grammar", - "tantivy-stacker", - "tantivy-tokenizer-api", - "tempfile", - "thiserror", - "time", - "uuid", - "winapi", -] - -[[package]] -name = "tantivy-bitpacker" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3b04eed5108d8283607da6710fe17a7663523440eaf7ea5a1a440d19a1448b6" -dependencies = [ - "bitpacking", -] - -[[package]] -name = "tantivy-columnar" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b628488ae936c83e92b5c4056833054ca56f76c0e616aee8339e24ac89119cd" -dependencies = [ - "downcast-rs", - "fastdivide", - "itertools", - "serde", - "tantivy-bitpacker", - "tantivy-common", - "tantivy-sstable", - "tantivy-stacker", -] - -[[package]] -name = "tantivy-common" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f880aa7cab0c063a47b62596d10991cdd0b6e0e0575d9c5eeb298b307a25de55" -dependencies = [ - "async-trait", - "byteorder", - "ownedbytes", - "serde", - "time", -] - -[[package]] -name = "tantivy-fst" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d60769b80ad7953d8a7b2c70cdfe722bbcdcac6bccc8ac934c40c034d866fc18" -dependencies = [ - "byteorder", - "regex-syntax", - "utf8-ranges", -] - -[[package]] -name = "tantivy-query-grammar" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "768fccdc84d60d86235d42d7e4c33acf43c418258ff5952abf07bd7837fcd26b" -dependencies = [ - "nom", - "serde", - "serde_json", -] - -[[package]] -name = "tantivy-sstable" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8292095d1a8a2c2b36380ec455f910ab52dde516af36321af332c93f20ab7d5" -dependencies = [ - "futures-util", - "itertools", - "tantivy-bitpacker", - "tantivy-common", - "tantivy-fst", - "zstd", -] - -[[package]] -name = "tantivy-stacker" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d38a379411169f0b3002c9cba61cdfe315f757e9d4f239c00c282497a0749d" -dependencies = [ - "murmurhash32", - "rand_distr", - "tantivy-common", -] - -[[package]] -name = "tantivy-tokenizer-api" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23024f6aeb25ceb1a0e27740c84bdb0fae52626737b7e9a9de6ad5aa25c7b038" -dependencies = [ - "serde", -] - [[package]] name = "tempfile" version = "3.27.0" @@ -1949,37 +1337,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "time" -version = "0.3.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" - -[[package]] -name = "time-macros" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" -dependencies = [ - "num-conv", - "time-core", -] - [[package]] name = "tokio" version = "1.52.3" @@ -2157,30 +1514,12 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" -[[package]] -name = "utf8-ranges" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" - [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "1.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" -dependencies = [ - "getrandom 0.4.2", - "js-sys", - "serde_core", - "wasm-bindgen", -] - [[package]] name = "valuable" version = "0.1.1" @@ -2312,22 +1651,6 @@ dependencies = [ "semver", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.11" @@ -2337,12 +1660,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-core" version = "0.62.2" @@ -2402,22 +1719,13 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -2429,22 +1737,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - [[package]] name = "windows-targets" version = "0.53.5" @@ -2452,106 +1744,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - [[package]] name = "windows_aarch64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - [[package]] name = "windows_aarch64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - [[package]] name = "windows_i686_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - [[package]] name = "windows_i686_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - [[package]] name = "windows_i686_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - [[package]] name = "windows_x86_64_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - [[package]] name = "windows_x86_64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - [[package]] name = "windows_x86_64_msvc" version = "0.53.1" @@ -2652,56 +1896,8 @@ dependencies = [ "wasmparser", ] -[[package]] -name = "zerocopy" -version = "0.8.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" - -[[package]] -name = "zstd" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml index d33da55..ed408d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ regex = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" serde_yaml = "0.9" -tantivy = "0.25" thiserror = "2" tokio = { version = "1", features = ["full"] } tower = { version = "0.5", features = ["util"] } diff --git a/src/app.rs b/src/app.rs index cdd81f2..e99fb2b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -5,7 +5,7 @@ //! RootSupervisor (one_for_one) //! -- vault_scanner (permanent; startup walk + overflow recovery) //! -- filesystem_watcher (permanent; restart on inotify error) -//! -- index_writer (permanent; owns the Tantivy IndexWriter) +//! -- index_writer (permanent; owns the `NoteStore` write path) //! -- http_server (permanent; restart on bind loss) //! ``` //! @@ -38,7 +38,6 @@ use tokio::task::JoinHandle; use crate::health::HealthState; use crate::http::{self as http_layer, HttpState}; -use crate::index::NoteIndex; use crate::store::NoteStore; use crate::vault::{self, Note}; use crate::watcher::run_debouncer; @@ -145,17 +144,13 @@ impl Application for Anwesen { async fn start(&self) -> Result { // Startup order matters: `vault_scanner` casts a `Rebuild` to the - // `index_writer` name at the end of its init. Hydra start_link is + // `index_writer` name at the end of its init. Hydra `start_link` is // synchronous, so we put `index_writer` first to guarantee it is // registered and in its message loop before `vault_scanner` runs. // The `one_for_one` strategy makes the order irrelevant for restart - // semantics, only for the cold-start handshake. - // - // The cold-start handshake also relies on this order in the other - // direction: `index_writer.init` skips the `rescan_now` cast on its - // first init (`record_init() == 0`) because `vault_scanner` is - // about to run its own startup walk. Reordering these children - // would silently break that assumption -- so don't. + // semantics, only for the cold-start handshake. After ANW-23 the + // writer is restart-recoverable (NoteStore is owned by Anwesen and + // outlives the process), so no rescan handshake is needed on init. let children = [ IndexWriter { counters: self.counters.clone(), @@ -422,10 +417,8 @@ pub enum IndexWriterMessage { /// Discard the current index and reindex the given notes. Sent by /// `vault_scanner` at startup and after `rescan_now`. Rebuild(Vec), - /// Apply one debounce-window's worth of upserts and deletes in a single - /// Tantivy commit. Sent by `filesystem_watcher`. Picks up sie's ANW-12 - /// follow-up #3 (commit batching) before ANW-16's watcher can turn - /// per-save events into a hot commit loop. + /// Apply one debounce-window's worth of upserts and deletes against + /// [`NoteStore`] in a single write. Sent by `filesystem_watcher`. Batch(IndexBatch), /// Insert-or-replace one note. Retained for direct callers; the watcher /// uses `Batch`. @@ -461,26 +454,23 @@ impl IndexWriter { counters: counters.clone(), store: store.clone(), health: health.clone(), - index: None, } .start_link(GenServerOptions::new().name(INDEX_WRITER_NAME)) }) } } -/// Runtime state for the [`IndexWriter`] process. Held in a separate struct -/// so the `Clone`-friendly child-spec form (which doesn't carry the live -/// `NoteIndex`) stays simple. Mirrors every write into the shared -/// [`NoteStore`] so the HTTP layer can serve read-one and listing -/// responses without consulting the index. +/// Runtime state for the [`IndexWriter`] process. Post-[ANW-23] the +/// "index" name survives in the supervisor tree and `/health` per +/// [[ADR-009 Reverse ADR-002 In-Memory Evaluation No Tantivy]]'s naming +/// call, but the role is now purely a serialized writer into the shared +/// [`NoteStore`]. No on-process state survives a restart -- `NoteStore` +/// is owned by `Anwesen` and outlives writer restarts, so no rescan +/// handshake is needed on init. pub(crate) struct IndexWriterState { counters: Arc, store: Arc, health: Arc, - /// Created lazily in `init` so a Tantivy construction failure surfaces - /// as an `ExitReason` and triggers a supervisor restart, rather than - /// poisoning the child spec. - index: Option, } impl GenServer for IndexWriterState { @@ -488,70 +478,28 @@ impl GenServer for IndexWriterState { async fn init(&mut self) -> Result<(), ExitReason> { let restart = self.counters.index_writer.record_init(); - let index = NoteIndex::new() - .map_err(|e| ExitReason::from(format!("index_writer: NoteIndex::new failed: {e}")))?; - self.index = Some(index); - - if restart > 0 { - // Writer-only restart: a fresh empty index has come up while the - // watcher keeps streaming batches at it. Ask `vault_scanner` for - // a full walk via the same `rescan_now` path the inotify-overflow - // recovery uses. Per kaa's pin (ADR-004 amendment 2026-05-14), - // rescan upserts are idempotent on path so in-flight watcher - // batches converge with the rescan. - VaultScanner::cast( - Dest::from(VAULT_SCANNER_NAME), - VaultScannerMessage::RescanNow, - ); - tracing::info!( - restart, - "index_writer: init -- rescan_now dispatched to vault_scanner" - ); - } else { - tracing::info!(restart, "index_writer: init"); - } + tracing::info!(restart, "index_writer: init"); Ok(()) } async fn handle_cast(&mut self, message: Self::Message) -> Result<(), ExitReason> { - let Some(index) = self.index.as_mut() else { - return Err(ExitReason::from( - "index_writer: handle_cast invoked before init", - )); - }; match message { IndexWriterMessage::Rebuild(notes) => { let count = notes.len(); - if let Err(e) = index.rebuild(¬es) { - tracing::error!(error = %e, "index_writer: rebuild failed"); - return Err(ExitReason::from(format!("rebuild: {e}"))); - } self.store.replace(notes); - tracing::info!(notes = count, "index_writer: rebuilt"); + tracing::info!(notes = count, "index_writer: rebuilt store"); } IndexWriterMessage::Batch(batch) => { let (u, d) = (batch.upserts.len(), batch.deletes.len()); - if let Err(e) = index.apply_batch(&batch.upserts, &batch.deletes) { - tracing::error!(error = %e, "index_writer: batch apply failed"); - return Err(ExitReason::from(format!("batch: {e}"))); - } self.store.apply_batch(batch.upserts, &batch.deletes); tracing::info!(upserts = u, deletes = d, "index_writer: batch applied"); } IndexWriterMessage::Upsert(note) => { let path = note.path.clone(); - if let Err(e) = index.upsert(¬e) { - tracing::error!(%path, error = %e, "index_writer: upsert failed"); - return Err(ExitReason::from(format!("upsert {path}: {e}"))); - } self.store.upsert(*note); tracing::debug!(%path, "index_writer: upserted"); } IndexWriterMessage::Delete(path) => { - if let Err(e) = index.delete(&path) { - tracing::error!(%path, error = %e, "index_writer: delete failed"); - return Err(ExitReason::from(format!("delete {path}: {e}"))); - } self.store.delete(&path); tracing::debug!(%path, "index_writer: deleted"); } diff --git a/src/index.rs b/src/index.rs deleted file mode 100644 index 2006f73..0000000 --- a/src/index.rs +++ /dev/null @@ -1,269 +0,0 @@ -//! In-memory Tantivy index over note frontmatter. -//! -//! Implements [[ADR-002 Tantivy as Frontmatter Index]] + the ANW-12 schema: -//! -//! - one `json` field (`frontmatter`) with the `raw` tokenizer pinned for v1 -//! (exact-match semantics on every key, matches the keyword-style operator -//! surface in the User Manual); -//! - one `string` field (`path`) with the `raw` tokenizer (exact lookup + -//! anchored prefix queries). -//! -//! The index lives in a [`RamDirectory`](tantivy::directory::RamDirectory) -- -//! rebuilt at startup from the scanner output and maintained incrementally -//! by [`upsert`](NoteIndex::upsert) / [`delete`](NoteIndex::delete) calls -//! driven from the filesystem watcher in [ANW-16]. - -use anyhow::{Context, Result}; -use serde_json::json; -use tantivy::schema::{Field, IndexRecordOption, Schema, TextFieldIndexing, TextOptions}; -use tantivy::{Index, IndexWriter, TantivyDocument, Term}; - -use crate::vault::{Note, frontmatter_to_json}; - -/// 50 MB heap for the writer. Tantivy's documented minimum is 15 MB; this -/// sits comfortably above that for low-thousands-of-notes vaults without -/// bloating idle memory. -const WRITER_HEAP_BYTES: usize = 50 * 1024 * 1024; - -/// Strongly-typed handle to the two schema fields. Carried alongside the -/// [`Index`] so call sites don't restring field names. -#[derive(Debug, Clone, Copy)] -pub struct Fields { - pub path: Field, - pub frontmatter: Field, -} - -/// The in-memory note index. Owns the [`Index`] and a long-lived -/// [`IndexWriter`]; one `NoteIndex` per daemon. -pub struct NoteIndex { - fields: Fields, - index: Index, - writer: IndexWriter, -} - -impl NoteIndex { - /// Construct an empty in-memory index with the pinned v1 schema. - /// - /// # Errors - /// Returns the underlying Tantivy error if writer allocation fails (the - /// only failure mode reachable for a fresh `RamDirectory`). - pub fn new() -> Result { - let mut schema_builder = Schema::builder(); - - let raw_indexing = TextFieldIndexing::default() - .set_tokenizer("raw") - .set_index_option(IndexRecordOption::Basic); - - let path_options = TextOptions::default() - .set_indexing_options(raw_indexing.clone()) - .set_stored(); - - let path = schema_builder.add_text_field("path", path_options); - - // JSON field: open-schema frontmatter. `raw` tokenizer pins exact-match - // semantics on every key, per the open question closed in - // [[ADR-002 Tantivy as Frontmatter Index]]. - let json_options = tantivy::schema::JsonObjectOptions::default() - .set_indexing_options(raw_indexing) - .set_stored(); - let frontmatter = schema_builder.add_json_field("frontmatter", json_options); - - let schema = schema_builder.build(); - let index = Index::create_in_ram(schema); - let writer: IndexWriter = index - .writer(WRITER_HEAP_BYTES) - .context("create tantivy writer")?; - - Ok(Self { - fields: Fields { path, frontmatter }, - index, - writer, - }) - } - - /// Discard every document and reindex the given notes. Used at startup - /// and during overflow recovery per [[ADR-003 Filesystem Change Tracking]]. - /// - /// # Errors - /// Returns the underlying Tantivy error if any add/commit fails. - pub fn rebuild(&mut self, notes: &[Note]) -> Result<()> { - self.writer - .delete_all_documents() - .context("delete_all_documents")?; - for note in notes { - self.add_document(note)?; - } - self.writer.commit().context("commit rebuild")?; - Ok(()) - } - - /// Insert-or-replace one note by path. Subsequent reads through a fresh - /// reader will see the new content after this call returns. - /// - /// # Errors - /// Returns the underlying Tantivy error if the add or commit fails. - pub fn upsert(&mut self, note: &Note) -> Result<()> { - self.writer.delete_term(self.path_term(¬e.path)); - self.add_document(note)?; - self.writer.commit().context("commit upsert")?; - Ok(()) - } - - /// Drop one note by path. No-op (still commits) if the path was never - /// indexed; callers can call freely on delete-events. - /// - /// # Errors - /// Returns the underlying Tantivy error if the commit fails. - pub fn delete(&mut self, path: &str) -> Result<()> { - self.writer.delete_term(self.path_term(path)); - self.writer.commit().context("commit delete")?; - Ok(()) - } - - /// Apply a batch of upserts and deletes in one Tantivy commit. The - /// watcher's debouncer dispatches batches per debounce window so a busy - /// editor save loop does not produce one commit per event. - /// - /// # Errors - /// Returns the underlying Tantivy error if any add or the final commit - /// fails. - pub fn apply_batch(&mut self, upserts: &[Note], deletes: &[String]) -> Result<()> { - for path in deletes { - self.writer.delete_term(self.path_term(path)); - } - for note in upserts { - self.writer.delete_term(self.path_term(¬e.path)); - self.add_document(note)?; - } - self.writer.commit().context("commit batch")?; - Ok(()) - } - - /// Number of indexed documents from a fresh reader. Read-only; intended - /// for tests and the `/health` endpoint ([ANW-8]). - /// - /// # Errors - /// Returns the underlying Tantivy error if opening the reader fails. - pub fn document_count(&self) -> Result { - let reader = self.index.reader().context("open reader")?; - let searcher = reader.searcher(); - Ok(searcher.num_docs()) - } - - /// Expose the [`Index`] so other layers (the future query handler in - /// [ANW-15]) can build their own readers and parsers without re-deriving - /// the schema. - #[must_use] - pub fn index(&self) -> &Index { - &self.index - } - - #[must_use] - pub fn fields(&self) -> Fields { - self.fields - } - - fn path_term(&self, path: &str) -> Term { - Term::from_field_text(self.fields.path, path) - } - - fn add_document(&mut self, note: &Note) -> Result<()> { - // Build the doc as JSON keyed by schema field name and let Tantivy - // parse it -- avoids restating the OwnedValue tree by hand. - let doc_json = json!({ - "path": ¬e.path, - "frontmatter": frontmatter_to_json(¬e.frontmatter), - }); - let doc = TantivyDocument::parse_json(&self.index.schema(), &doc_json.to_string()) - .context("parse_json")?; - self.writer.add_document(doc).context("add_document")?; - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use chrono::{TimeZone, Utc}; - use std::collections::BTreeMap; - use tantivy::collector::TopDocs; - use tantivy::query::TermQuery; - - use crate::vault::Value; - - fn sample_note(path: &str, tag: &str) -> Note { - let mut fm: BTreeMap = BTreeMap::new(); - fm.insert( - "tags".into(), - Value::Sequence(vec![Value::String(tag.into())]), - ); - fm.insert("title".into(), Value::String(format!("note {path}"))); - Note { - path: path.into(), - frontmatter: fm, - body: String::new(), - raw_bytes: Vec::new(), - last_modified: Utc.with_ymd_and_hms(2026, 5, 14, 12, 0, 0).unwrap(), - etag: "\"deadbeef\"".into(), - size: 0, - } - } - - fn count_path(idx: &NoteIndex, path: &str) -> tantivy::Result { - let reader = idx.index().reader()?; - let searcher = reader.searcher(); - let term = Term::from_field_text(idx.fields().path, path); - let query = TermQuery::new(term, IndexRecordOption::Basic); - let hits = searcher.search(&query, &TopDocs::with_limit(10))?; - Ok(hits.len()) - } - - #[test] - fn rebuild_populates_index() { - let mut idx = NoteIndex::new().unwrap(); - idx.rebuild(&[sample_note("a.md", "x"), sample_note("b.md", "y")]) - .unwrap(); - assert_eq!(idx.document_count().unwrap(), 2); - assert_eq!(count_path(&idx, "a.md").unwrap(), 1); - assert_eq!(count_path(&idx, "b.md").unwrap(), 1); - } - - #[test] - fn rebuild_replaces_previous_contents() { - let mut idx = NoteIndex::new().unwrap(); - idx.rebuild(&[sample_note("old.md", "x")]).unwrap(); - idx.rebuild(&[sample_note("new.md", "y")]).unwrap(); - assert_eq!(idx.document_count().unwrap(), 1); - assert_eq!(count_path(&idx, "old.md").unwrap(), 0); - assert_eq!(count_path(&idx, "new.md").unwrap(), 1); - } - - #[test] - fn upsert_replaces_by_path() { - let mut idx = NoteIndex::new().unwrap(); - idx.upsert(&sample_note("a.md", "v1")).unwrap(); - // Mutate then upsert under the same path; document count must stay 1. - idx.upsert(&sample_note("a.md", "v2")).unwrap(); - assert_eq!(idx.document_count().unwrap(), 1); - assert_eq!(count_path(&idx, "a.md").unwrap(), 1); - } - - #[test] - fn delete_removes_path() { - let mut idx = NoteIndex::new().unwrap(); - idx.upsert(&sample_note("a.md", "x")).unwrap(); - idx.upsert(&sample_note("b.md", "y")).unwrap(); - idx.delete("a.md").unwrap(); - assert_eq!(idx.document_count().unwrap(), 1); - assert_eq!(count_path(&idx, "a.md").unwrap(), 0); - assert_eq!(count_path(&idx, "b.md").unwrap(), 1); - } - - #[test] - fn delete_unknown_path_is_noop() { - let mut idx = NoteIndex::new().unwrap(); - idx.upsert(&sample_note("a.md", "x")).unwrap(); - idx.delete("never-indexed.md").unwrap(); - assert_eq!(idx.document_count().unwrap(), 1); - } -} diff --git a/src/lib.rs b/src/lib.rs index d068d0f..2fa823f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,15 @@ //! Anwesen: read-only HTTP daemon over a markdown vault. //! //! The binary in `main.rs` wires this library to a CLI; submodules implement -//! the vault scanner, the Tantivy index, the filesystem watcher, the -//! supervisor tree, and the HTTP surface as those issues land. +//! the vault scanner, the in-memory note store, the filesystem watcher, the +//! supervisor tree, and the HTTP surface. See +//! [[ADR-009 Reverse ADR-002 In-Memory Evaluation No Tantivy]] for why v1 +//! ships without a search index. pub mod app; pub mod doctor; pub mod health; pub mod http; -pub mod index; pub mod query; pub mod store; pub mod vault; diff --git a/src/query.rs b/src/query.rs index 7fb24da..517a6ed 100644 --- a/src/query.rs +++ b/src/query.rs @@ -10,13 +10,11 @@ //! Different field predicates AND together; multiple values under //! `__in` / `__all` are comma-separated; unknown operators are `400`. //! -//! v1 evaluates predicates by iterating the in-memory [`NoteStore`] and -//! applying each [`Predicate::matches`] in turn. The Tantivy index from -//! [[ADR-002 Tantivy as Frontmatter Index]] is still built and maintained, -//! but query-time filtering doesn't use it yet. At the documented scale -//! (low-thousands-of-notes vaults) this is sub-millisecond; migration to a -//! Tantivy-driven candidate set is a future optimization once a real -//! consumer pushes throughput. +//! Predicates are evaluated by iterating the in-memory [`NoteStore`] and +//! applying each [`Predicate::matches`] in turn. At the documented scale +//! (low-thousands-of-notes vaults) this is sub-millisecond; see +//! [[ADR-009 Reverse ADR-002 In-Memory Evaluation No Tantivy]] for the +//! call to keep evaluation in-memory rather than carrying a Tantivy index. use chrono::{DateTime, NaiveDate}; use regex::Regex; diff --git a/src/store.rs b/src/store.rs index 6c7bfdd..7e63fb2 100644 --- a/src/store.rs +++ b/src/store.rs @@ -3,10 +3,10 @@ //! HTTP layer ([ANW-13] / [ANW-14] / [ANW-15]) for read-one and listing //! responses. //! -//! Per [[ADR-002 Tantivy as Frontmatter Index]] / [ANW-11], the daemon -//! rereads from disk only on a watcher event for that path. The store is -//! that in-memory cache; the index in [`crate::index`] sits beside it, -//! shaped for frontmatter queries rather than full-record retrieval. +//! Per [ANW-11], the daemon rereads from disk only on a watcher event for +//! that path; this store is that in-memory cache and -- per +//! [[ADR-009 Reverse ADR-002 In-Memory Evaluation No Tantivy]] -- the sole +//! authoritative record set both `/notes` and `/query` read from. use std::collections::BTreeMap; use std::sync::{Arc, RwLock}; diff --git a/src/vault.rs b/src/vault.rs index 00eb831..d78802a 100644 --- a/src/vault.rs +++ b/src/vault.rs @@ -99,7 +99,7 @@ impl Value { } /// Convert a whole [`Frontmatter`] tree to a [`serde_json::Value`] object -/// suitable for HTTP responses or for Tantivy ingestion. +/// suitable for HTTP responses. #[must_use] pub fn frontmatter_to_json(fm: &Frontmatter) -> JsonValue { let mut map = JsonMap::new(); diff --git a/src/watcher.rs b/src/watcher.rs index b8913e3..e197ed3 100644 --- a/src/watcher.rs +++ b/src/watcher.rs @@ -5,8 +5,7 @@ //! pushed into a Tokio channel; [`run_debouncer`] drains the channel, //! classifies events into [`WatchAction`]s, coalesces a 100 ms window's //! worth into one [`Batch`], and casts the batch to the `index_writer` -//! named process for a single Tantivy commit (folds in sie's ANW-12 -//! follow-up #3). +//! named process for a single [`crate::store::NoteStore`] write. //! //! See [[ADR-003 Filesystem Change Tracking]] for the event model.