diff options
| author | metamuffin <metamuffin@disroot.org> | 2025-12-15 15:09:37 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2025-12-15 15:09:37 +0100 |
| commit | 0e48299889c3c2b81bf351ffe5da71e0bcd4c22a (patch) | |
| tree | 8a7ff2bd2330c206070b2062723ba471b2d62544 | |
| parent | 7552a4ff0e027334398d28d5687a339ad77c0871 (diff) | |
| download | jellything-0e48299889c3c2b81bf351ffe5da71e0bcd4c22a.tar jellything-0e48299889c3c2b81bf351ffe5da71e0bcd4c22a.tar.bz2 jellything-0e48299889c3c2b81bf351ffe5da71e0bcd4c22a.tar.zst | |
db
| -rw-r--r-- | Cargo.lock | 412 | ||||
| -rw-r--r-- | database/Cargo.toml | 1 | ||||
| -rw-r--r-- | database/src/backends/memory.rs | 13 | ||||
| -rw-r--r-- | database/src/backends/mod.rs | 5 | ||||
| -rw-r--r-- | database/src/backends/redb.rs | 19 | ||||
| -rw-r--r-- | database/src/backends/rocksdb.rs | 19 | ||||
| -rw-r--r-- | database/src/indices/mod.rs | 19 | ||||
| -rw-r--r-- | database/src/indices/order.rs | 49 | ||||
| -rw-r--r-- | database/src/lib.rs | 513 | ||||
| -rw-r--r-- | database/src/search.rs | 64 | ||||
| -rw-r--r-- | server/Cargo.toml | 2 |
11 files changed, 151 insertions, 965 deletions
@@ -102,12 +102,6 @@ dependencies = [ ] [[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -188,12 +182,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - -[[package]] name = "arg_enum_proc_macro" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -420,15 +408,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] -name = "bitpacking" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c1d3e2bfd8d06048a179f7b17afc3188effa10385e7b00dc65af6aae732ea92" -dependencies = [ - "crunchy", -] - -[[package]] name = "bitstream-io" version = "4.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -469,31 +448,6 @@ dependencies = [ ] [[package]] -name = "bon" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebeb9aaf9329dff6ceb65c689ca3db33dbf15f324909c60e4e5eef5701ce31b1" -dependencies = [ - "bon-macros", - "rustversion", -] - -[[package]] -name = "bon-macros" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e9d642a7e3a318e37c2c9427b5a6a48aa1ad55dcd986f3034ab2239045a645" -dependencies = [ - "darling", - "ident_case", - "prettyplease", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[package]] name = "built" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -552,12 +506,6 @@ dependencies = [ ] [[package]] -name = "census" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" - -[[package]] name = "cexpr" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -870,7 +818,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", - "serde_core", ] [[package]] @@ -942,12 +889,6 @@ dependencies = [ ] [[package]] -name = "downcast-rs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" - -[[package]] name = "ebml" version = "0.1.0" source = "git+https://codeberg.org/metamuffin/ebml-rs#1535ae503f67b82d8a08d2c2787156f5bd4ffbba" @@ -1069,12 +1010,6 @@ dependencies = [ ] [[package]] -name = "fastdivide" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afc2bd4d5a73106dd53d10d73d3401c2f32730ba2c0b93ddb888a8983680471" - -[[package]] name = "fastrand" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1146,12 +1081,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] name = "form_urlencoded" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1161,16 +1090,6 @@ dependencies = [ ] [[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 = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1382,17 +1301,6 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - -[[package]] -name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" @@ -1434,12 +1342,6 @@ dependencies = [ ] [[package]] -name = "htmlescape" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" - -[[package]] name = "http" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1602,15 +1504,6 @@ dependencies = [ ] [[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.64" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1807,7 +1700,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown", "serde", "serde_core", ] @@ -1947,7 +1840,6 @@ dependencies = [ "rocksdb", "serde", "serde_json", - "tantivy", ] [[package]] @@ -2067,7 +1959,7 @@ dependencies = [ "rocket_ws", "serde", "serde_json", - "serde_yml", + "serde_yaml_ng", "tokio", "tokio-util", ] @@ -2186,12 +2078,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] -name = "levenshtein_automata" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" - -[[package]] name = "libavif" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2278,16 +2164,6 @@ dependencies = [ ] [[package]] -name = "libyml" -version = "0.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980" -dependencies = [ - "anyhow", - "version_check", -] - -[[package]] name = "libz-sys" version = "1.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2350,15 +2226,6 @@ dependencies = [ ] [[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 = "lru-slab" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2375,12 +2242,6 @@ dependencies = [ ] [[package]] -name = "lz4_flex" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a" - -[[package]] name = "markup" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2445,30 +2306,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[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.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] -name = "memmap2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" -dependencies = [ - "libc", -] - -[[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2531,12 +2374,6 @@ dependencies = [ ] [[package]] -name = "murmurhash32" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b" - -[[package]] name = "nalgebra" version = "0.32.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2715,12 +2552,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] -name = "oneshot" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce411919553d3f9fa53a0880544cda985a112117a0444d5ff1e870a893d6ea" - -[[package]] name = "opaque-debug" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2736,15 +2567,6 @@ dependencies = [ ] [[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 = "owning_ref" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2933,16 +2755,6 @@ dependencies = [ ] [[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] name = "proc-macro2" version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3494,16 +3306,6 @@ dependencies = [ ] [[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.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3668,18 +3470,16 @@ dependencies = [ ] [[package]] -name = "serde_yml" -version = "0.0.12" +name = "serde_yaml_ng" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" +checksum = "7b4db627b98b36d4203a7b458cf3573730f2bb591b28871d916dfa9efabfd41f" dependencies = [ "indexmap", "itoa", - "libyml", - "memchr", "ryu", "serde", - "version_check", + "unsafe-libyaml", ] [[package]] @@ -3763,15 +3563,6 @@ dependencies = [ ] [[package]] -name = "sketches-ddsketch" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" -dependencies = [ - "serde", -] - -[[package]] name = "slab" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3886,152 +3677,6 @@ dependencies = [ ] [[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 0.14.0", - "levenshtein_automata", - "log", - "lru", - "lz4_flex", - "measure_time", - "memmap2", - "once_cell", - "oneshot", - "rayon", - "regex", - "rust-stemmers", - "rustc-hash", - "serde", - "serde_json", - "sketches-ddsketch", - "smallvec 1.15.1", - "tantivy-bitpacker", - "tantivy-columnar", - "tantivy-common", - "tantivy-fst", - "tantivy-query-grammar", - "tantivy-stacker", - "tantivy-tokenizer-api", - "tempfile", - "thiserror 2.0.17", - "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 0.14.0", - "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 7.1.3", - "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 0.14.0", - "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.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4517,12 +4162,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] -name = "utf8-ranges" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" - -[[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4535,18 +4174,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] -name = "uuid" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" -dependencies = [ - "getrandom 0.3.4", - "js-sys", - "serde_core", - "wasm-bindgen", -] - -[[package]] name = "v_frame" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4819,15 +4446,6 @@ dependencies = [ [[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" @@ -5170,24 +4788,6 @@ dependencies = [ ] [[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" diff --git a/database/Cargo.toml b/database/Cargo.toml index eeeee7f..7e79b92 100644 --- a/database/Cargo.toml +++ b/database/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2024" [dependencies] -tantivy = "0.25.0" jellycommon = { path = "../common" } serde = { version = "1.0.228", features = ["derive"] } log = { workspace = true } diff --git a/database/src/backends/memory.rs b/database/src/backends/memory.rs index 97c8c2c..2f19ce6 100644 --- a/database/src/backends/memory.rs +++ b/database/src/backends/memory.rs @@ -4,13 +4,18 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ -use crate::backends::DatabaseStorage; +use crate::backends::KV; use anyhow::Result; use std::{collections::BTreeMap, sync::RwLock}; pub struct Memory(RwLock<BTreeMap<Vec<u8>, Vec<u8>>>); -impl DatabaseStorage for Memory { +impl Memory { + pub fn new() -> Self { + Self(RwLock::new(BTreeMap::new())) + } +} +impl KV for Memory { fn set(&self, key: &[u8], value: &[u8]) -> Result<()> { self.0.write().unwrap().insert(key.to_vec(), value.to_vec()); Ok(()) @@ -18,6 +23,10 @@ impl DatabaseStorage for Memory { fn get<'a>(&'a self, key: &[u8]) -> Result<Option<Vec<u8>>> { Ok(self.0.read().unwrap().get(key).cloned()) } + fn del(&self, key: &[u8]) -> Result<()> { + self.0.write().unwrap().remove(key); + Ok(()) + } fn next(&self, key: &[u8]) -> Result<Option<Vec<u8>>> { let r = self.0.read().unwrap(); Ok(r.range(key.to_vec()..).next().map(|(k, _)| k.to_owned())) diff --git a/database/src/backends/mod.rs b/database/src/backends/mod.rs index 1240ac1..b6d3770 100644 --- a/database/src/backends/mod.rs +++ b/database/src/backends/mod.rs @@ -4,15 +4,16 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ +pub mod memory; pub mod redb; pub mod rocksdb; -pub mod memory; use anyhow::Result; -pub trait DatabaseStorage { +pub trait KV { fn set(&self, key: &[u8], value: &[u8]) -> Result<()>; fn get<'a>(&'a self, key: &[u8]) -> Result<Option<Vec<u8>>>; + fn del(&self, key: &[u8]) -> Result<()>; fn next(&self, key: &[u8]) -> Result<Option<Vec<u8>>>; fn prev(&self, key: &[u8]) -> Result<Option<Vec<u8>>>; } diff --git a/database/src/backends/redb.rs b/database/src/backends/redb.rs index 39fe532..1b672b6 100644 --- a/database/src/backends/redb.rs +++ b/database/src/backends/redb.rs @@ -4,7 +4,9 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ -use crate::backends::DatabaseStorage; +use std::path::Path; + +use crate::backends::KV; use anyhow::Result; use redb::{Database, ReadableDatabase, TableDefinition}; @@ -14,13 +16,26 @@ pub struct Redb { const TABLE: TableDefinition<&[u8], &[u8]> = TableDefinition::new("kv"); -impl DatabaseStorage for Redb { +impl Redb { + pub fn new(path: &Path) -> Result<Self> { + Ok(Self { + db: Database::create(path)?, + }) + } +} +impl KV for Redb { fn set(&self, key: &[u8], value: &[u8]) -> Result<()> { let txn = self.db.begin_write()?; txn.open_table(TABLE)?.insert(key, value)?; txn.commit()?; Ok(()) } + fn del(&self, key: &[u8]) -> Result<()> { + let txn = self.db.begin_write()?; + txn.open_table(TABLE)?.remove(key)?; + txn.commit()?; + Ok(()) + } fn get<'a>(&'a self, key: &[u8]) -> Result<Option<Vec<u8>>> { let txn = self.db.begin_read()?; match txn.open_table(TABLE)?.get(key)? { diff --git a/database/src/backends/rocksdb.rs b/database/src/backends/rocksdb.rs index 7c6f5f3..f4ed55b 100644 --- a/database/src/backends/rocksdb.rs +++ b/database/src/backends/rocksdb.rs @@ -4,7 +4,9 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ -use crate::backends::DatabaseStorage; +use std::path::Path; + +use crate::backends::KV; use anyhow::Result; use rocksdb::DB; @@ -12,14 +14,23 @@ pub struct Rocksdb { db: DB, } -impl DatabaseStorage for Rocksdb { +impl Rocksdb { + pub fn new(path: &Path) -> Result<Self> { + Ok(Self { + db: DB::open_default(path)?, + }) + } +} +impl KV for Rocksdb { fn set(&self, key: &[u8], value: &[u8]) -> Result<()> { - self.db.put(key, value)?; - Ok(()) + Ok(self.db.put(key, value)?) } fn get<'a>(&'a self, key: &[u8]) -> Result<Option<Vec<u8>>> { Ok(self.db.get(key)?) } + fn del(&self, key: &[u8]) -> Result<()> { + Ok(self.db.delete(key)?) + } fn next(&self, key: &[u8]) -> Result<Option<Vec<u8>>> { let mut it = self.db.raw_iterator(); it.seek_for_prev(key); diff --git a/database/src/indices/mod.rs b/database/src/indices/mod.rs new file mode 100644 index 0000000..48e91a9 --- /dev/null +++ b/database/src/indices/mod.rs @@ -0,0 +1,19 @@ +/* + This file is part of jellything (https://codeberg.org/metamuffin/jellything) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2025 metamuffin <metamuffin.org> +*/ + +use crate::backends::KV; +use anyhow::Result; + +pub mod order; + +pub trait Index<T> { + fn add(&self, db: &dyn KV, id: u64, val: &T) -> Result<()>; + fn remove(&self, db: &dyn KV, id: u64, val: &T) -> Result<()>; + fn compare(&self, before: &T, after: &T) -> bool { + let _ = (before, after); + true + } +} diff --git a/database/src/indices/order.rs b/database/src/indices/order.rs new file mode 100644 index 0000000..852342d --- /dev/null +++ b/database/src/indices/order.rs @@ -0,0 +1,49 @@ +/* + This file is part of jellything (https://codeberg.org/metamuffin/jellything) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2025 metamuffin <metamuffin.org> +*/ + +use crate::{Table, backends::KV, indices::Index}; +use anyhow::Result; +use std::sync::Arc; + +pub struct OrderIndex<T> { + id: u32, + value: fn(&T) -> [u8; 8], + db: Arc<dyn KV>, +} +impl<T: 'static> OrderIndex<T> { + pub fn new(table: &mut Table<T>, id: u32, value: fn(&T) -> [u8; 8]) -> Self { + table.indices.push(Box::new(Self { + id, + value, + db: table.db.clone(), + })); + Self { + id, + value, + db: table.db.clone(), + } + } + fn key(&self, id: u64, val: &T) -> Vec<u8> { + let mut key = Vec::new(); + key.extend(self.id.to_be_bytes()); + key.extend((self.value)(val)); + key.extend(id.to_be_bytes()); + key + } +} +impl<T: 'static> Index<T> for OrderIndex<T> { + fn add(&self, db: &dyn KV, id: u64, val: &T) -> Result<()> { + db.set(&self.key(id, val), &[])?; + Ok(()) + } + fn remove(&self, db: &dyn KV, id: u64, val: &T) -> Result<()> { + db.del(&self.key(id, val))?; + Ok(()) + } + fn compare(&self, before: &T, after: &T) -> bool { + (self.value)(before) == (self.value)(after) + } +} diff --git a/database/src/lib.rs b/database/src/lib.rs index 0e89873..828761e 100644 --- a/database/src/lib.rs +++ b/database/src/lib.rs @@ -3,499 +3,46 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin <metamuffin.org> */ -pub mod search; -use anyhow::{Context, Result, anyhow, bail}; -use jellycommon::{ - IdentifierType, Node, NodeID, - user::{NodeUserData, User}, -}; -use log::info; -use redb::{Durability, ReadableDatabase, ReadableTable, StorageError, TableDefinition}; -use search::NodeTextSearchIndex; -use serde::{Serialize, de::DeserializeOwned}; -use std::{ - fs::create_dir_all, - path::{Path, PathBuf}, - str::FromStr, - sync::Arc, - time::SystemTime, -}; -use tantivy::{ - DateTime, TantivyDocument, - collector::{Count, TopDocs}, - doc, - query::QueryParser, - schema::Value, +use anyhow::{Result, bail}; + +use crate::{ + backends::{KV, memory::Memory, redb::Redb, rocksdb::Rocksdb}, + indices::Index, }; +use std::{path::Path, sync::Arc}; -const T_USER: TableDefinition<&str, Ser<User>> = TableDefinition::new("user"); -const T_USER_NODE: TableDefinition<(&str, [u8; 32]), Ser<NodeUserData>> = - TableDefinition::new("user_node"); -const T_INVITE: TableDefinition<&str, ()> = TableDefinition::new("invite"); -const T_NODE: TableDefinition<[u8; 32], Ser<Node>> = TableDefinition::new("node"); -const T_NODE_CHILDREN: TableDefinition<([u8; 32], [u8; 32]), ()> = - TableDefinition::new("node_children"); -const T_TAG_NODE: TableDefinition<(&str, [u8; 32]), ()> = TableDefinition::new("tag_node"); -const T_NODE_IDENTIFIER: TableDefinition<(u8, &str), [u8; 32]> = TableDefinition::new("node_ids"); -const T_IMPORT_FILE_MTIME: TableDefinition<&[u8], u64> = TableDefinition::new("import_file_mtime"); -const T_NODE_MTIME: TableDefinition<[u8; 32], u64> = TableDefinition::new("node_mtime"); -const T_NODE_MEDIA_PATHS: TableDefinition<([u8; 32], &str), ()> = - TableDefinition::new("node_media_paths"); +pub mod backends; +pub mod indices; -#[derive(Clone)] pub struct Database { - inner: Arc<redb::Database>, - text_search: Arc<NodeTextSearchIndex>, + storage: Arc<dyn KV>, } impl Database { - pub fn open(path: &Path) -> Result<Self, anyhow::Error> { - create_dir_all(path).context("creating database directory")?; - info!("opening kv store..."); - let db = redb::Database::create(path.join("data")).context("opening kv store")?; - info!("opening node index..."); - let ft_node = NodeTextSearchIndex::new(path).context("in node index")?; - let r = Self { - inner: db.into(), - text_search: ft_node.into(), - }; - - { - // this creates all tables such that read operations on them do not fail. - let txn = r.inner.begin_write()?; - txn.open_table(T_INVITE)?; - txn.open_table(T_USER)?; - txn.open_table(T_USER_NODE)?; - txn.open_table(T_NODE)?; - txn.open_table(T_NODE_MTIME)?; - txn.open_table(T_NODE_CHILDREN)?; - txn.open_table(T_NODE_IDENTIFIER)?; - txn.open_table(T_NODE_MEDIA_PATHS)?; - txn.open_table(T_IMPORT_FILE_MTIME)?; - txn.commit()?; - } - - info!("ready"); - Ok(r) - } - - pub fn get_node_slug(&self, slug: &str) -> Result<Option<Arc<Node>>> { - self.get_node(NodeID::from_slug(slug)) - } - - pub fn get_node(&self, id: NodeID) -> Result<Option<Arc<Node>>> { - let txn = self.inner.begin_read()?; - let t_node = txn.open_table(T_NODE)?; - if let Some(node) = t_node.get(id.0)? { - Ok(Some(node.value().0.into())) - } else { - Ok(None) - } - } - pub fn get_node_by_identifier( - &self, - ty: IdentifierType, - value: &str, - ) -> Result<Option<NodeID>> { - let txn = self.inner.begin_read()?; - let t_node_external_id = txn.open_table(T_NODE_IDENTIFIER)?; - if let Some(id) = t_node_external_id.get((ty as u8, value))? { - Ok(Some(NodeID(id.value()))) - } else { - Ok(None) - } - } - pub fn get_node_children(&self, id: NodeID) -> Result<Vec<NodeID>> { - let txn = self.inner.begin_read()?; - let t_node_children = txn.open_table(T_NODE_CHILDREN)?; - Ok(t_node_children - .range((id.0, NodeID::MIN.0)..(id.0, NodeID::MAX.0))? - .map(|r| r.map(|r| NodeID(r.0.value().1))) - .collect::<Result<Vec<_>, StorageError>>()?) - } - pub fn get_tag_nodes(&self, tag: &str) -> Result<Vec<NodeID>> { - let txn = self.inner.begin_read()?; - let t_tag_node = txn.open_table(T_TAG_NODE)?; - Ok(t_tag_node - .range((tag, NodeID::MIN.0)..(tag, NodeID::MAX.0))? - .map(|r| r.map(|r| NodeID(r.0.value().1))) - .collect::<Result<Vec<_>, StorageError>>()?) - } - pub fn get_nodes_modified_since(&self, since: u64) -> Result<Vec<NodeID>> { - let txn = self.inner.begin_read()?; - let t_node_mtime = txn.open_table(T_NODE_MTIME)?; - Ok(t_node_mtime - .iter()? - .flat_map(|r| r.map(|r| (NodeID(r.0.value()), r.1.value()))) - .filter(|(_, mtime)| *mtime >= since) - .map(|(id, _)| id) - .collect()) - } - - pub fn clear_nodes(&self) -> Result<()> { - let mut txn = self.inner.begin_write()?; - let mut t_node = txn.open_table(T_NODE)?; - let mut t_node_mtime = txn.open_table(T_NODE_MTIME)?; - let mut t_node_children = txn.open_table(T_NODE_CHILDREN)?; - let mut t_node_external_id = txn.open_table(T_NODE_IDENTIFIER)?; - let mut t_import_file_mtime = txn.open_table(T_IMPORT_FILE_MTIME)?; - let mut t_node_media_paths = txn.open_table(T_NODE_MEDIA_PATHS)?; - t_node.retain(|_, _| false)?; - t_node_mtime.retain(|_, _| false)?; - t_node_children.retain(|_, _| false)?; - t_node_external_id.retain(|_, _| false)?; - t_import_file_mtime.retain(|_, _| false)?; - t_node_media_paths.retain(|_, _| false)?; - drop(( - t_node, - t_node_mtime, - t_node_children, - t_node_external_id, - t_import_file_mtime, - t_node_media_paths, - )); - txn.set_durability(Durability::Immediate)?; - txn.commit()?; - Ok(()) - } - - pub fn get_node_udata(&self, id: NodeID, username: &str) -> Result<Option<NodeUserData>> { - let txn = self.inner.begin_read()?; - let t_node = txn.open_table(T_USER_NODE)?; - if let Some(node) = t_node.get((username, id.0))? { - Ok(Some(node.value().0)) - } else { - Ok(None) - } - } - - pub fn update_node_init(&self, id: NodeID, update: impl FnOnce(&mut Node)) -> Result<()> { - let time = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() - .as_secs(); - let mut txn = self.inner.begin_write()?; - let mut t_node = txn.open_table(T_NODE)?; - let mut t_node_mtime = txn.open_table(T_NODE_MTIME)?; - let mut t_node_children = txn.open_table(T_NODE_CHILDREN)?; - let mut t_node_external_id = txn.open_table(T_NODE_IDENTIFIER)?; - let mut t_tag_node = txn.open_table(T_TAG_NODE)?; - let mut node = t_node.get(id.0)?.map(|v| v.value().0).unwrap_or_default(); - - let dh_before = serde_json::to_vec(&node).unwrap(); - update(&mut node); - let dh_after = serde_json::to_vec(&node).unwrap(); - - if dh_before == dh_after { - return Ok(()); - } - - for parent in &node.parents { - t_node_children.insert((parent.0, id.0), ())?; - } - for (pl, eid) in &node.identifiers { - t_node_external_id.insert((*pl as u8, eid.as_str()), id.0)?; - } - for tag in &node.tags { - t_tag_node.insert((tag.as_str(), id.0), ())?; - } - t_node.insert(&id.0, Ser(node))?; - t_node_mtime.insert(&id.0, time)?; - drop(( - t_node, - t_node_mtime, - t_node_children, - t_node_external_id, - t_tag_node, - )); - txn.set_durability(Durability::Immediate)?; - txn.commit()?; - Ok(()) - } - pub fn get_node_media_paths(&self, id: NodeID) -> Result<Vec<PathBuf>> { - let txn = self.inner.begin_read()?; - let table = txn.open_table(T_NODE_MEDIA_PATHS)?; - let mut paths = Vec::new(); - // TODO fix this - for p in table.range((id.0, "\0")..(id.0, "\x7f"))? { - paths.push(PathBuf::from_str(p?.0.value().1)?); - } - Ok(paths) - } - pub fn insert_node_media_path(&self, id: NodeID, path: &Path) -> Result<()> { - let txn = self.inner.begin_write()?; - let mut table = txn.open_table(T_NODE_MEDIA_PATHS)?; - table.insert((id.0, path.to_str().unwrap()), ())?; - drop(table); - txn.commit()?; - Ok(()) - } - - pub fn update_node_udata( - &self, - node: NodeID, - username: &str, - update: impl FnOnce(&mut NodeUserData) -> Result<()>, - ) -> Result<()> { - let txn = self.inner.begin_write()?; - let mut user_nodes = txn.open_table(T_USER_NODE)?; - - let mut udata = user_nodes - .get((username, node.0))? - .map(|x| x.value().0) - .unwrap_or_default(); - - update(&mut udata)?; - - user_nodes.insert((username, node.0), Ser(udata))?; - drop(user_nodes); - txn.commit()?; - Ok(()) - } - - pub fn get_user(&self, username: &str) -> Result<Option<User>> { - let txn = self.inner.begin_read()?; - let t_user = txn.open_table(T_USER)?; - if let Some(user) = t_user.get(username)? { - Ok(Some(user.value().0)) - } else { - Ok(None) - } - } - pub fn update_user( - &self, - username: &str, - update: impl FnOnce(&mut User) -> Result<()>, - ) -> Result<()> { - let txn = self.inner.begin_write()?; - let mut users = txn.open_table(T_USER)?; - let mut user = users - .get(username)? - .ok_or(anyhow!("user does not exist"))? - .value() - .0; - update(&mut user)?; - users.insert(&username, Ser(user))?; - drop(users); - txn.commit()?; - - Ok(()) - } - pub fn delete_user(&self, username: &str) -> Result<bool> { - let txn = self.inner.begin_write()?; - let mut table = txn.open_table(T_USER)?; - let r = table.remove(username)?.is_some(); - drop(table); - txn.commit()?; - Ok(r) - } - pub fn list_users(&self) -> Result<Vec<User>> { - let txn = self.inner.begin_read()?; - let table = txn.open_table(T_USER)?; - let i = table - .iter()? - .map(|a| { - let (_, y) = a.unwrap(); // TODO - y.value().0 - }) - .collect::<Vec<_>>(); - drop(table); - Ok(i) - } - pub fn list_invites(&self) -> Result<Vec<String>> { - let txn = self.inner.begin_read()?; - let table = txn.open_table(T_INVITE)?; - let i = table - .iter()? - .map(|a| { - let (x, _) = a.unwrap(); - x.value().to_owned() - }) - .collect::<Vec<_>>(); - drop(table); - Ok(i) - } - pub fn create_invite(&self, inv: &str) -> Result<()> { - let txn = self.inner.begin_write()?; - let mut table = txn.open_table(T_INVITE)?; - table.insert(inv, ())?; - drop(table); - txn.commit()?; - Ok(()) - } - pub fn delete_invite(&self, inv: &str) -> Result<bool> { - let txn = self.inner.begin_write()?; - let mut table = txn.open_table(T_INVITE)?; - let r = table.remove(inv)?.is_some(); - drop(table); - txn.commit()?; - Ok(r) - } - pub fn register_user(&self, invite: &str, username: &str, user: User) -> Result<()> { - let txn = self.inner.begin_write()?; - let mut invites = txn.open_table(T_INVITE)?; - let mut users = txn.open_table(T_USER)?; - - if invites.remove(invite)?.is_none() { - bail!("invitation invalid"); - } - let prev_user = users.insert(username, Ser(user))?.map(|x| x.value().0); - if prev_user.is_some() { - bail!("username taken"); - } - - drop(users); - drop(invites); - txn.commit()?; - Ok(()) - } - pub fn list_nodes_with_udata(&self, username: &str) -> Result<Vec<(Arc<Node>, NodeUserData)>> { - let txn = self.inner.begin_read()?; - let nodes = txn.open_table(T_NODE)?; - let node_users = txn.open_table(T_USER_NODE)?; - let i = nodes - .iter()? - .map(|a| { - let (x, y) = a.unwrap(); - let (x, y) = (x.value().to_owned(), Arc::new(y.value().0)); - let z = node_users - .get(&(username, x)) - .unwrap() - .map(|z| z.value().0) - .unwrap_or_default(); - (y, z) - }) - .collect::<Vec<_>>(); - drop(nodes); - Ok(i) - } - pub fn search(&self, query: &str, limit: usize, offset: usize) -> Result<(usize, Vec<NodeID>)> { - let query = QueryParser::for_index( - &self.text_search.index, - vec![self.text_search.title, self.text_search.description], - ) - .parse_query(query) - .context("parsing query")?; - - let searcher = self.text_search.reader.searcher(); - let sres = searcher.search(&query, &TopDocs::with_limit(limit).and_offset(offset))?; - let scount = searcher.search(&query, &Count)?; - - let mut results = Vec::new(); - for (_, daddr) in sres { - let doc: TantivyDocument = searcher.doc(daddr)?; - let id = doc - .get_first(self.text_search.id) - .unwrap() - .as_bytes() - .unwrap(); - let id = NodeID(id.try_into().unwrap()); - results.push(id); - } - Ok((scount, results)) - } - - pub fn search_create_index(&self) -> Result<()> { - let mut w = self.text_search.writer.write().unwrap(); - w.delete_all_documents()?; - - let txn = self.inner.begin_read()?; - let nodes = txn.open_table(T_NODE)?; - for node in nodes.iter()? { - let (x, y) = node?; - let (id, node) = (x.value().to_owned(), y.value().0); - - w.add_document(doc!( - self.text_search.id => id.to_vec(), - self.text_search.title => node.title.unwrap_or_default(), - self.text_search.description => node.description.unwrap_or_default(), - self.text_search.releasedate => DateTime::from_timestamp_millis(node.release_date.unwrap_or_default()), - self.text_search.f_index => node.index.unwrap_or_default() as u64, - ))?; - } - - w.commit()?; - Ok(()) - } - - pub fn create_admin_user(&self, username: &str, password_hash: Vec<u8>) -> Result<()> { - let txn = self.inner.begin_write().unwrap(); - let mut users = txn.open_table(T_USER).unwrap(); - - let admin = users.get(username).unwrap().map(|x| x.value().0); - users - .insert( - username, - Ser(User { - admin: true, - name: username.to_owned(), - password: password_hash, - ..admin.unwrap_or_else(|| User { - display_name: "Admin".to_string(), - ..Default::default() - }) - }), - ) - .unwrap(); - - drop(users); - txn.commit().unwrap(); - Ok(()) - } - pub fn get_import_file_mtime(&self, path: &Path) -> Result<Option<u64>> { - let bytes = path.as_os_str().as_encoded_bytes(); - let txn = self.inner.begin_read()?; - let table = txn.open_table(T_IMPORT_FILE_MTIME)?; - if let Some(v) = table.get(bytes)? { - Ok(Some(v.value())) - } else { - Ok(None) - } - } - pub fn set_import_file_mtime(&self, path: &Path, mtime: u64) -> Result<()> { - let bytes = path.as_os_str().as_encoded_bytes(); - let txn = self.inner.begin_write()?; - let mut table = txn.open_table(T_IMPORT_FILE_MTIME)?; - table.insert(bytes, mtime)?; - drop(table); - txn.commit()?; - Ok(()) + pub fn new(driver: &str, path: &Path) -> Result<Self> { + Ok(Self { + storage: match driver { + "rocksdb" => Arc::new(Rocksdb::new(path)?), + "redb" => Arc::new(Redb::new(path)?), + "memory" => Arc::new(Memory::new()), + _ => bail!("unknown db driver"), + }, + }) } } -#[derive(Debug)] -pub struct Ser<T>(pub T); -impl<T: DeserializeOwned + Serialize + std::fmt::Debug> redb::Value for Ser<T> { - type SelfType<'a> - = Ser<T> - where - Self: 'a; - type AsBytes<'a> - = Vec<u8> - where - Self: 'a; - - fn fixed_width() -> Option<usize> { - None - } - - fn from_bytes<'a>(data: &'a [u8]) -> Self::SelfType<'a> - where - Self: 'a, - { - Ser(serde_json::from_slice(data).unwrap()) - } - - fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Self::AsBytes<'a> - where - Self: 'a, - Self: 'b, - { - serde_json::to_vec(&value.0).unwrap() - } - - fn type_name() -> redb::TypeName { - redb::TypeName::new("json") +pub struct Table<T> { + id: u32, + indices: Vec<Box<dyn Index<T>>>, + db: Arc<dyn KV>, +} +impl<T> Table<T> { + pub fn new(db: &Database, id: u32) -> Self { + Self { + id, + indices: Vec::new(), + db: db.storage.clone(), + } } } diff --git a/database/src/search.rs b/database/src/search.rs deleted file mode 100644 index bbe39ab..0000000 --- a/database/src/search.rs +++ /dev/null @@ -1,64 +0,0 @@ -/* - This file is part of jellything (https://codeberg.org/metamuffin/jellything) - which is licensed under the GNU Affero General Public License (version 3); see /COPYING. - Copyright (C) 2025 metamuffin <metamuffin.org> -*/ -use anyhow::Context; -use std::{fs::create_dir_all, path::Path, sync::RwLock}; -use tantivy::{ - Index, IndexReader, IndexWriter, ReloadPolicy, - directory::MmapDirectory, - schema::{DateOptions, DateTimePrecision, FAST, Field, INDEXED, STORED, STRING, Schema, TEXT}, -}; - -pub struct NodeTextSearchIndex { - pub schema: Schema, - pub reader: IndexReader, - pub writer: RwLock<IndexWriter>, - pub index: Index, - pub id: Field, - pub title: Field, - pub releasedate: Field, - pub description: Field, - pub parent: Field, - pub f_index: Field, -} -impl NodeTextSearchIndex { - pub(crate) fn new(path: &Path) -> anyhow::Result<Self> { - let mut schema = Schema::builder(); - let id = schema.add_text_field("id", TEXT | STORED | FAST); - let title = schema.add_text_field("title", TEXT); - let description = schema.add_text_field("description", TEXT); - let parent = schema.add_text_field("parent", STRING | FAST); - let f_index = schema.add_u64_field("index", FAST); - let releasedate = schema.add_date_field( - "releasedate", - DateOptions::from(INDEXED) - .set_fast() - .set_precision(DateTimePrecision::Seconds), - ); - let schema = schema.build(); - create_dir_all(path.join("node_index"))?; - let directory = - MmapDirectory::open(path.join("node_index")).context("opening index directory")?; - let index = Index::open_or_create(directory, schema.clone()).context("creating index")?; - let reader = index - .reader_builder() - .reload_policy(ReloadPolicy::OnCommitWithDelay) - .try_into() - .context("creating reader")?; - let writer = index.writer(30_000_000).context("creating writer")?; - Ok(Self { - index, - writer: writer.into(), - reader, - schema, - parent, - f_index, - releasedate, - id, - description, - title, - }) - } -} diff --git a/server/Cargo.toml b/server/Cargo.toml index a802b2d..84b978a 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -26,7 +26,7 @@ rocket = { workspace = true, features = ["secrets", "json"] } rocket_ws = { workspace = true } serde = { version = "1.0.228", features = ["derive", "rc"] } serde_json = "1.0.145" -serde_yml = "0.0.12" +serde_yaml_ng = "0.10.0" tokio = { workspace = true } tokio-util = { version = "0.7.17", features = ["io", "io-util"] } |