Blame


1 e2b5610c 2022-04-11 op /*
2 e2b5610c 2022-04-11 op * Copyright (c) 2022 Omar Polo <op@openbsd.org>
3 e2b5610c 2022-04-11 op *
4 e2b5610c 2022-04-11 op * Permission to use, copy, modify, and distribute this software for any
5 e2b5610c 2022-04-11 op * purpose with or without fee is hereby granted, provided that the above
6 e2b5610c 2022-04-11 op * copyright notice and this permission notice appear in all copies.
7 e2b5610c 2022-04-11 op *
8 e2b5610c 2022-04-11 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 e2b5610c 2022-04-11 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 e2b5610c 2022-04-11 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 e2b5610c 2022-04-11 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 e2b5610c 2022-04-11 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 e2b5610c 2022-04-11 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 e2b5610c 2022-04-11 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 e2b5610c 2022-04-11 op */
16 e2b5610c 2022-04-11 op
17 e2b5610c 2022-04-11 op #include <stdio.h>
18 e2b5610c 2022-04-11 op #include <stdlib.h>
19 e2b5610c 2022-04-11 op
20 e2b5610c 2022-04-11 op #include "db.h"
21 e2b5610c 2022-04-11 op #include "fts.h"
22 e2b5610c 2022-04-11 op #include "tokenize.h"
23 e2b5610c 2022-04-11 op
24 e2b5610c 2022-04-11 op struct doclist {
25 e2b5610c 2022-04-11 op uint32_t *ids;
26 e2b5610c 2022-04-11 op size_t len;
27 e2b5610c 2022-04-11 op };
28 e2b5610c 2022-04-11 op
29 e2b5610c 2022-04-11 op int
30 e2b5610c 2022-04-11 op fts(struct db *db, const char *query, db_hit_cb cb, void *data)
31 e2b5610c 2022-04-11 op {
32 e2b5610c 2022-04-11 op struct doclist *xs = NULL;
33 e2b5610c 2022-04-11 op size_t i, len;
34 e2b5610c 2022-04-11 op char **toks, **t;
35 e2b5610c 2022-04-11 op int ret = 0;
36 e2b5610c 2022-04-11 op
37 e2b5610c 2022-04-11 op if ((toks = tokenize(query)) == NULL)
38 e2b5610c 2022-04-11 op return -1;
39 e2b5610c 2022-04-11 op
40 e2b5610c 2022-04-11 op len = 0;
41 e2b5610c 2022-04-11 op for (t = toks; *t != NULL; ++t)
42 e2b5610c 2022-04-11 op len++;
43 e2b5610c 2022-04-11 op
44 e2b5610c 2022-04-11 op if (len == 0)
45 e2b5610c 2022-04-11 op goto done;
46 e2b5610c 2022-04-11 op
47 e2b5610c 2022-04-11 op if ((xs = calloc(len, sizeof(*xs))) == NULL) {
48 e2b5610c 2022-04-11 op freetoks(toks);
49 e2b5610c 2022-04-11 op return -1;
50 e2b5610c 2022-04-11 op }
51 e2b5610c 2022-04-11 op
52 e2b5610c 2022-04-11 op for (i = 0; i < len; ++i) {
53 e2b5610c 2022-04-11 op xs[i].ids = db_word_docs(db, toks[i], &xs[i].len);
54 e2b5610c 2022-04-11 op if (xs[i].ids == NULL || xs[i].len == 0)
55 e2b5610c 2022-04-11 op goto done;
56 e2b5610c 2022-04-11 op }
57 e2b5610c 2022-04-11 op
58 e2b5610c 2022-04-11 op for (;;) {
59 e2b5610c 2022-04-11 op struct db_entry e;
60 e2b5610c 2022-04-11 op uint32_t mdoc;
61 e2b5610c 2022-04-11 op
62 e2b5610c 2022-04-11 op mdoc = xs[0].ids[0];
63 e2b5610c 2022-04-11 op for (i = 1; i < len; ++i) {
64 e2b5610c 2022-04-11 op if (xs[i].ids[0] > mdoc)
65 e2b5610c 2022-04-11 op goto next;
66 e2b5610c 2022-04-11 op while (xs[i].ids[0] < mdoc) {
67 e2b5610c 2022-04-11 op if (--xs[i].len == 0)
68 e2b5610c 2022-04-11 op goto done;
69 e2b5610c 2022-04-11 op xs[i].ids++;
70 e2b5610c 2022-04-11 op }
71 e2b5610c 2022-04-11 op
72 e2b5610c 2022-04-11 op if (xs[i].ids[0] != mdoc)
73 e2b5610c 2022-04-11 op goto next;
74 e2b5610c 2022-04-11 op }
75 e2b5610c 2022-04-11 op
76 e2b5610c 2022-04-11 op if (db_doc_by_id(db, mdoc, &e) == -1) {
77 e2b5610c 2022-04-11 op ret = -1;
78 e2b5610c 2022-04-11 op goto done;
79 e2b5610c 2022-04-11 op }
80 e2b5610c 2022-04-11 op
81 e2b5610c 2022-04-11 op if (cb(db, &e, data) == -1) {
82 e2b5610c 2022-04-11 op ret = -1;
83 e2b5610c 2022-04-11 op goto done;
84 e2b5610c 2022-04-11 op }
85 e2b5610c 2022-04-11 op
86 e2b5610c 2022-04-11 op next:
87 e2b5610c 2022-04-11 op if (--xs[0].len == 0)
88 e2b5610c 2022-04-11 op goto done;
89 e2b5610c 2022-04-11 op xs[0].ids++;
90 e2b5610c 2022-04-11 op }
91 e2b5610c 2022-04-11 op
92 e2b5610c 2022-04-11 op done:
93 e2b5610c 2022-04-11 op free(xs);
94 e2b5610c 2022-04-11 op freetoks(toks);
95 e2b5610c 2022-04-11 op
96 e2b5610c 2022-04-11 op return ret;
97 e2b5610c 2022-04-11 op }