code wiki / hub / nx_search_query_parser.nx

nx_search_query_parser.nx

buildroot/runtime/hub/nx_search_query_parser.nx

22796 B542 linesdepth 4pulls 5 transitivereach 15 importersview sourcekind librarytopic search
docsdependenciesstructsconstsfunctions

about

nx_search_query_parser.nx -- HUB primitive; HTTP query string -> NxSearchQuery. COMPOSES (per NISHI_SMALL_SHARP_COMPOSABLE_STANDARD §4.1 M7): nx_search_inverted (nx_inv_is_token_char + nx_inv_hash_bytes_lower token-character convention reuse) nx_hygiene_prims (NxOptPtr; safe-arith; bounded-loop budget) COMPOSED BY: wiki/nx_wiki_search_handler.nx (next commit; wiki wiring) (future) obd-config-site search handler (future) sprinkler-config-site search handler any site that needs to parse search query strings Status: V1 SEED. 2026-05-27. SITE-AGNOSTIC HUB PRIMITIVE per NISHI_SMALL_SHARP_COMPOSABLE_STANDARD §4.1 M3. WINNER-TIER: BASELINE-C provisional INCUMBENTS: Elasticsearch's QueryParser (Lucene), Whoosh (Python), Tantivy (Rust), Bleve (Go), Algolia's query parser, Meilisearch's query parser NUMBERS: V1 ships query parsing (URL-decode + tokenize + field extraction); paired latency bench vs Lucene QueryParser pending real query workload GAP: Lucene QueryParser handles boolean operators (AND/OR/NOT), phrase quotes, fuzzy ~, boost ^, proximity ~N -- V1 ships JUST term-list parsing (implicit AND); V2 adds the operators PLAN: M-next: V2 boolean operators + phrase quotes; paired latency bench vs Lucene on identical workload EXEMPTION REASON: n/a; provisional pending measurement V1 SCOPE per NISHI_SEARCH_CHARTER.md §6: - URL-decode query string (% escapes + plus-is-space) - Extract q= terms (implicit AND; V1) - Extract scope= (ONSITE default / OFFSITE / BOTH; sealed) - Extract n= max results - Tokenize per nx_search_inverted conventions (lowercase + nx_inv_is_token_char + length 2..64) - Sealed NxSearchQuery emit (caller-allocated buffers)

dependencies 3 imports · 6 importers

nx_syscalls.nx nx_search_inverted.nx nx_hygiene_prims.nx nx_search_query_parser.nx nx_search_handler_flow.nx nx_search_onsite_engine.nx nx_search_render_html.nx nx_search_snippet_extract.nx nx_wiki_search_render.nx nx_wiki_search_wiring.nx

imports: nx_syscalls.nxnx_search_inverted.nxnx_hygiene_prims.nx

imported by: nx_search_handler_flow.nxnx_search_onsite_engine.nxnx_search_render_html.nxnx_search_snippet_extract.nxnx_wiki_search_render.nxnx_wiki_search_wiring.nx

structs

115struct NxSearchQuery

consts

