-
Notifications
You must be signed in to change notification settings - Fork 20
/
compilation_ctx.h
165 lines (127 loc) · 5.61 KB
/
compilation_ctx.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#pragma once
#include "common.h"
#include "queries.h"
#include "runtime.h"
#include <switch_mallocators.h>
namespace Trinity {
enum class ENT : uint8_t {
matchterm = 0,
constfalse,
consttrue,
dummyop,
matchallterms,
matchanyterms,
unaryand,
unarynot,
matchanyphrases,
matchallphrases,
matchphrase,
consttrueexpr,
logicaland,
logicalnot,
logicalor,
matchsome,
// matchallnodes and matchanynodes are handled by the compiler/optimizer, though
// no exec. nodes of that type are generated during compilation.
matchallnodes,
matchanynodes,
SPECIALIMPL_COLLECTION_LOGICALOR,
SPECIALIMPL_COLLECTION_LOGICALAND,
};
struct exec_node final {
ENT fp;
union {
void * ptr;
uint32_t u32;
uint16_t u16;
};
// cost is computed by reorder_execnode()
// and we keep track of this here so that we can make some higher level optimizations later
uint64_t cost;
};
struct compilation_ctx {
simple_allocator allocator{4096 * 6};
simple_allocator runsAllocator{4096}, ctxAllocator{4096};
std::vector<void *> large_allocs;
~compilation_ctx() {
for (auto p : large_allocs)
std::free(p);
}
void *allocate(const std::size_t size) {
if (ctxAllocator.can_allocate(size))
return ctxAllocator.Alloc(size);
else {
auto ptr = malloc(size);
large_allocs.emplace_back(ptr);
return ptr;
}
}
struct partial_match_ctx final {
uint16_t size;
uint16_t min;
exec_node nodes[0];
};
struct nodes_group final {
uint16_t size;
exec_node nodes[0];
};
struct termsrun final {
uint16_t size;
exec_term_id_t terms[0];
static_assert(std::numeric_limits<decltype(size)>::max() >= Limits::MaxTermLength);
bool operator==(const termsrun &o) const noexcept;
bool is_set(const exec_term_id_t id) const noexcept;
bool erase(const exec_term_id_t id) noexcept;
bool erase(const termsrun &o);
auto empty() const noexcept {
return !size;
}
};
struct cacheable_termsrun final {
isrc_docid_t lastConsideredDID;
const termsrun *run;
bool res;
};
struct phrase final {
uint8_t size;
exec_term_id_t termIDs[0];
static_assert(std::numeric_limits<decltype(size)>::max() >= Trinity::Limits::MaxPhraseSize);
uint8_t intersection(const termsrun *const tr, exec_term_id_t *const out) const noexcept;
// returns terms found in run, but missing from this phrase
uint8_t disjoint_union(const termsrun *const tr, exec_term_id_t *const out) const noexcept;
bool intersected_by(const termsrun *const tr) const noexcept;
bool operator==(const phrase &o) const noexcept;
bool is_set(const exec_term_id_t id) const noexcept;
bool is_set(const exec_term_id_t *const l, const uint8_t n) const noexcept;
};
struct phrasesrun final {
uint16_t size;
phrase * phrases[0];
};
struct binop_ctx final {
exec_node lhs;
exec_node rhs;
};
struct unaryop_ctx final {
exec_node expr;
};
inline uint16_t register_token(const Trinity::phrase *p) {
return resolve_query_term(p->terms[0].token);
}
phrase *register_phrase(const Trinity::phrase *p);
binop_ctx *register_binop(const exec_node lhs, const exec_node rhs) {
auto ptr = ctxAllocator.New<binop_ctx>();
ptr->lhs = lhs;
ptr->rhs = rhs;
return ptr;
}
unaryop_ctx *register_unaryop(const exec_node expr) {
auto ptr = ctxAllocator.New<unaryop_ctx>();
ptr->expr = expr;
return ptr;
}
virtual uint16_t resolve_query_term(const str8_t term) = 0;
};
exec_node compile_query(ast_node *root, compilation_ctx &cctx);
void group_execnodes(exec_node &, simple_allocator &);
} // namespace Trinity