2 * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include "dictionary.h"
25 dictionary_init(struct dictionary *dict)
27 memset(dict, 0, sizeof(*dict));
32 add_docid(struct dict_entry *e, int docid)
37 if (e->len > 0 && e->ids[e->len-1] == docid)
40 if (e->len == e->cap) {
41 newcap = e->cap * 1.5;
44 t = recallocarray(e->ids, e->cap, newcap, sizeof(*e->ids));
51 e->ids[e->len++] = docid;
56 dictionary_add(struct dictionary *dict, const char *word, int docid)
58 struct dict_entry *e = NULL;
60 size_t newcap, mid = 0, left = 0, right = dict->len;
63 while (left < right) {
64 mid = (left + right) / 2;
65 e = &dict->entries[mid];
66 r = strcmp(word, e->word);
72 return add_docid(e, docid);
78 if (dict->len == dict->cap) {
79 newcap = dict->cap * 1.5;
82 newentr = recallocarray(dict->entries, dict->cap, newcap,
83 sizeof(*dict->entries));
86 dict->entries = newentr;
90 e = &dict->entries[mid];
91 if (e != dict->entries + dict->len) {
92 size_t i = e - dict->entries;
93 memmove(e+1, e, sizeof(*e) * (dict->len - i));
97 memset(e, 0, sizeof(*e));
98 if ((e->word = strdup(word)) == NULL)
100 return add_docid(e, docid);
104 dictionary_add_words(struct dictionary *dict, char **words, int docid)
106 for (; *words != NULL; ++words) {
107 if (!dictionary_add(dict, *words, docid))
115 dictionary_free(struct dictionary *dict)
119 for (i = 0; i < dict->len; ++i) {
120 free(dict->entries[i].word);
121 free(dict->entries[i].ids);