54const NX_SQP_OK: i64 = 0
55const NX_SQP_BAD_INPUT: i64 = 1500
56const NX_SQP_QUERY_TOO_LONG: i64 = 1501
57const NX_SQP_TOO_MANY_TERMS: i64 = 1502
58const NX_SQP_TERM_TOO_LONG: i64 = 1503
59const NX_SQP_TERMS_BUF_OVERFLOW: i64 = 1504
60const NX_SQP_BAD_URL_ESCAPE: i64 = 1505
61const NX_SQP_BAD_SCOPE: i64 = 1506
62const NX_SQP_LOOP_BUDGET: i64 = 1507
63const NX_SQP_NOT_IMPLEMENTED: i64 = 1508
66const NX_SEARCH_SCOPE_ONSITE: i64 = 0 // default; local docs only
67const NX_SEARCH_SCOPE_OFFSITE: i64 = 1 // crawled offsite content only (V3 ships engine)
68const NX_SEARCH_SCOPE_BOTH: i64 = 2 // federated; merged
69const NX_SEARCH_SCOPE_N: i64 = 3
78const NX_SQP_MAX_QUERY_LEN: i64 = 2048 // total query-string bytes
79const NX_SQP_MAX_TERMS: i64 = 32 // hard cap per query (per NX_INV_MAX_POSTINGS_PER hint)
80const NX_SQP_MAX_TERM_LEN: i64 = 64 // per NX_INV_MAX_TOKEN_LEN
81const NX_SQP_MIN_TERM_LEN: i64 = 2 // per NX_INV_MIN_TOKEN_LEN
82const NX_SQP_TERMS_BUF_MIN_CAP: i64 = 1024 // 32 terms * 32 avg bytes
83const NX_SQP_DEFAULT_MAX_RESULTS: i64 = 20
84const NX_SQP_HARD_MAX_RESULTS: i64 = 1000
85const NX_SQP_LOOP_BUDGET: i64 = 100000 // per-parse iteration cap
88const NX_SQP_ASCII_PLUS: i64 = 0x2B // '+'
89const NX_SQP_ASCII_PERCENT: i64 = 0x25 // '%'
90const NX_SQP_ASCII_AMP: i64 = 0x26 // '&'
91const NX_SQP_ASCII_EQ: i64 = 0x3D // '='
92const NX_SQP_ASCII_SP: i64 = 0x20 // ' '
95const NX_SQP_PARAM_Q: *u8 = "q" as *u8
96const NX_SQP_PARAM_Q_N: i64 = 1
97const NX_SQP_PARAM_SCOPE: *u8 = "scope" as *u8
98const NX_SQP_PARAM_SCOPE_N: i64 = 5
99const NX_SQP_PARAM_N: *u8 = "n" as *u8
100const NX_SQP_PARAM_N_N: i64 = 1
103const NX_SQP_SCOPE_VAL_ONSITE: *u8 = "onsite" as *u8
104const NX_SQP_SCOPE_VAL_ONSITE_N: i64 = 6
105const NX_SQP_SCOPE_VAL_OFFSITE: *u8 = "offsite" as *u8
106const NX_SQP_SCOPE_VAL_OFFSITE_N: i64 = 7
107const NX_SQP_SCOPE_VAL_BOTH: *u8 = "both" as *u8
108const NX_SQP_SCOPE_VAL_BOTH_N: i64 = 4
129const NX_SQP_TERM_KIND_SHOULD: i64 = 0 // bare term (V1 default; preserved)
130const NX_SQP_TERM_KIND_MUST: i64 = 1 // "+term" -- doc must contain
131const NX_SQP_TERM_KIND_MUST_NOT: i64 = 2 // "-term" -- doc must NOT contain
132const NX_SQP_TERM_KIND_N: i64 = 3

functions

71func nx_search_scope_is_valid(s: i64) -> i64
135func nx_search_query_init(q: *NxSearchQuery,
160func nx_sqp_hex_val(c: i64) -> i64
called by 1: nx_sqp_decode_one
169func nx_sqp_decode_one(src: *u8, src_n: i64, idx: i64,
199func nx_sqp_bytes_eq(a: *u8, a_n: i64, b: *u8, b_n: i64) -> i64
218func nx_search_query_append_term_kind(q: *NxSearchQuery,
258func nx_search_query_append_term(q: *NxSearchQuery,
268func nx_search_query_tokenize_value(q: *NxSearchQuery,
342func nx_search_query_parse_scope_value(q: *NxSearchQuery,
365func nx_search_query_parse_n_value(q: *NxSearchQuery,
390func nx_search_query_parse(q: *NxSearchQuery,
492func nx_search_query_count(q: *NxSearchQuery) -> i64
498func nx_search_query_term_at(q: *NxSearchQuery, idx: i64,
525func nx_search_query_scope(q: *NxSearchQuery) -> i64
called by 1: nx_srh_write_banner
530func nx_search_query_max_results(q: *NxSearchQuery) -> i64
537func nx_search_query_term_kind_at(q: *NxSearchQuery, idx: i64) -> i64