╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ search.zig ───────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
227 } 228 i += 1; 229 } 230 self.returned = true; 231 return self.pos[0..self.pos_len]; 232 } 233 }; 234 } 235 236 // the unique lowercased words of `text`, in the order they first appear. 237 fn tokenize(aa: std.mem.Allocator, text: []const u8) ![]const []const u8 { 238 var words: std.StringArrayHashMapUnmanaged(void) = .empty; 239 const limit = @min(text.len, max_indexed_bytes); 240 var i: usize = 0; 241 while (i < limit) { 242 if (!isWordByte(text[i])) { 243 i += 1; 244 continue; 245 } 246 const start = i; 247 while (i < limit and isWordByte(text[i])) i += 1; 248 const word = text[start..@min(i, start + max_word_len)]; 249 if (word.len < min_word_len) continue; 250 const lowered = try aa.alloc(u8, word.len); 251 _ = std.ascii.lowerString(lowered, word); 252 try words.put(aa, lowered, {}); 253 if (words.count() == max_words_per_doc) break; 254 } 255 return words.keys(); 256 } 257 258 // a word is a run of ascii alphanumerics and non-ascii bytes. 259 fn isWordByte(byte: u8) bool { 260 return std.ascii.isAlphanumeric(byte) or byte >= 0x80; 261 } 262