╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ search_thread.zig ────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
40 const index = try DB.SortedMap(.read_write).init(try haxy_moment.putCursor(hash.hashInt(hash_kind, indexKey(kind)))); 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 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, 49 comptime kind: evt.EventKind, 50 haxy_moment: DB.HashMap(.read_only), 51 aa: std.mem.Allocator, 52 query_text: []const u8, 53 filters: []const ?DB.SortedSet(.read_only), 54 ) !srch.Query(DB) { 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 66 // the text a thread is indexed under, none once it is removed: the title and 67 // labels first, so the tokenizer's caps can only drop the tail of a long 68 // description. 69 fn text(aa: std.mem.Allocator, record: anytype) ![]const u8 { 70 if (record.removed) return ""; 71 return std.mem.concat(aa, u8, &.{ record.event.title, " ", record.event.labels, " ", record.event.description }); 72 } 73