#include <Relation.h>
Definition at line 134 of file Relation.h.
◆ IndirectRelation()
◆ computeIndices()
void souffle::synthesiser::IndirectRelation::computeIndices |
( |
| ) |
|
|
override |
Generate index set for a indirect indexed relation.
Definition at line 513 of file Relation.cpp.
514 assert(!isProvenance &&
"indirect indexes cannot used for provenance");
520 assert(!inds.empty() &&
"no full index in relation");
523 for (
size_t i = 0;
i < inds.size();
i++) {
530 assert(masterIndex < inds.size() &&
"no full index in relation");
531 computedIndices = inds;
References i.
◆ generateTypeStruct()
void souffle::synthesiser::IndirectRelation::generateTypeStruct |
( |
std::ostream & |
out | ) |
|
|
override |
Generate type struct of a indirect indexed relation.
Definition at line 559 of file Relation.cpp.
561 const auto& inds = getIndices();
563 size_t numIndexes = inds.size();
564 std::map<MinIndexSelection::LexOrder, int> indexToNumMap;
568 out <<
"static constexpr Relation::arity_type Arity = " <<
arity <<
";\n";
571 out <<
"using t_tuple = Tuple<RamDomain, " <<
arity <<
">;\n";
574 out <<
"Table<t_tuple> dataTable;\n";
575 out <<
"Lock insert_lock;\n";
578 for (
size_t i = 0;
i < inds.size();
i++) {
581 if (
i < getMinIndexSelection().getAllOrders().
size()) {
582 indexToNumMap[getMinIndexSelection().getAllOrders()[
i]] =
i;
585 std::vector<std::string> typecasts;
586 typecasts.reserve(
types.size());
590 case 'f': typecasts.push_back(
"ramBitCast<RamFloat>");
break;
591 case 'u': typecasts.push_back(
"ramBitCast<RamUnsigned>");
break;
592 default: typecasts.push_back(
"ramBitCast<RamSigned>");
596 std::string
comparator =
"t_comparator_" + std::to_string(
i);
599 out <<
" int operator()(const t_tuple *a, const t_tuple *b) const {\n";
601 std::function<void(
size_t)> gencmp = [&](
size_t i) {
602 size_t attrib = ind[
i];
603 const auto& typecast = typecasts[attrib];
604 out <<
"(" << typecast <<
"((*a)[" << attrib <<
"]) <" << typecast <<
" ((*b)[" << attrib
605 <<
"])) ? -1 : ((" << typecast <<
"((*a)[" << attrib <<
"]) > " << typecast <<
"((*b)["
606 << attrib <<
"])) ? 1 :(";
607 if (
i + 1 < ind.size()) {
616 out <<
"bool less(const t_tuple *a, const t_tuple *b) const {\n";
618 std::function<void(
size_t)> genless = [&](
size_t i) {
619 size_t attrib = ind[
i];
620 const auto& typecast = typecasts[attrib];
621 out << typecast <<
" ((*a)[" << attrib <<
"]) < " << typecast <<
"((*b)[" << attrib <<
"])";
622 if (
i + 1 < ind.size()) {
623 out <<
"|| (" << typecast <<
"((*a)[" << attrib <<
"]) == " << typecast <<
"((*b)[" << attrib
631 out <<
"bool equal(const t_tuple *a, const t_tuple *b) const {\n";
633 std::function<void(
size_t)> geneq = [&](
size_t i) {
634 size_t attrib = ind[
i];
635 const auto& typecast = typecasts[attrib];
636 out << typecast <<
"((*a)[" << attrib <<
"]) == " << typecast <<
"((*b)[" << attrib <<
"])";
637 if (
i + 1 < ind.size()) {
646 if (ind.size() ==
arity) {
647 out <<
"using t_ind_" <<
i <<
" = btree_set<const t_tuple*," <<
comparator <<
">;\n";
649 out <<
"using t_ind_" <<
i <<
" = btree_multiset<const t_tuple*," <<
comparator <<
">;\n";
652 out <<
"t_ind_" <<
i <<
" ind_" <<
i <<
";\n";
656 for (
size_t i = 0;
i < numIndexes;
i++) {
657 out <<
"using iterator_" <<
i <<
" = IterDerefWrapper<typename t_ind_" <<
i <<
"::iterator>;\n";
659 out <<
"using iterator = iterator_" << masterIndex <<
";\n";
662 out <<
"struct context {\n";
663 for (
size_t i = 0;
i < numIndexes;
i++) {
664 out <<
"t_ind_" <<
i <<
"::operation_hints hints_" <<
i <<
"_lower;\n";
665 out <<
"t_ind_" <<
i <<
"::operation_hints hints_" <<
i <<
"_upper;\n";
668 out <<
"context createContext() { return context(); }\n";
671 out <<
"bool insert(const t_tuple& t) {\n";
672 out <<
"context h;\n";
673 out <<
"return insert(t, h);\n";
676 out <<
"bool insert(const t_tuple& t, context& h) {\n";
677 out <<
"const t_tuple* masterCopy = nullptr;\n";
679 out <<
"auto lease = insert_lock.acquire();\n";
680 out <<
"if (contains(t, h)) return false;\n";
681 out <<
"masterCopy = &dataTable.insert(t);\n";
682 out <<
"ind_" << masterIndex <<
".insert(masterCopy, h.hints_" << masterIndex <<
"_lower);\n";
684 for (
size_t i = 0;
i < numIndexes;
i++) {
685 if (
i != masterIndex) {
686 out <<
"ind_" <<
i <<
".insert(masterCopy, h.hints_" <<
i <<
"_lower"
690 out <<
"return true;\n";
693 out <<
"bool insert(const RamDomain* ramDomain) {\n";
694 out <<
"RamDomain data[" <<
arity <<
"];\n";
695 out <<
"std::copy(ramDomain, ramDomain + " <<
arity <<
", data);\n";
696 out <<
"const t_tuple& tuple = reinterpret_cast<const t_tuple&>(data);\n";
697 out <<
"context h;\n";
698 out <<
"return insert(tuple, h);\n";
701 std::vector<std::string> decls;
702 std::vector<std::string> params;
703 for (
size_t i = 0;
i <
arity;
i++) {
704 decls.push_back(
"RamDomain a" + std::to_string(
i));
705 params.push_back(
"a" + std::to_string(
i));
707 out <<
"bool insert(" <<
join(decls,
",") <<
") {\n";
708 out <<
"RamDomain data[" <<
arity <<
"] = {" <<
join(params,
",") <<
"};\n";
709 out <<
"return insert(data);\n";
713 out <<
"bool contains(const t_tuple& t, context& h) const {\n";
714 out <<
"return ind_" << masterIndex <<
".contains(&t, h.hints_" << masterIndex <<
"_lower"
718 out <<
"bool contains(const t_tuple& t) const {\n";
719 out <<
"context h;\n";
720 out <<
"return contains(t, h);\n";
724 out <<
"std::size_t size() const {\n";
725 out <<
"return ind_" << masterIndex <<
".size();\n";
729 out <<
"iterator find(const t_tuple& t, context& h) const {\n";
730 out <<
"return ind_" << masterIndex <<
".find(&t, h.hints_" << masterIndex <<
"_lower"
734 out <<
"iterator find(const t_tuple& t) const {\n";
735 out <<
"context h;\n";
736 out <<
"return find(t, h);\n";
740 out <<
"range<iterator> lowerUpperRange_0(const t_tuple& lower, const t_tuple& upper, context& h) const "
743 out <<
"return range<iterator>(ind_" << masterIndex <<
".begin(),ind_" << masterIndex <<
".end());\n";
746 out <<
"range<iterator> lowerUpperRange_0(const t_tuple& lower, const t_tuple& upper) const {\n";
748 out <<
"return range<iterator>(ind_" << masterIndex <<
".begin(),ind_" << masterIndex <<
".end());\n";
752 for (
auto search : getMinIndexSelection().getSearches()) {
753 auto& lexOrder = getMinIndexSelection().getLexOrder(search);
754 size_t indNum = indexToNumMap[lexOrder];
756 out <<
"range<iterator_" << indNum <<
"> lowerUpperRange_" << search;
757 out <<
"(const t_tuple& lower, const t_tuple& upper, context& h) const {\n";
761 for (
size_t column = 0; column <
arity; column++) {
762 if (search[column] == analysis::AttributeConstraint::Equal) {
767 out <<
"t_comparator_" << indNum <<
" comparator;\n";
768 out <<
"int cmp = comparator(&lower, &upper);\n";
771 if (eqSize ==
arity) {
773 out <<
"if (cmp == 0) {\n";
774 out <<
" auto pos = find(lower, h);\n";
775 out <<
" auto fin = end();\n";
776 out <<
" if (pos != fin) {fin = pos; ++fin;}\n";
777 out <<
" return make_range(pos, fin);\n";
781 out <<
"if (cmp > 0) {\n";
782 out <<
" return range<iterator_" << indNum <<
">(ind_" << indNum <<
".end(), ind_" << indNum
787 out <<
"return range<iterator_" << indNum <<
">(ind_" << indNum <<
".lower_bound(&lower, h.hints_"
788 << indNum <<
"_lower"
789 <<
"), ind_" << indNum <<
".upper_bound(&upper, h.hints_" << indNum <<
"_upper"
794 out <<
"range<iterator_" << indNum <<
"> lowerUpperRange_" << search;
795 out <<
"(const t_tuple& lower, const t_tuple& upper) const {\n";
797 out <<
"context h;\n";
798 out <<
"return lowerUpperRange_" << search <<
"(lower, upper, h);\n";
803 out <<
"bool empty() const {\n";
804 out <<
"return ind_" << masterIndex <<
".empty();\n";
808 out <<
"std::vector<range<iterator>> partition() const {\n";
809 out <<
"std::vector<range<iterator>> res;\n";
810 out <<
"for (const auto& cur : ind_" << masterIndex <<
".getChunks(400)) {\n";
811 out <<
" res.push_back(make_range(derefIter(cur.begin()), derefIter(cur.end())));\n";
813 out <<
"return res;\n";
817 out <<
"void purge() {\n";
818 for (
size_t i = 0;
i < numIndexes;
i++) {
819 out <<
"ind_" <<
i <<
".clear();\n";
821 out <<
"dataTable.clear();\n";
825 out <<
"iterator begin() const {\n";
826 out <<
"return ind_" << masterIndex <<
".begin();\n";
829 out <<
"iterator end() const {\n";
830 out <<
"return ind_" << masterIndex <<
".end();\n";
834 out <<
"void printStatistics(std::ostream& o) const {\n";
835 for (
size_t i = 0;
i < numIndexes;
i++) {
836 out <<
"o << \" arity " <<
arity <<
" indirect b-tree index " <<
i <<
" lex-order " << inds[
i]
838 out <<
"ind_" <<
i <<
".printStats(o);\n";
References i, souffle::join(), relation, TCB_SPAN_NAMESPACE_NAME::detail::size(), and types.
◆ getTypeName()
std::string souffle::synthesiser::IndirectRelation::getTypeName |
( |
| ) |
|
|
override |
Generate type name of a indirect indexed relation.
Definition at line 535 of file Relation.cpp.
537 std::unordered_set<uint32_t> attributesUsed;
538 for (
auto& ind : getIndices()) {
539 for (
auto& attr : ind) {
540 attributesUsed.insert(attr);
544 std::stringstream res;
545 res <<
"t_btree_" << getTypeAttributeString(
relation.getAttributeTypes(), attributesUsed);
547 for (
auto& ind : getIndices()) {
548 res <<
"__" <<
join(ind,
"_");
551 for (
auto& search : getMinIndexSelection().getSearches()) {
552 res <<
"__" << search;
References souffle::join(), and relation.
The documentation for this class was generated from the following files:
Relation(std::string name, size_t arity, size_t auxiliaryArity, std::vector< std::string > attributeNames, std::vector< std::string > attributeTypes, RelationRepresentation representation)
detail::joined_sequence< Iter, Printer > join(const Iter &a, const Iter &b, const std::string &sep, const Printer &p)
Creates an object to be forwarded to some output stream for printing sequences of elements interspers...