╭ changed ────────────╮ │src/search_thread.zig│ ╰─────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │41 try srch.replace(DB, index, allocator, key, old_text, new_text); │ │42 } │ │43 │ │44 -// the doc keys matching `query_text`, in key order, narrowed to `filter` when│ │45 -// it is keyed the same way │ │44 +// the doc keys matching `query_text`, in key order, narrowed to each non-null│ │45 +// set in `filters`, which must be keyed the same way │ │46 pub fn query( │ │47 comptime DB: type, │ │48 comptime hash_kind: hash.HashKind, │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │50 haxy_moment: DB.HashMap(.read_only), │ │51 aa: std.mem.Allocator, │ │52 query_text: []const u8, │ │53 - filter: ?DB.SortedSet(.read_only), │ │53 + filters: []const ?DB.SortedSet(.read_only), │ │54 ) !srch.Query(DB) { │ │55 - const cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, indexKey(kind))) orelse return .{ .terms = .empty };│ │56 - const index = try DB.SortedMap(.read_only).init(cursor); │ │57 - var results = try srch.Query(DB).init(index, aa, query_text); │ │58 - if (filter) |set| try results.require(aa, set); │ │55 + // no index means no words match, which one empty term expresses │ │56 + var results: srch.Query(DB) = .{ .terms = .empty }; │ │57 + if (try haxy_moment.getCursor(hash.hashInt(hash_kind, indexKey(kind)))) |cursor| { │ │58 + results = try srch.Query(DB).init(try DB.SortedMap(.read_only).init(cursor), aa, query_text); │ │59 + } else { │ │60 + try results.terms.append(aa, .{ .postings = &.{} }); │ │61 + } │ │62 + for (filters) |filter| if (filter) |set| try results.require(aa, set); │ │63 return results; │ │64 } │ │65 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