Generate type struct of a direct indexed relation.
192 const auto& inds = getIndices();
193 size_t numIndexes = inds.size();
194 std::map<MinIndexSelection::LexOrder, int> indexToNumMap;
198 out <<
"static constexpr Relation::arity_type Arity = " <<
arity <<
";\n";
201 out <<
"using t_tuple = Tuple<RamDomain, " <<
arity <<
">;\n";
205 out <<
"struct updater_" <<
getTypeName() <<
" {\n";
206 out <<
"void update(t_tuple& old_t, const t_tuple& new_t) {\n";
209 out <<
"old_t[" <<
i <<
"] = new_t[" <<
i <<
"];\n";
217 for (
size_t i = 0;
i < inds.size();
i++) {
220 if (
i < getMinIndexSelection().getAllOrders().
size()) {
221 indexToNumMap[getMinIndexSelection().getAllOrders()[
i]] =
i;
224 std::vector<std::string> typecasts;
225 typecasts.reserve(
types.size());
229 case 'f': typecasts.push_back(
"ramBitCast<RamFloat>");
break;
230 case 'u': typecasts.push_back(
"ramBitCast<RamUnsigned>");
break;
231 default: typecasts.push_back(
"ramBitCast<RamSigned>");
235 auto genstruct = [&](std::string
name,
size_t bound) {
236 out <<
"struct " <<
name <<
"{\n";
237 out <<
" int operator()(const t_tuple& a, const t_tuple& b) const {\n";
239 std::function<void(
size_t)> gencmp = [&](
size_t i) {
240 size_t attrib = ind[
i];
241 const auto& typecast = typecasts[attrib];
243 out <<
"(" << typecast <<
"(a[" << attrib <<
"]) < " << typecast <<
"(b[" << attrib
244 <<
"])) ? -1 : (" << typecast <<
"(a[" << attrib <<
"]) > " << typecast <<
"(b[" << attrib
255 out <<
"bool less(const t_tuple& a, const t_tuple& b) const {\n";
257 std::function<void(
size_t)> genless = [&](
size_t i) {
258 size_t attrib = ind[
i];
259 const auto& typecast = typecasts[attrib];
261 out <<
"(" << typecast <<
"(a[" << attrib <<
"]) < " << typecast <<
"(b[" << attrib <<
"]))";
263 out <<
"|| (" << typecast <<
"(a[" << attrib <<
"]) == " << typecast <<
"(b[" << attrib
271 out <<
"bool equal(const t_tuple& a, const t_tuple& b) const {\n";
273 std::function<void(
size_t)> geneq = [&](
size_t i) {
274 size_t attrib = ind[
i];
275 const auto& typecast = typecasts[attrib];
277 out <<
"(" << typecast <<
"(a[" << attrib <<
"]) == " << typecast <<
"(b[" << attrib <<
"]))";
288 std::string
comparator =
"t_comparator_" + std::to_string(
i);
295 std::string comparator_aux;
296 if (provenanceIndexNumbers.find(
i) == provenanceIndexNumbers.end()) {
298 comparator_aux =
"t_comparator_" + std::to_string(
i) +
"_aux";
304 out <<
"using t_ind_" <<
i <<
" = btree_set<t_tuple," <<
comparator
305 <<
",std::allocator<t_tuple>,256,typename "
306 "souffle::detail::default_strategy<t_tuple>::type,"
307 << comparator_aux <<
",updater_" <<
getTypeName() <<
">;\n";
309 if (ind.size() ==
arity) {
310 out <<
"using t_ind_" <<
i <<
" = btree_set<t_tuple," <<
comparator <<
">;\n";
313 out <<
"using t_ind_" <<
i <<
" = btree_multiset<t_tuple," <<
comparator <<
">;\n";
316 out <<
"t_ind_" <<
i <<
" ind_" <<
i <<
";\n";
320 out <<
"using iterator = t_ind_" << masterIndex <<
"::iterator;\n";
323 out <<
"struct context {\n";
324 for (
size_t i = 0;
i < numIndexes;
i++) {
325 out <<
"t_ind_" <<
i <<
"::operation_hints hints_" <<
i <<
"_lower"
327 out <<
"t_ind_" <<
i <<
"::operation_hints hints_" <<
i <<
"_upper"
331 out <<
"context createContext() { return context(); }\n";
334 out <<
"bool insert(const t_tuple& t) {\n";
335 out <<
"context h;\n";
336 out <<
"return insert(t, h);\n";
339 out <<
"bool insert(const t_tuple& t, context& h) {\n";
340 out <<
"if (ind_" << masterIndex <<
".insert(t, h.hints_" << masterIndex <<
"_lower"
342 for (
size_t i = 0;
i < numIndexes;
i++) {
343 if (
i != masterIndex && provenanceIndexNumbers.find(
i) == provenanceIndexNumbers.end()) {
344 out <<
"ind_" <<
i <<
".insert(t, h.hints_" <<
i <<
"_lower"
348 out <<
"return true;\n";
349 out <<
"} else return false;\n";
352 out <<
"bool insert(const RamDomain* ramDomain) {\n";
353 out <<
"RamDomain data[" <<
arity <<
"];\n";
354 out <<
"std::copy(ramDomain, ramDomain + " <<
arity <<
", data);\n";
355 out <<
"const t_tuple& tuple = reinterpret_cast<const t_tuple&>(data);\n";
356 out <<
"context h;\n";
357 out <<
"return insert(tuple, h);\n";
360 std::vector<std::string> decls;
361 std::vector<std::string> params;
362 for (
size_t i = 0;
i <
arity;
i++) {
363 decls.push_back(
"RamDomain a" + std::to_string(
i));
364 params.push_back(
"a" + std::to_string(
i));
366 out <<
"bool insert(" <<
join(decls,
",") <<
") {\n";
367 out <<
"RamDomain data[" <<
arity <<
"] = {" <<
join(params,
",") <<
"};\n";
368 out <<
"return insert(data);\n";
372 out <<
"bool contains(const t_tuple& t, context& h) const {\n";
373 out <<
"return ind_" << masterIndex <<
".contains(t, h.hints_" << masterIndex <<
"_lower"
377 out <<
"bool contains(const t_tuple& t) const {\n";
378 out <<
"context h;\n";
379 out <<
"return contains(t, h);\n";
383 out <<
"std::size_t size() const {\n";
384 out <<
"return ind_" << masterIndex <<
".size();\n";
388 out <<
"iterator find(const t_tuple& t, context& h) const {\n";
389 out <<
"return ind_" << masterIndex <<
".find(t, h.hints_" << masterIndex <<
"_lower"
393 out <<
"iterator find(const t_tuple& t) const {\n";
394 out <<
"context h;\n";
395 out <<
"return find(t, h);\n";
399 out <<
"range<iterator> lowerUpperRange_" << SearchSignature(
arity)
400 <<
"(const t_tuple& /* lower */, const t_tuple& /* upper */, context& /* h */) const "
403 out <<
"return range<iterator>(ind_" << masterIndex <<
".begin(),ind_" << masterIndex <<
".end());\n";
406 out <<
"range<iterator> lowerUpperRange_" << SearchSignature(
arity)
407 <<
"(const t_tuple& /* lower */, const t_tuple& /* upper */) const {\n";
409 out <<
"return range<iterator>(ind_" << masterIndex <<
".begin(),ind_" << masterIndex <<
".end());\n";
413 for (
auto search : getMinIndexSelection().getSearches()) {
414 auto& lexOrder = getMinIndexSelection().getLexOrder(search);
415 size_t indNum = indexToNumMap[lexOrder];
417 out <<
"range<t_ind_" << indNum <<
"::iterator> lowerUpperRange_" << search;
418 out <<
"(const t_tuple& lower, const t_tuple& upper, context& h) const {\n";
422 for (
size_t column = 0; column <
arity; column++) {
423 if (search[column] == analysis::AttributeConstraint::Equal) {
428 out <<
"t_comparator_" << indNum <<
" comparator;\n";
429 out <<
"int cmp = comparator(lower, upper);\n";
432 if (eqSize ==
arity) {
434 out <<
"if (cmp == 0) {\n";
435 out <<
" auto pos = ind_" << indNum <<
".find(lower, h.hints_" << indNum <<
"_lower);\n";
436 out <<
" auto fin = ind_" << indNum <<
".end();\n";
437 out <<
" if (pos != fin) {fin = pos; ++fin;}\n";
438 out <<
" return make_range(pos, fin);\n";
442 out <<
"if (cmp > 0) {\n";
443 out <<
" return make_range(ind_" << indNum <<
".end(), ind_" << indNum <<
".end());\n";
446 out <<
"return make_range(ind_" << indNum <<
".lower_bound(lower, h.hints_" << indNum <<
"_lower"
447 <<
"), ind_" << indNum <<
".upper_bound(upper, h.hints_" << indNum <<
"_upper"
452 out <<
"range<t_ind_" << indNum <<
"::iterator> lowerUpperRange_" << search;
453 out <<
"(const t_tuple& lower, const t_tuple& upper) const {\n";
455 out <<
"context h;\n";
456 out <<
"return lowerUpperRange_" << search <<
"(lower,upper,h);\n";
461 out <<
"bool empty() const {\n";
462 out <<
"return ind_" << masterIndex <<
".empty();\n";
466 out <<
"std::vector<range<iterator>> partition() const {\n";
467 out <<
"return ind_" << masterIndex <<
".getChunks(400);\n";
471 out <<
"void purge() {\n";
472 for (
size_t i = 0;
i < numIndexes;
i++) {
473 out <<
"ind_" <<
i <<
".clear();\n";
478 out <<
"iterator begin() const {\n";
479 out <<
"return ind_" << masterIndex <<
".begin();\n";
482 out <<
"iterator end() const {\n";
483 out <<
"return ind_" << masterIndex <<
".end();\n";
487 if (!provenanceIndexNumbers.empty()) {
488 out <<
"void copyIndex() {\n";
489 out <<
"for (auto const &cur : ind_" << masterIndex <<
") {\n";
490 for (
auto const i : provenanceIndexNumbers) {
491 out <<
"ind_" <<
i <<
".insert(cur);\n";
498 out <<
"void printStatistics(std::ostream& o) const {\n";
499 for (
size_t i = 0;
i < numIndexes;
i++) {
500 out <<
"o << \" arity " <<
arity <<
" direct b-tree index " <<
i <<
" lex-order " << inds[
i]
502 out <<
"ind_" <<
i <<
".printStats(o);\n";