@delali/narsil-react-native 0.3.1-next.154 → 0.3.1-next.156
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +144 -0
- package/NarsilReactNative.podspec +2 -2
- package/android/CMakeLists.txt +1 -1
- package/cpp/HybridNarsilCoreAnalysis.cpp +277 -0
- package/cpp/HybridNarsilCoreImpl.hpp +43 -0
- package/cpp/HybridNarsilCoreKeyword.cpp +253 -0
- package/cpp/HybridNarsilCoreMath.cpp +47 -0
- package/cpp/core/include/narsil_analysis.h +86 -0
- package/cpp/core/include/narsil_core.h +1 -1
- package/cpp/core/include/narsil_keyword.h +110 -0
- package/cpp/core/include/narsil_math.h +36 -0
- package/cpp/core/src/analysis/analyse.c +281 -0
- package/cpp/core/src/analysis/analyser.h +49 -0
- package/cpp/core/src/analysis/languages.c +79 -0
- package/cpp/core/src/analysis/languages.h +42 -0
- package/cpp/core/src/analysis/normalise.c +242 -0
- package/cpp/core/src/analysis/normalise.h +28 -0
- package/cpp/core/src/analysis/split.c +183 -0
- package/cpp/core/src/analysis/split.h +27 -0
- package/cpp/core/src/analysis/stop_words.c +82 -0
- package/cpp/core/src/analysis/stop_words.h +19 -0
- package/cpp/core/src/analysis/term_cache.c +88 -0
- package/cpp/core/src/analysis/term_cache.h +36 -0
- package/cpp/core/src/analysis/text.c +161 -0
- package/cpp/core/src/analysis/text.h +45 -0
- package/cpp/core/src/analysis/transform.c +103 -0
- package/cpp/core/src/analysis/unicode.c +252 -0
- package/cpp/core/src/analysis/unicode.h +54 -0
- package/cpp/core/src/internal.h +4 -0
- package/cpp/core/src/keyword/pass.h +117 -0
- package/cpp/core/src/keyword/prune.c +324 -0
- package/cpp/core/src/keyword/request.c +179 -0
- package/cpp/core/src/keyword/rows.c +83 -0
- package/cpp/core/src/keyword/rows.h +18 -0
- package/cpp/core/src/keyword/score.c +257 -0
- package/cpp/core/src/keyword/score.h +17 -0
- package/cpp/core/src/keyword/scratch.c +226 -0
- package/cpp/core/src/keyword/scratch.h +55 -0
- package/cpp/core/src/keyword/select.c +155 -0
- package/cpp/core/src/keyword/select.h +17 -0
- package/cpp/core/src/languages/bulgarian_stemmer.c +114 -0
- package/cpp/core/src/languages/data/albanian.c +54 -0
- package/cpp/core/src/languages/data/amharic.c +93 -0
- package/cpp/core/src/languages/data/arabic.c +146 -0
- package/cpp/core/src/languages/data/armenian.c +46 -0
- package/cpp/core/src/languages/data/azerbaijani.c +68 -0
- package/cpp/core/src/languages/data/bambara.c +48 -0
- package/cpp/core/src/languages/data/basque.c +62 -0
- package/cpp/core/src/languages/data/belarusian.c +56 -0
- package/cpp/core/src/languages/data/bengali.c +63 -0
- package/cpp/core/src/languages/data/bosnian.c +73 -0
- package/cpp/core/src/languages/data/breton.c +52 -0
- package/cpp/core/src/languages/data/bulgarian.c +144 -0
- package/cpp/core/src/languages/data/burmese.c +48 -0
- package/cpp/core/src/languages/data/catalan.c +84 -0
- package/cpp/core/src/languages/data/chinese.c +70 -0
- package/cpp/core/src/languages/data/croatian.c +72 -0
- package/cpp/core/src/languages/data/czech.c +72 -0
- package/cpp/core/src/languages/data/dagbani.c +88 -0
- package/cpp/core/src/languages/data/danish.c +56 -0
- package/cpp/core/src/languages/data/declarations.h +114 -0
- package/cpp/core/src/languages/data/dutch.c +58 -0
- package/cpp/core/src/languages/data/english.c +172 -0
- package/cpp/core/src/languages/data/esperanto.c +71 -0
- package/cpp/core/src/languages/data/estonian.c +417 -0
- package/cpp/core/src/languages/data/ewe.c +89 -0
- package/cpp/core/src/languages/data/faroese.c +54 -0
- package/cpp/core/src/languages/data/fijian.c +44 -0
- package/cpp/core/src/languages/data/finnish.c +100 -0
- package/cpp/core/src/languages/data/french.c +74 -0
- package/cpp/core/src/languages/data/ga.c +83 -0
- package/cpp/core/src/languages/data/galician.c +70 -0
- package/cpp/core/src/languages/data/georgian.c +57 -0
- package/cpp/core/src/languages/data/german.c +96 -0
- package/cpp/core/src/languages/data/greek.c +202 -0
- package/cpp/core/src/languages/data/guarani.c +110 -0
- package/cpp/core/src/languages/data/gujarati.c +90 -0
- package/cpp/core/src/languages/data/haitian-creole.c +54 -0
- package/cpp/core/src/languages/data/hausa.c +85 -0
- package/cpp/core/src/languages/data/hawaiian.c +50 -0
- package/cpp/core/src/languages/data/hebrew.c +85 -0
- package/cpp/core/src/languages/data/hindi.c +91 -0
- package/cpp/core/src/languages/data/hungarian.c +98 -0
- package/cpp/core/src/languages/data/icelandic.c +73 -0
- package/cpp/core/src/languages/data/igbo.c +90 -0
- package/cpp/core/src/languages/data/indonesian.c +296 -0
- package/cpp/core/src/languages/data/irish.c +60 -0
- package/cpp/core/src/languages/data/italian.c +107 -0
- package/cpp/core/src/languages/data/japanese.c +52 -0
- package/cpp/core/src/languages/data/kannada.c +60 -0
- package/cpp/core/src/languages/data/kazakh.c +57 -0
- package/cpp/core/src/languages/data/khmer.c +71 -0
- package/cpp/core/src/languages/data/kinyarwanda.c +54 -0
- package/cpp/core/src/languages/data/kirundi.c +53 -0
- package/cpp/core/src/languages/data/korean.c +74 -0
- package/cpp/core/src/languages/data/kurmanji.c +43 -0
- package/cpp/core/src/languages/data/kyrgyz.c +65 -0
- package/cpp/core/src/languages/data/lao.c +46 -0
- package/cpp/core/src/languages/data/latin.c +46 -0
- package/cpp/core/src/languages/data/latvian.c +75 -0
- package/cpp/core/src/languages/data/lingala.c +88 -0
- package/cpp/core/src/languages/data/lithuanian.c +65 -0
- package/cpp/core/src/languages/data/luxembourgish.c +80 -0
- package/cpp/core/src/languages/data/macedonian.c +286 -0
- package/cpp/core/src/languages/data/malagasy.c +51 -0
- package/cpp/core/src/languages/data/malay.c +184 -0
- package/cpp/core/src/languages/data/malayalam.c +64 -0
- package/cpp/core/src/languages/data/maltese.c +102 -0
- package/cpp/core/src/languages/data/maori.c +52 -0
- package/cpp/core/src/languages/data/marathi.c +62 -0
- package/cpp/core/src/languages/data/nepali.c +72 -0
- package/cpp/core/src/languages/data/norwegian.c +74 -0
- package/cpp/core/src/languages/data/oromo.c +51 -0
- package/cpp/core/src/languages/data/persian.c +150 -0
- package/cpp/core/src/languages/data/polish.c +111 -0
- package/cpp/core/src/languages/data/portuguese.c +91 -0
- package/cpp/core/src/languages/data/punjabi.c +80 -0
- package/cpp/core/src/languages/data/registry.c +116 -0
- package/cpp/core/src/languages/data/romanian.c +93 -0
- package/cpp/core/src/languages/data/russian.c +76 -0
- package/cpp/core/src/languages/data/samoan.c +47 -0
- package/cpp/core/src/languages/data/sanskrit.c +53 -0
- package/cpp/core/src/languages/data/scottish-gaelic.c +119 -0
- package/cpp/core/src/languages/data/serbian.c +84 -0
- package/cpp/core/src/languages/data/shona.c +55 -0
- package/cpp/core/src/languages/data/sinhala.c +78 -0
- package/cpp/core/src/languages/data/slovak.c +135 -0
- package/cpp/core/src/languages/data/slovenian.c +139 -0
- package/cpp/core/src/languages/data/sorani.c +55 -0
- package/cpp/core/src/languages/data/spanish.c +84 -0
- package/cpp/core/src/languages/data/swahili.c +59 -0
- package/cpp/core/src/languages/data/swedish.c +60 -0
- package/cpp/core/src/languages/data/tagalog.c +75 -0
- package/cpp/core/src/languages/data/tamil.c +69 -0
- package/cpp/core/src/languages/data/tatar.c +548 -0
- package/cpp/core/src/languages/data/telugu.c +54 -0
- package/cpp/core/src/languages/data/thai.c +46 -0
- package/cpp/core/src/languages/data/tibetan.c +55 -0
- package/cpp/core/src/languages/data/tigrinya.c +73 -0
- package/cpp/core/src/languages/data/tongan.c +47 -0
- package/cpp/core/src/languages/data/turkish.c +100 -0
- package/cpp/core/src/languages/data/twi.c +88 -0
- package/cpp/core/src/languages/data/ukrainian.c +99 -0
- package/cpp/core/src/languages/data/urdu.c +174 -0
- package/cpp/core/src/languages/data/vietnamese.c +88 -0
- package/cpp/core/src/languages/data/welsh.c +143 -0
- package/cpp/core/src/languages/data/wolof.c +51 -0
- package/cpp/core/src/languages/data/xhosa.c +56 -0
- package/cpp/core/src/languages/data/yoruba.c +93 -0
- package/cpp/core/src/languages/data/zulu.c +58 -0
- package/cpp/core/src/languages/marks.c +64 -0
- package/cpp/core/src/languages/rules.c +63 -0
- package/cpp/core/src/languages/rules.h +68 -0
- package/cpp/core/src/languages/sanskrit_stemmer.c +50 -0
- package/cpp/core/src/languages/scripts.c +143 -0
- package/cpp/core/src/languages/slovenian_stemmer.c +46 -0
- package/cpp/core/src/languages/snowball/api.c +52 -0
- package/cpp/core/src/languages/snowball/api.h +43 -0
- package/cpp/core/src/languages/snowball/arabic_stemmer.c +1506 -0
- package/cpp/core/src/languages/snowball/arabic_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/armenian_stemmer.c +523 -0
- package/cpp/core/src/languages/snowball/armenian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/basque_stemmer.c +1089 -0
- package/cpp/core/src/languages/snowball/basque_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/catalan_stemmer.c +1380 -0
- package/cpp/core/src/languages/snowball/catalan_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/czech_stemmer.c +582 -0
- package/cpp/core/src/languages/snowball/czech_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/danish_stemmer.c +352 -0
- package/cpp/core/src/languages/snowball/danish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/dutch_stemmer.c +1657 -0
- package/cpp/core/src/languages/snowball/dutch_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/english_stemmer.c +1019 -0
- package/cpp/core/src/languages/snowball/english_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/esperanto_stemmer.c +716 -0
- package/cpp/core/src/languages/snowball/esperanto_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/estonian_stemmer.c +1361 -0
- package/cpp/core/src/languages/snowball/estonian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/finnish_stemmer.c +800 -0
- package/cpp/core/src/languages/snowball/finnish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/french_stemmer.c +1217 -0
- package/cpp/core/src/languages/snowball/french_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/german_stemmer.c +567 -0
- package/cpp/core/src/languages/snowball/german_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/greek_stemmer.c +3450 -0
- package/cpp/core/src/languages/snowball/greek_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/hindi_stemmer.c +325 -0
- package/cpp/core/src/languages/snowball/hindi_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/hungarian_stemmer.c +742 -0
- package/cpp/core/src/languages/snowball/hungarian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/indonesian_stemmer.c +443 -0
- package/cpp/core/src/languages/snowball/indonesian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/irish_stemmer.c +428 -0
- package/cpp/core/src/languages/snowball/irish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/italian_stemmer.c +983 -0
- package/cpp/core/src/languages/snowball/italian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/lithuanian_stemmer.c +794 -0
- package/cpp/core/src/languages/snowball/lithuanian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/nepali_stemmer.c +361 -0
- package/cpp/core/src/languages/snowball/nepali_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/norwegian_stemmer.c +332 -0
- package/cpp/core/src/languages/snowball/norwegian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/persian_stemmer.c +538 -0
- package/cpp/core/src/languages/snowball/persian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/polish_stemmer.c +501 -0
- package/cpp/core/src/languages/snowball/polish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/portuguese_stemmer.c +866 -0
- package/cpp/core/src/languages/snowball/portuguese_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/romanian_stemmer.c +940 -0
- package/cpp/core/src/languages/snowball/romanian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/russian_stemmer.c +598 -0
- package/cpp/core/src/languages/snowball/russian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/serbian_stemmer.c +6765 -0
- package/cpp/core/src/languages/snowball/serbian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/snowball_runtime.h +122 -0
- package/cpp/core/src/languages/snowball/spanish_stemmer.c +955 -0
- package/cpp/core/src/languages/snowball/spanish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/swedish_stemmer.c +364 -0
- package/cpp/core/src/languages/snowball/swedish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/tamil_stemmer.c +1305 -0
- package/cpp/core/src/languages/snowball/tamil_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/turkish_stemmer.c +1700 -0
- package/cpp/core/src/languages/snowball/turkish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/utilities.c +716 -0
- package/cpp/core/src/languages/substitutions.c +131 -0
- package/cpp/core/src/languages/swahili_stemmer.c +85 -0
- package/cpp/core/src/languages/ukrainian_stemmer.c +168 -0
- package/cpp/core/src/locks.c +2 -15
- package/cpp/core/src/math/apply.c +44 -0
- package/cpp/core/src/math/fdlibm.h +16 -0
- package/cpp/core/src/math/inverse.c +242 -0
- package/cpp/core/src/math/log.c +90 -0
- package/cpp/core/src/math/reduce.c +325 -0
- package/cpp/core/src/math/trig.c +188 -0
- package/cpp/core/src/math/words.h +45 -0
- package/cpp/core/src/thread_yield.h +18 -0
- package/cpp/core/src/unicode/decompositions.c +310 -0
- package/cpp/core/src/unicode/lowercase.c +172 -0
- package/cpp/core/src/unicode/properties.c +214 -0
- package/cpp/core/src/workspace.c +5 -1
- package/lib/engine/analysis.d.ts +3 -0
- package/lib/engine/analysis.js +76 -0
- package/lib/engine/core.js +5 -0
- package/lib/engine/keyword.d.ts +3 -0
- package/lib/engine/keyword.js +25 -0
- package/lib/specs/core.nitro.d.ts +1 -0
- package/nitrogen/generated/shared/c++/HybridNarsilCoreSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridNarsilCoreSpec.hpp +1 -0
- package/package.json +4 -3
- package/src/engine/analysis.ts +87 -0
- package/src/engine/core.ts +6 -0
- package/src/engine/keyword.ts +26 -0
- package/src/specs/core.nitro.ts +1 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#include "rows.h"
|
|
2
|
+
|
|
3
|
+
#include "scratch.h"
|
|
4
|
+
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
#define INSERTION_SORT_ROWS 16U
|
|
8
|
+
#define UNKNOWN_FIELD_RANK 0x10000U
|
|
9
|
+
|
|
10
|
+
typedef struct {
|
|
11
|
+
const uint32_t *source;
|
|
12
|
+
uint32_t *target;
|
|
13
|
+
} merge_pass;
|
|
14
|
+
|
|
15
|
+
static uint32_t rank_of(const keyword_row_keys *keys, uint32_t row) {
|
|
16
|
+
uint16_t field = keys->fields[row];
|
|
17
|
+
return field < keys->field_count ? keys->name_ranks[field] : UNKNOWN_FIELD_RANK;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static int row_before(const keyword_row_keys *keys, uint32_t lhs, uint32_t rhs) {
|
|
21
|
+
uint32_t left_doc = keys->doc_ids[lhs];
|
|
22
|
+
uint32_t right_doc = keys->doc_ids[rhs];
|
|
23
|
+
if (left_doc != right_doc) { return left_doc < right_doc; }
|
|
24
|
+
return rank_of(keys, lhs) < rank_of(keys, rhs);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static void insertion_sort(const keyword_row_keys *keys, uint32_t *order, uint32_t begin, uint32_t end) {
|
|
28
|
+
for (uint32_t place = begin + 1; place < end; place++) {
|
|
29
|
+
uint32_t row = order[place];
|
|
30
|
+
uint32_t slot = place;
|
|
31
|
+
while (slot > begin && row_before(keys, row, order[slot - 1])) {
|
|
32
|
+
order[slot] = order[slot - 1];
|
|
33
|
+
slot--;
|
|
34
|
+
}
|
|
35
|
+
order[slot] = row;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static void merge_runs(const keyword_row_keys *keys, const merge_pass *merge, uint32_t begin, uint32_t middle,
|
|
40
|
+
uint32_t end) {
|
|
41
|
+
uint32_t left = begin;
|
|
42
|
+
uint32_t right = middle;
|
|
43
|
+
uint32_t out = begin;
|
|
44
|
+
while (left < middle && right < end) {
|
|
45
|
+
if (row_before(keys, merge->source[right], merge->source[left])) {
|
|
46
|
+
merge->target[out++] = merge->source[right++];
|
|
47
|
+
} else {
|
|
48
|
+
merge->target[out++] = merge->source[left++];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
while (left < middle) { merge->target[out++] = merge->source[left++]; }
|
|
52
|
+
while (right < end) { merge->target[out++] = merge->source[right++]; }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static uint32_t smaller(uint64_t value, uint32_t limit) { return value < limit ? (uint32_t)value : limit; }
|
|
56
|
+
|
|
57
|
+
const uint32_t *keyword_sort_rows(const keyword_row_keys *keys, keyword_scratch *scratch, uint32_t count) {
|
|
58
|
+
uint32_t *order = scratch->order;
|
|
59
|
+
if (count <= INSERTION_SORT_ROWS) {
|
|
60
|
+
insertion_sort(keys, order, 0, count);
|
|
61
|
+
return order;
|
|
62
|
+
}
|
|
63
|
+
for (uint64_t begin = 0; begin < count; begin += INSERTION_SORT_ROWS) {
|
|
64
|
+
insertion_sort(keys, order, (uint32_t)begin, smaller(begin + INSERTION_SORT_ROWS, count));
|
|
65
|
+
}
|
|
66
|
+
merge_pass merge = {order, scratch->order_spare};
|
|
67
|
+
for (uint64_t width = INSERTION_SORT_ROWS; width < count; width *= 2) {
|
|
68
|
+
for (uint64_t begin = 0; begin < count; begin += 2 * width) {
|
|
69
|
+
merge_runs(keys, &merge, (uint32_t)begin, smaller(begin + width, count), smaller(begin + (2 * width), count));
|
|
70
|
+
}
|
|
71
|
+
uint32_t *written = merge.target;
|
|
72
|
+
merge.target = merge.source == order ? order : scratch->order_spare;
|
|
73
|
+
merge.source = written;
|
|
74
|
+
}
|
|
75
|
+
return merge.source;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
int keyword_ranks_ascend(const keyword_row_keys *keys, uint32_t begin, uint32_t count) {
|
|
79
|
+
for (uint32_t row = begin + 1; row < begin + count; row++) {
|
|
80
|
+
if (rank_of(keys, row) < rank_of(keys, row - 1)) { return 0; }
|
|
81
|
+
}
|
|
82
|
+
return 1;
|
|
83
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#ifndef NARSIL_KEYWORD_ROWS_H
|
|
2
|
+
#define NARSIL_KEYWORD_ROWS_H
|
|
3
|
+
|
|
4
|
+
#include "scratch.h"
|
|
5
|
+
|
|
6
|
+
#include <stdint.h>
|
|
7
|
+
|
|
8
|
+
typedef struct {
|
|
9
|
+
const uint32_t *doc_ids;
|
|
10
|
+
const uint16_t *fields;
|
|
11
|
+
const uint16_t *name_ranks;
|
|
12
|
+
uint32_t field_count;
|
|
13
|
+
} keyword_row_keys;
|
|
14
|
+
|
|
15
|
+
const uint32_t *keyword_sort_rows(const keyword_row_keys *keys, keyword_scratch *scratch, uint32_t count);
|
|
16
|
+
int keyword_ranks_ascend(const keyword_row_keys *keys, uint32_t begin, uint32_t count);
|
|
17
|
+
|
|
18
|
+
#endif
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
#include "score.h"
|
|
2
|
+
|
|
3
|
+
#include "pass.h"
|
|
4
|
+
#include "rows.h"
|
|
5
|
+
#include "scratch.h"
|
|
6
|
+
#include "select.h"
|
|
7
|
+
|
|
8
|
+
#include "../math/fdlibm.h"
|
|
9
|
+
|
|
10
|
+
#include "../../include/narsil_keyword.h"
|
|
11
|
+
|
|
12
|
+
#include <stddef.h>
|
|
13
|
+
#include <stdint.h>
|
|
14
|
+
|
|
15
|
+
#define IDF_HALF_DOCUMENT 0.5
|
|
16
|
+
|
|
17
|
+
typedef struct {
|
|
18
|
+
int member_mode;
|
|
19
|
+
double idf;
|
|
20
|
+
int has_term;
|
|
21
|
+
uint32_t term;
|
|
22
|
+
double factor;
|
|
23
|
+
double partial_factor;
|
|
24
|
+
} keyword_run;
|
|
25
|
+
|
|
26
|
+
typedef struct {
|
|
27
|
+
const keyword_pass *pass;
|
|
28
|
+
keyword_run *run;
|
|
29
|
+
const keyword_row_keys *keys;
|
|
30
|
+
const keyword_rows *rows;
|
|
31
|
+
} list_scan;
|
|
32
|
+
|
|
33
|
+
typedef struct {
|
|
34
|
+
const uint32_t *order;
|
|
35
|
+
uint32_t begin;
|
|
36
|
+
uint32_t end;
|
|
37
|
+
uint32_t ordinal;
|
|
38
|
+
} row_run;
|
|
39
|
+
|
|
40
|
+
double keyword_idf(double document_frequency, double total_documents) {
|
|
41
|
+
if (total_documents == 0) { return 0; }
|
|
42
|
+
double rest = (total_documents - document_frequency) + IDF_HALF_DOCUMENT;
|
|
43
|
+
return fdlibm_log((rest / (document_frequency + IDF_HALF_DOCUMENT)) + 1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void keyword_list_rows(const keyword_pass *pass, uint32_t list, keyword_rows *rows) {
|
|
47
|
+
const narsil_keyword_request *request = pass->request;
|
|
48
|
+
if ((keyword_list_flags(request, list) & NARSIL_KEYWORD_LIST_FROM_ROWS) != 0) {
|
|
49
|
+
rows->doc_ids = request->row_doc_ids;
|
|
50
|
+
rows->fields = request->row_fields;
|
|
51
|
+
rows->narrow_frequencies = NULL;
|
|
52
|
+
rows->wide_frequencies = request->row_frequencies;
|
|
53
|
+
} else {
|
|
54
|
+
rows->doc_ids = request->pool_doc_ids;
|
|
55
|
+
rows->fields = request->pool_fields;
|
|
56
|
+
rows->narrow_frequencies = request->pool_frequencies;
|
|
57
|
+
rows->wide_frequencies = NULL;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
void keyword_list_keys(const keyword_pass *pass, uint32_t list, keyword_row_keys *keys) {
|
|
62
|
+
keyword_rows rows;
|
|
63
|
+
keyword_list_rows(pass, list, &rows);
|
|
64
|
+
keys->doc_ids = rows.doc_ids;
|
|
65
|
+
keys->fields = rows.fields;
|
|
66
|
+
keys->name_ranks = pass->request->name_ranks;
|
|
67
|
+
keys->field_count = pass->field_count;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static void touch(const keyword_pass *pass, uint32_t ordinal) {
|
|
71
|
+
keyword_scratch *scratch = pass->scratch;
|
|
72
|
+
if (scratch->stamps[ordinal] == scratch->generation) { return; }
|
|
73
|
+
scratch->stamps[ordinal] = scratch->generation;
|
|
74
|
+
scratch->scores[ordinal] = 0;
|
|
75
|
+
if (pass->tracks_coverage) {
|
|
76
|
+
scratch->covered[ordinal] = 0;
|
|
77
|
+
scratch->last_term[ordinal] = 0;
|
|
78
|
+
}
|
|
79
|
+
scratch->touched[scratch->touched_count++] = ordinal;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static void cover(const keyword_pass *pass, uint32_t ordinal, uint32_t term) {
|
|
83
|
+
if (!pass->tracks_coverage) { return; }
|
|
84
|
+
keyword_scratch *scratch = pass->scratch;
|
|
85
|
+
if (scratch->last_term[ordinal] == term + 1) { return; }
|
|
86
|
+
scratch->last_term[ordinal] = term + 1;
|
|
87
|
+
scratch->covered[ordinal]++;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static void score_row(const list_scan *scan, uint32_t row, uint32_t ordinal) {
|
|
91
|
+
const keyword_pass *pass = scan->pass;
|
|
92
|
+
uint32_t field = scan->rows->fields[row];
|
|
93
|
+
if (!keyword_searchable(pass, field)) { return; }
|
|
94
|
+
touch(pass, ordinal);
|
|
95
|
+
pass->scratch->scores[ordinal] +=
|
|
96
|
+
keyword_row_score(pass, scan->run->idf, keyword_frequency(scan->rows, row), field, ordinal);
|
|
97
|
+
if (scan->run->has_term) { cover(pass, ordinal, scan->run->term); }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static void score_members(const list_scan *scan, const row_run *rows) {
|
|
101
|
+
const keyword_pass *pass = scan->pass;
|
|
102
|
+
const keyword_run *run = scan->run;
|
|
103
|
+
const uint8_t *partial_marks = pass->request->partial_marks;
|
|
104
|
+
uint32_t ordinal = rows->ordinal;
|
|
105
|
+
double sum = 0;
|
|
106
|
+
int any = 0;
|
|
107
|
+
for (uint32_t place = rows->begin; place < rows->end; place++) {
|
|
108
|
+
uint32_t row = rows->order[place];
|
|
109
|
+
uint32_t field = scan->rows->fields[row];
|
|
110
|
+
if (!keyword_searchable(pass, field)) { continue; }
|
|
111
|
+
double factor = partial_marks[field] == 1 ? run->partial_factor : run->factor;
|
|
112
|
+
if (!(factor > 0)) { continue; }
|
|
113
|
+
sum += keyword_row_score(pass, run->idf, keyword_frequency(scan->rows, row), field, ordinal) * factor;
|
|
114
|
+
any = 1;
|
|
115
|
+
}
|
|
116
|
+
if (!any) { return; }
|
|
117
|
+
keyword_scratch *scratch = pass->scratch;
|
|
118
|
+
if (scratch->group_stamps[ordinal] != scratch->group_generation) {
|
|
119
|
+
scratch->group_stamps[ordinal] = scratch->group_generation;
|
|
120
|
+
scratch->group_best[ordinal] = sum;
|
|
121
|
+
scratch->group_touched[scratch->group_touched_count++] = ordinal;
|
|
122
|
+
} else if (sum > scratch->group_best[ordinal]) {
|
|
123
|
+
scratch->group_best[ordinal] = sum;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static void score_run(const list_scan *scan, const row_run *rows) {
|
|
128
|
+
if (scan->run->member_mode) {
|
|
129
|
+
score_members(scan, rows);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
for (uint32_t place = rows->begin; place < rows->end; place++) { score_row(scan, rows->order[place], rows->ordinal); }
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static void score_unordered_list(const list_scan *scan, uint32_t begin, uint32_t length) {
|
|
136
|
+
keyword_scratch *scratch = scan->pass->scratch;
|
|
137
|
+
const uint32_t *doc_ids = scan->keys->doc_ids;
|
|
138
|
+
for (uint32_t place = 0; place < length; place++) { scratch->order[place] = begin + place; }
|
|
139
|
+
const uint32_t *sorted = keyword_sort_rows(scan->keys, scratch, length);
|
|
140
|
+
uint32_t place = 0;
|
|
141
|
+
while (place < length) {
|
|
142
|
+
uint32_t ordinal = doc_ids[sorted[place]];
|
|
143
|
+
uint32_t end = place + 1;
|
|
144
|
+
while (end < length && doc_ids[sorted[end]] == ordinal) { end++; }
|
|
145
|
+
if (keyword_scorable(scan->pass, ordinal)) {
|
|
146
|
+
row_run rows = {sorted, place, end, ordinal};
|
|
147
|
+
score_run(scan, &rows);
|
|
148
|
+
}
|
|
149
|
+
place = end;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const uint32_t *keyword_rank_ordered_run(const keyword_pass *pass, const keyword_row_keys *keys, uint32_t begin,
|
|
154
|
+
uint32_t count) {
|
|
155
|
+
keyword_scratch *scratch = pass->scratch;
|
|
156
|
+
uint32_t *rows = scratch->order;
|
|
157
|
+
for (uint32_t row = 0; row < count; row++) { rows[row] = begin + row; }
|
|
158
|
+
if (count > 1 && !keyword_ranks_ascend(keys, begin, count)) { return keyword_sort_rows(keys, scratch, count); }
|
|
159
|
+
return rows;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static void score_ordered_list(const list_scan *scan, uint32_t begin, uint32_t length) {
|
|
163
|
+
const uint32_t *doc_ids = scan->keys->doc_ids;
|
|
164
|
+
uint32_t end = begin + length;
|
|
165
|
+
uint32_t place = begin;
|
|
166
|
+
while (place < end) {
|
|
167
|
+
uint32_t ordinal = doc_ids[place];
|
|
168
|
+
uint32_t run_end = place + 1;
|
|
169
|
+
while (run_end < end && doc_ids[run_end] == ordinal) { run_end++; }
|
|
170
|
+
if (keyword_scorable(scan->pass, ordinal)) {
|
|
171
|
+
uint32_t count = run_end - place;
|
|
172
|
+
if (count == 1 && !scan->run->member_mode) {
|
|
173
|
+
score_row(scan, place, ordinal);
|
|
174
|
+
} else {
|
|
175
|
+
row_run rows = {keyword_rank_ordered_run(scan->pass, scan->keys, place, count), 0, count, ordinal};
|
|
176
|
+
score_run(scan, &rows);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
place = run_end;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static void score_list(const keyword_pass *pass, keyword_run *run, uint32_t list) {
|
|
184
|
+
const narsil_keyword_request *request = pass->request;
|
|
185
|
+
keyword_rows rows;
|
|
186
|
+
keyword_row_keys keys;
|
|
187
|
+
keyword_list_rows(pass, list, &rows);
|
|
188
|
+
keyword_list_keys(pass, list, &keys);
|
|
189
|
+
run->factor = keyword_list_value(request, list, NARSIL_KEYWORD_LIST_FACTOR);
|
|
190
|
+
run->partial_factor = keyword_list_value(request, list, NARSIL_KEYWORD_LIST_PARTIAL_FACTOR);
|
|
191
|
+
list_scan scan = {pass, run, &keys, &rows};
|
|
192
|
+
uint32_t begin = keyword_list_start(request, list);
|
|
193
|
+
uint32_t length = keyword_list_length(request, list);
|
|
194
|
+
if ((keyword_list_flags(request, list) & NARSIL_KEYWORD_LIST_ORDERED) == 0) {
|
|
195
|
+
score_unordered_list(&scan, begin, length);
|
|
196
|
+
} else {
|
|
197
|
+
score_ordered_list(&scan, begin, length);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static void finish_group(const keyword_pass *pass, uint32_t term) {
|
|
202
|
+
keyword_scratch *scratch = pass->scratch;
|
|
203
|
+
for (uint32_t index = 0; index < scratch->group_touched_count; index++) {
|
|
204
|
+
uint32_t ordinal = scratch->group_touched[index];
|
|
205
|
+
touch(pass, ordinal);
|
|
206
|
+
scratch->scores[ordinal] += scratch->group_best[ordinal];
|
|
207
|
+
cover(pass, ordinal, term);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static uint32_t slot_word(const narsil_keyword_request *request, uint32_t slot, uint32_t word) {
|
|
212
|
+
return request->slots[((size_t)slot * NARSIL_KEYWORD_SLOT_STRIDE) + word];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
static double list_idf(const narsil_keyword_request *request, uint32_t list) {
|
|
216
|
+
return keyword_idf(keyword_list_value(request, list, NARSIL_KEYWORD_LIST_DOCUMENT_FREQUENCY),
|
|
217
|
+
request->total_documents);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
uint32_t keyword_score_every_slot(const keyword_pass *pass) {
|
|
221
|
+
const narsil_keyword_request *request = pass->request;
|
|
222
|
+
double total_documents = request->total_documents;
|
|
223
|
+
keyword_begin(pass->scratch);
|
|
224
|
+
uint32_t list_from = 0;
|
|
225
|
+
uint32_t value_from = 0;
|
|
226
|
+
for (uint32_t slot = 0; slot < request->slot_count; slot++) {
|
|
227
|
+
uint32_t kind = slot_word(request, slot, NARSIL_KEYWORD_SLOT_KIND);
|
|
228
|
+
uint32_t term = slot_word(request, slot, NARSIL_KEYWORD_SLOT_TERM);
|
|
229
|
+
uint32_t list_end = slot_word(request, slot, NARSIL_KEYWORD_SLOT_LIST_END);
|
|
230
|
+
uint32_t value_end = slot_word(request, slot, NARSIL_KEYWORD_SLOT_VALUE_END);
|
|
231
|
+
keyword_run run = {0, 0, 0, term, 0, 0};
|
|
232
|
+
if (kind == NARSIL_KEYWORD_TERM_SLOT) {
|
|
233
|
+
run.has_term = 1;
|
|
234
|
+
for (uint32_t list = list_from; list < list_end; list++) {
|
|
235
|
+
run.idf = list_idf(request, list);
|
|
236
|
+
score_list(pass, &run, list);
|
|
237
|
+
}
|
|
238
|
+
} else if (kind == NARSIL_KEYWORD_GROUP_SLOT) {
|
|
239
|
+
run.member_mode = 1;
|
|
240
|
+
run.has_term = 1;
|
|
241
|
+
run.idf = keyword_idf(request->slot_values[value_from], total_documents);
|
|
242
|
+
keyword_begin_group(pass->scratch);
|
|
243
|
+
for (uint32_t list = list_from; list < list_end; list++) { score_list(pass, &run, list); }
|
|
244
|
+
finish_group(pass, term);
|
|
245
|
+
} else {
|
|
246
|
+
double idf = 0;
|
|
247
|
+
for (uint32_t value = value_from; value < value_end; value++) {
|
|
248
|
+
idf += keyword_idf(request->slot_values[value], total_documents);
|
|
249
|
+
}
|
|
250
|
+
run.idf = idf;
|
|
251
|
+
for (uint32_t list = list_from; list < list_end; list++) { score_list(pass, &run, list); }
|
|
252
|
+
}
|
|
253
|
+
list_from = list_end;
|
|
254
|
+
value_from = value_end;
|
|
255
|
+
}
|
|
256
|
+
return keyword_select_kept(pass);
|
|
257
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#ifndef NARSIL_KEYWORD_SCORE_H
|
|
2
|
+
#define NARSIL_KEYWORD_SCORE_H
|
|
3
|
+
|
|
4
|
+
#include "pass.h"
|
|
5
|
+
#include "rows.h"
|
|
6
|
+
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
|
|
9
|
+
#define KEYWORD_NOT_PRUNED UINT32_MAX
|
|
10
|
+
|
|
11
|
+
void keyword_list_keys(const keyword_pass *pass, uint32_t list, keyword_row_keys *keys);
|
|
12
|
+
const uint32_t *keyword_rank_ordered_run(const keyword_pass *pass, const keyword_row_keys *keys, uint32_t begin,
|
|
13
|
+
uint32_t count);
|
|
14
|
+
uint32_t keyword_score_every_slot(const keyword_pass *pass);
|
|
15
|
+
uint32_t keyword_score_pruned(const keyword_pass *pass);
|
|
16
|
+
|
|
17
|
+
#endif
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
#include "scratch.h"
|
|
2
|
+
|
|
3
|
+
#include "../internal.h"
|
|
4
|
+
|
|
5
|
+
#include "../../include/narsil_core.h"
|
|
6
|
+
|
|
7
|
+
#include <stddef.h>
|
|
8
|
+
#include <stdint.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include <string.h>
|
|
11
|
+
|
|
12
|
+
#define FIRST_ORDER_CAPACITY 256U
|
|
13
|
+
#define FIRST_SELECTION_CAPACITY 16U
|
|
14
|
+
#define FIRST_LIST_CAPACITY 16U
|
|
15
|
+
#define MAX_GENERATION INT32_MAX
|
|
16
|
+
#define BITS_PER_WORD 32U
|
|
17
|
+
#define BITSETS_PER_SCRATCH 3U
|
|
18
|
+
#define TOUCHED_SPARE_ENTRIES 1U
|
|
19
|
+
|
|
20
|
+
static void *allocation(size_t count, size_t size) {
|
|
21
|
+
if (count == 0 || count > SIZE_MAX / size) { return NULL; }
|
|
22
|
+
return malloc(count * size);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static void *zeroed_allocation(size_t count, size_t size) {
|
|
26
|
+
if (count == 0) { return NULL; }
|
|
27
|
+
return calloc(count, size);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void keyword_scratch_release(keyword_scratch *scratch) {
|
|
31
|
+
free(scratch->scores);
|
|
32
|
+
free(scratch->stamps);
|
|
33
|
+
free(scratch->touched);
|
|
34
|
+
free(scratch->scorable);
|
|
35
|
+
free(scratch->seen_bits);
|
|
36
|
+
free(scratch->counted_bits);
|
|
37
|
+
free(scratch->covered);
|
|
38
|
+
free(scratch->last_term);
|
|
39
|
+
free(scratch->group_best);
|
|
40
|
+
free(scratch->group_stamps);
|
|
41
|
+
free(scratch->group_touched);
|
|
42
|
+
free(scratch->order);
|
|
43
|
+
free(scratch->order_spare);
|
|
44
|
+
free(scratch->selection);
|
|
45
|
+
free(scratch->list_order);
|
|
46
|
+
free(scratch->list_bounds);
|
|
47
|
+
free(scratch->list_idfs);
|
|
48
|
+
free(scratch->remaining_bounds);
|
|
49
|
+
memset(scratch, 0, sizeof *scratch);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
size_t keyword_scratch_bytes(const keyword_scratch *scratch) {
|
|
53
|
+
size_t per_ordinal = sizeof(double) + sizeof(int32_t) + sizeof(uint32_t);
|
|
54
|
+
size_t per_covered = 2 * sizeof(uint32_t);
|
|
55
|
+
size_t per_group = sizeof(double) + sizeof(int32_t) + sizeof(uint32_t);
|
|
56
|
+
size_t per_list = sizeof(uint32_t) + (3 * sizeof(double));
|
|
57
|
+
size_t remaining_end = scratch->list_capacity > 0 ? sizeof(double) : 0;
|
|
58
|
+
size_t bitset_words = (size_t)(scratch->capacity / BITS_PER_WORD) + 1;
|
|
59
|
+
size_t ordinal_extras =
|
|
60
|
+
scratch->capacity > 0 ? sizeof(uint32_t) * ((BITSETS_PER_SCRATCH * bitset_words) + TOUCHED_SPARE_ENTRIES) : 0;
|
|
61
|
+
return ((size_t)scratch->capacity * per_ordinal) + ordinal_extras +
|
|
62
|
+
((size_t)scratch->coverage_capacity * per_covered) + ((size_t)scratch->group_capacity * per_group) +
|
|
63
|
+
((size_t)scratch->order_capacity * 2 * sizeof(uint32_t)) +
|
|
64
|
+
((size_t)scratch->selection_capacity * sizeof(double)) + ((size_t)scratch->list_capacity * per_list) +
|
|
65
|
+
remaining_end;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static narsil_status reserve_ordinals(keyword_scratch *scratch, uint32_t capacity) {
|
|
69
|
+
if (capacity <= scratch->capacity) { return NARSIL_OK; }
|
|
70
|
+
size_t bitset_words = (size_t)(capacity / BITS_PER_WORD) + 1;
|
|
71
|
+
double *scores = zeroed_allocation(capacity, sizeof *scores);
|
|
72
|
+
int32_t *stamps = zeroed_allocation(capacity, sizeof *stamps);
|
|
73
|
+
uint32_t *touched = allocation((size_t)capacity + TOUCHED_SPARE_ENTRIES, sizeof *touched);
|
|
74
|
+
uint32_t *scorable = allocation(bitset_words, sizeof *scorable);
|
|
75
|
+
uint32_t *seen_bits = allocation(bitset_words, sizeof *seen_bits);
|
|
76
|
+
uint32_t *counted_bits = allocation(bitset_words, sizeof *counted_bits);
|
|
77
|
+
if (scores == NULL || stamps == NULL || touched == NULL || scorable == NULL || seen_bits == NULL ||
|
|
78
|
+
counted_bits == NULL) {
|
|
79
|
+
free(scores);
|
|
80
|
+
free(stamps);
|
|
81
|
+
free(touched);
|
|
82
|
+
free(scorable);
|
|
83
|
+
free(seen_bits);
|
|
84
|
+
free(counted_bits);
|
|
85
|
+
return NARSIL_OUT_OF_MEMORY;
|
|
86
|
+
}
|
|
87
|
+
free(scratch->scores);
|
|
88
|
+
free(scratch->stamps);
|
|
89
|
+
free(scratch->touched);
|
|
90
|
+
free(scratch->scorable);
|
|
91
|
+
free(scratch->seen_bits);
|
|
92
|
+
free(scratch->counted_bits);
|
|
93
|
+
scratch->scores = scores;
|
|
94
|
+
scratch->stamps = stamps;
|
|
95
|
+
scratch->touched = touched;
|
|
96
|
+
scratch->scorable = scorable;
|
|
97
|
+
scratch->seen_bits = seen_bits;
|
|
98
|
+
scratch->counted_bits = counted_bits;
|
|
99
|
+
scratch->capacity = capacity;
|
|
100
|
+
scratch->generation = 0;
|
|
101
|
+
return NARSIL_OK;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
static narsil_status reserve_coverage(keyword_scratch *scratch, uint32_t capacity) {
|
|
105
|
+
if (capacity <= scratch->coverage_capacity) { return NARSIL_OK; }
|
|
106
|
+
uint32_t *covered = allocation(capacity, sizeof *covered);
|
|
107
|
+
uint32_t *last_term = allocation(capacity, sizeof *last_term);
|
|
108
|
+
if (covered == NULL || last_term == NULL) {
|
|
109
|
+
free(covered);
|
|
110
|
+
free(last_term);
|
|
111
|
+
return NARSIL_OUT_OF_MEMORY;
|
|
112
|
+
}
|
|
113
|
+
free(scratch->covered);
|
|
114
|
+
free(scratch->last_term);
|
|
115
|
+
scratch->covered = covered;
|
|
116
|
+
scratch->last_term = last_term;
|
|
117
|
+
scratch->coverage_capacity = capacity;
|
|
118
|
+
return NARSIL_OK;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static narsil_status reserve_groups(keyword_scratch *scratch, uint32_t capacity) {
|
|
122
|
+
if (capacity <= scratch->group_capacity) { return NARSIL_OK; }
|
|
123
|
+
double *best = allocation(capacity, sizeof *best);
|
|
124
|
+
int32_t *stamps = zeroed_allocation(capacity, sizeof *stamps);
|
|
125
|
+
uint32_t *touched = allocation(capacity, sizeof *touched);
|
|
126
|
+
if (best == NULL || stamps == NULL || touched == NULL) {
|
|
127
|
+
free(best);
|
|
128
|
+
free(stamps);
|
|
129
|
+
free(touched);
|
|
130
|
+
return NARSIL_OUT_OF_MEMORY;
|
|
131
|
+
}
|
|
132
|
+
free(scratch->group_best);
|
|
133
|
+
free(scratch->group_stamps);
|
|
134
|
+
free(scratch->group_touched);
|
|
135
|
+
scratch->group_best = best;
|
|
136
|
+
scratch->group_stamps = stamps;
|
|
137
|
+
scratch->group_touched = touched;
|
|
138
|
+
scratch->group_capacity = capacity;
|
|
139
|
+
scratch->group_generation = 0;
|
|
140
|
+
return NARSIL_OK;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static narsil_status reserve_order(keyword_scratch *scratch, uint32_t needed) {
|
|
144
|
+
if (needed <= scratch->order_capacity) { return NARSIL_OK; }
|
|
145
|
+
uint32_t capacity = grown_capacity(FIRST_ORDER_CAPACITY, needed);
|
|
146
|
+
uint32_t *order = allocation(capacity, sizeof *order);
|
|
147
|
+
uint32_t *spare = allocation(capacity, sizeof *spare);
|
|
148
|
+
if (order == NULL || spare == NULL) {
|
|
149
|
+
free(order);
|
|
150
|
+
free(spare);
|
|
151
|
+
return NARSIL_OUT_OF_MEMORY;
|
|
152
|
+
}
|
|
153
|
+
free(scratch->order);
|
|
154
|
+
free(scratch->order_spare);
|
|
155
|
+
scratch->order = order;
|
|
156
|
+
scratch->order_spare = spare;
|
|
157
|
+
scratch->order_capacity = capacity;
|
|
158
|
+
return NARSIL_OK;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static narsil_status reserve_selection(keyword_scratch *scratch, uint32_t needed) {
|
|
162
|
+
if (needed <= scratch->selection_capacity) { return NARSIL_OK; }
|
|
163
|
+
uint32_t capacity = grown_capacity(FIRST_SELECTION_CAPACITY, needed);
|
|
164
|
+
double *selection = allocation(capacity, sizeof *selection);
|
|
165
|
+
if (selection == NULL) { return NARSIL_OUT_OF_MEMORY; }
|
|
166
|
+
free(scratch->selection);
|
|
167
|
+
scratch->selection = selection;
|
|
168
|
+
scratch->selection_capacity = capacity;
|
|
169
|
+
return NARSIL_OK;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
static narsil_status reserve_lists(keyword_scratch *scratch, uint32_t needed) {
|
|
173
|
+
if (needed <= scratch->list_capacity) { return NARSIL_OK; }
|
|
174
|
+
uint32_t capacity = grown_capacity(FIRST_LIST_CAPACITY, needed);
|
|
175
|
+
uint32_t *order = allocation(capacity, sizeof *order);
|
|
176
|
+
double *bounds = allocation(capacity, sizeof *bounds);
|
|
177
|
+
double *idfs = allocation(capacity, sizeof *idfs);
|
|
178
|
+
double *remaining = allocation((size_t)capacity + 1, sizeof *remaining);
|
|
179
|
+
if (order == NULL || bounds == NULL || idfs == NULL || remaining == NULL) {
|
|
180
|
+
free(order);
|
|
181
|
+
free(bounds);
|
|
182
|
+
free(idfs);
|
|
183
|
+
free(remaining);
|
|
184
|
+
return NARSIL_OUT_OF_MEMORY;
|
|
185
|
+
}
|
|
186
|
+
free(scratch->list_order);
|
|
187
|
+
free(scratch->list_bounds);
|
|
188
|
+
free(scratch->list_idfs);
|
|
189
|
+
free(scratch->remaining_bounds);
|
|
190
|
+
scratch->list_order = order;
|
|
191
|
+
scratch->list_bounds = bounds;
|
|
192
|
+
scratch->list_idfs = idfs;
|
|
193
|
+
scratch->remaining_bounds = remaining;
|
|
194
|
+
scratch->list_capacity = capacity;
|
|
195
|
+
return NARSIL_OK;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
narsil_status keyword_reserve(keyword_scratch *scratch, const keyword_needs *needs) {
|
|
199
|
+
narsil_status status = reserve_ordinals(scratch, needs->capacity);
|
|
200
|
+
if (status == NARSIL_OK && needs->coverage) { status = reserve_coverage(scratch, needs->capacity); }
|
|
201
|
+
if (status == NARSIL_OK && needs->groups) { status = reserve_groups(scratch, needs->capacity); }
|
|
202
|
+
if (status == NARSIL_OK) { status = reserve_order(scratch, needs->order); }
|
|
203
|
+
if (status == NARSIL_OK) { status = reserve_selection(scratch, needs->selection); }
|
|
204
|
+
if (status == NARSIL_OK) { status = reserve_lists(scratch, needs->lists); }
|
|
205
|
+
return status;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
void keyword_begin(keyword_scratch *scratch) {
|
|
209
|
+
if (scratch->generation >= MAX_GENERATION) {
|
|
210
|
+
if (scratch->capacity > 0) { memset(scratch->stamps, 0, (size_t)scratch->capacity * sizeof *scratch->stamps); }
|
|
211
|
+
scratch->generation = 0;
|
|
212
|
+
}
|
|
213
|
+
scratch->generation++;
|
|
214
|
+
scratch->touched_count = 0;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
void keyword_begin_group(keyword_scratch *scratch) {
|
|
218
|
+
if (scratch->group_generation >= MAX_GENERATION) {
|
|
219
|
+
if (scratch->group_capacity > 0) {
|
|
220
|
+
memset(scratch->group_stamps, 0, (size_t)scratch->group_capacity * sizeof *scratch->group_stamps);
|
|
221
|
+
}
|
|
222
|
+
scratch->group_generation = 0;
|
|
223
|
+
}
|
|
224
|
+
scratch->group_generation++;
|
|
225
|
+
scratch->group_touched_count = 0;
|
|
226
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#ifndef NARSIL_KEYWORD_SCRATCH_H
|
|
2
|
+
#define NARSIL_KEYWORD_SCRATCH_H
|
|
3
|
+
|
|
4
|
+
#include "../../include/narsil_core.h"
|
|
5
|
+
|
|
6
|
+
#include <stddef.h>
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
|
|
9
|
+
typedef struct {
|
|
10
|
+
double *scores;
|
|
11
|
+
int32_t *stamps;
|
|
12
|
+
uint32_t *touched;
|
|
13
|
+
uint32_t *scorable;
|
|
14
|
+
uint32_t *seen_bits;
|
|
15
|
+
uint32_t *counted_bits;
|
|
16
|
+
uint32_t capacity;
|
|
17
|
+
int32_t generation;
|
|
18
|
+
uint32_t touched_count;
|
|
19
|
+
uint32_t *covered;
|
|
20
|
+
uint32_t *last_term;
|
|
21
|
+
uint32_t coverage_capacity;
|
|
22
|
+
double *group_best;
|
|
23
|
+
int32_t *group_stamps;
|
|
24
|
+
uint32_t *group_touched;
|
|
25
|
+
uint32_t group_capacity;
|
|
26
|
+
int32_t group_generation;
|
|
27
|
+
uint32_t group_touched_count;
|
|
28
|
+
uint32_t *order;
|
|
29
|
+
uint32_t *order_spare;
|
|
30
|
+
uint32_t order_capacity;
|
|
31
|
+
double *selection;
|
|
32
|
+
uint32_t selection_capacity;
|
|
33
|
+
uint32_t *list_order;
|
|
34
|
+
double *list_bounds;
|
|
35
|
+
double *list_idfs;
|
|
36
|
+
double *remaining_bounds;
|
|
37
|
+
uint32_t list_capacity;
|
|
38
|
+
} keyword_scratch;
|
|
39
|
+
|
|
40
|
+
typedef struct {
|
|
41
|
+
uint32_t capacity;
|
|
42
|
+
int coverage;
|
|
43
|
+
int groups;
|
|
44
|
+
uint32_t order;
|
|
45
|
+
uint32_t selection;
|
|
46
|
+
uint32_t lists;
|
|
47
|
+
} keyword_needs;
|
|
48
|
+
|
|
49
|
+
void keyword_scratch_release(keyword_scratch *scratch);
|
|
50
|
+
size_t keyword_scratch_bytes(const keyword_scratch *scratch);
|
|
51
|
+
narsil_status keyword_reserve(keyword_scratch *scratch, const keyword_needs *needs);
|
|
52
|
+
void keyword_begin(keyword_scratch *scratch);
|
|
53
|
+
void keyword_begin_group(keyword_scratch *scratch);
|
|
54
|
+
|
|
55
|
+
#endif
|