╭ changed ─────╮ │src/search.zig│ ╰──────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │69 // stop at their page size. │ │70 pub fn Query(comptime DB: type) type { │ │71 return struct { │ │72 - // one per typed word; empty when nothing can match │ │72 + // one per typed word, then one per required set. a term with no │ │73 + // postings matches nothing, so neither does the query. │ │74 terms: std.ArrayList(Term), │ │75 // the key the next result starts from, plus room for the one byte that│ │76 // steps past a returned key │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │148 if (!std.mem.startsWith(u8, indexed, word)) break; │ │149 try postings.append(aa, .{ .set = try DB.SortedSet(.read_only).init(pair.value_cursor) });│ │150 } │ │150 - // a word nothing starts with rules out every document │ │151 - if (postings.items.len == 0) return .{ .terms = .empty }; │ │151 + // a word nothing starts with leaves an empty term, which rules │ │152 + // out every document │ │153 try terms.append(aa, .{ .postings = postings.items }); │ │154 } │ │155 return .{ .terms = terms }; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │156 } │ │157 │ │158 // narrow the results to the doc keys in `set`. it is one more term, │ │158 - // with that set as its only posting. a query nothing can match stays │ │159 - // empty, since requiring a set would turn it into every doc key in it. │ │159 + // with that set as its only posting. │ │160 pub fn require(self: *Self, aa: std.mem.Allocator, set: DB.SortedSet(.read_only)) !void {│ │161 - if (self.terms.items.len == 0) return; │ │161 const postings = try aa.alloc(Posting, 1); │ │162 postings[0] = .{ .set = set }; │ │163 try self.terms.append(aa, .{ .postings = postings }); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │171 } │ │172 │ │173 pub fn next(self: *Self) !?[]const u8 { │ │174 + // with no terms at all nothing narrows the results, so none are listed│ │175 if (self.terms.items.len == 0) return null; │ │176 if (self.returned) { │ │177 // doc keys are at most max_doc_key_len, so appending a byte │ ╰────────────────────────────────────────────────────────────────────────────────────────╯