souffle  2.0.2-371-g6315b36
Public Member Functions
souffle::synthesiser::BrieRelation Class Reference

#include <Relation.h>

Inheritance diagram for souffle::synthesiser::BrieRelation:
Inheritance graph
Collaboration diagram for souffle::synthesiser::BrieRelation:
Collaboration graph

Public Member Functions

 BrieRelation (const ram::Relation &ramRel, const MinIndexSelection &indexSet, bool isProvenance)
 
void computeIndices () override
 Generate index set for a brie relation. More...
 
void generateTypeStruct (std::ostream &out) override
 Generate type struct of a brie relation. More...
 
std::string getTypeName () override
 Generate type name of a brie relation. More...
 
- Public Member Functions inherited from souffle::ram::Relation
Relationclone () const override
 Create a clone (i.e. More...
 
unsigned getArity () const
 Get arity of relation. More...
 
const std::vector< std::string > & getAttributeNames () const
 Get attribute names. More...
 
const std::vector< std::string > & getAttributeTypes () const
 Get attribute types. More...
 
unsigned getAuxiliaryArity () const
 Get number of auxiliary attributes. More...
 
const std::string & getName () const
 Get name. More...
 
RelationRepresentation getRepresentation () const
 Relation representation type. More...
 
bool isNullary () const
 Is nullary relation. More...
 
bool isTemp () const
 Is temporary relation (for semi-naive evaluation) More...
 
bool operator< (const Relation &other) const
 Compare two relations via their name. More...
 
 Relation (std::string name, size_t arity, size_t auxiliaryArity, std::vector< std::string > attributeNames, std::vector< std::string > attributeTypes, RelationRepresentation representation)
 
- Public Member Functions inherited from souffle::ram::Node
virtual void apply (const NodeMapper &)
 Apply the mapper to all child nodes. More...
 
virtual std::vector< const Node * > getChildNodes () const
 Obtain list of all embedded child nodes. More...
 
bool operator!= (const Node &other) const
 Inequality check for two RAM nodes. More...
 
bool operator== (const Node &other) const
 Equivalence check for two RAM nodes. More...
 
virtual void rewrite (const Node *oldNode, Own< Node > newNode)
 Rewrite a child node. More...
 
virtual ~Node ()=default
 

Additional Inherited Members

- Protected Member Functions inherited from souffle::ram::Relation
bool equal (const Node &node) const override
 Equality check for two RAM nodes. More...
 
void print (std::ostream &out) const override
 Print RAM node. More...
 
- Protected Attributes inherited from souffle::ram::Relation
const size_t arity
 Arity, i.e., number of attributes. More...
 
const std::vector< std::string > attributeNames
 Name of attributes. More...
 
const std::vector< std::string > attributeTypes
 Type of attributes. More...
 
const size_t auxiliaryArity
 Number of auxiliary attributes (e.g. More...
 
const std::string name
 Name of relation. More...
 
const RelationRepresentation representation
 Data-structure representation. More...
 

Detailed Description

Definition at line 144 of file Relation.h.

Constructor & Destructor Documentation

◆ BrieRelation()

souffle::synthesiser::BrieRelation::BrieRelation ( const ram::Relation ramRel,
const MinIndexSelection indexSet,
bool  isProvenance 
)
inline

Definition at line 146 of file Relation.h.

147  : Relation(ramRel, indexSet, isProvenance) {}

Member Function Documentation

◆ computeIndices()

void souffle::synthesiser::BrieRelation::computeIndices ( )
override

Generate index set for a brie relation.

Definition at line 849 of file Relation.cpp.

849  {
850  assert(!isProvenance && "bries cannot be used with provenance");
851 
852  // Generate and set indices
853  MinIndexSelection::OrderCollection inds = indices.getAllOrders();
854 
855  // generate a full index if no indices exist
856  assert(!inds.empty() && "No full index in relation");
857 
858  // expand all indexes to be full
859  for (auto& ind : inds) {
860  if (ind.size() != getArity()) {
861  // use a set as a cache for fast lookup
862  std::set<int> curIndexElems(ind.begin(), ind.end());
863 
864  // expand index to be full
865  for (size_t i = 0; i < getArity(); i++) {
866  if (curIndexElems.find(i) == curIndexElems.end()) {
867  ind.push_back(i);
868  }
869  }
870  }
871 
872  assert(ind.size() == getArity() && "index is not a full");
873  }
874  masterIndex = 0;
875 
876  computedIndices = inds;
877 }

References i.

◆ generateTypeStruct()

void souffle::synthesiser::BrieRelation::generateTypeStruct ( std::ostream &  out)
override

Generate type struct of a brie relation.

Definition at line 904 of file Relation.cpp.

904  {
905  size_t arity = getArity();
906  const auto& inds = getIndices();
907  size_t numIndexes = inds.size();
908  std::map<MinIndexSelection::LexOrder, int> indexToNumMap;
909 
910  // struct definition
911  out << "struct " << getTypeName() << " {\n";
912  out << "static constexpr Relation::arity_type Arity = " << arity << ";\n";
913 
914  // define trie structures
915  for (size_t i = 0; i < inds.size(); i++) {
916  if (i < getMinIndexSelection().getAllOrders().size()) {
917  indexToNumMap[getMinIndexSelection().getAllOrders()[i]] = i;
918  }
919  out << "using t_ind_" << i << " = Trie<" << inds[i].size() << ">;\n";
920  out << "t_ind_" << i << " ind_" << i << ";\n";
921  }
922  out << "using t_tuple = t_ind_" << masterIndex << "::entry_type;\n";
923 
924  // generate auxiliary iterators that use orderOut
925  for (size_t i = 0; i < numIndexes; i++) {
926  // generate auxiliary iterators which orderOut
927  out << "class iterator_" << i << " : public std::iterator<std::forward_iterator_tag, t_tuple> {\n";
928  out << " using nested_iterator = typename t_ind_" << i << "::iterator;\n";
929  out << " nested_iterator nested;\n";
930  out << " t_tuple value;\n";
931 
932  out << "public:\n";
933  out << " iterator_" << i << "() = default;\n";
934  out << " iterator_" << i << "(const nested_iterator& iter) : nested(iter), value(orderOut_" << i
935  << "(*iter)) {}\n";
936  out << " iterator_" << i << "(const iterator_" << i << "& other) = default;\n";
937  out << " iterator_" << i << "& operator=(const iterator_" << i << "& other) = default;\n";
938 
939  out << " bool operator==(const iterator_" << i << "& other) const {\n";
940  out << " return nested == other.nested;\n";
941  out << " }\n";
942 
943  out << " bool operator!=(const iterator_" << i << "& other) const {\n";
944  out << " return !(*this == other);\n";
945  out << " }\n";
946 
947  out << " const t_tuple& operator*() const {\n";
948  out << " return value;\n";
949  out << " }\n";
950 
951  out << " const t_tuple* operator->() const {\n";
952  out << " return &value;\n";
953  out << " }\n";
954 
955  out << " iterator_" << i << "& operator++() {\n";
956  out << " ++nested;\n";
957  out << " value = orderOut_" << i << "(*nested);\n";
958  out << " return *this;\n";
959  out << " }\n";
960  out << "};\n";
961  }
962  out << "using iterator = iterator_" << masterIndex << ";\n";
963 
964  // hints struct
965  out << "struct context {\n";
966  for (size_t i = 0; i < numIndexes; i++) {
967  out << "t_ind_" << i << "::op_context hints_" << i << ";\n";
968  }
969  out << "};\n";
970  out << "context createContext() { return context(); }\n";
971 
972  // insert methods
973  out << "bool insert(const t_tuple& t) {\n";
974  out << "context h;\n";
975  out << "return insert(t, h);\n";
976  out << "}\n";
977 
978  out << "bool insert(const t_tuple& t, context& h) {\n";
979  out << "if (ind_" << masterIndex << ".insert(orderIn_" << masterIndex << "(t), h.hints_" << masterIndex
980  << ")) {\n";
981  for (size_t i = 0; i < numIndexes; i++) {
982  if (i != masterIndex) {
983  out << "ind_" << i << ".insert(orderIn_" << i << "(t), h.hints_" << i << ");\n";
984  }
985  }
986  out << "return true;\n";
987  out << "} else return false;\n";
988  out << "}\n";
989 
990  out << "bool insert(const RamDomain* ramDomain) {\n";
991  out << "RamDomain data[" << arity << "];\n";
992  out << "std::copy(ramDomain, ramDomain + " << arity << ", data);\n";
993  out << "const t_tuple& tuple = reinterpret_cast<const t_tuple&>(data);\n";
994  out << "context h;\n";
995  out << "return insert(tuple, h);\n";
996  out << "}\n";
997 
998  // insert method
999  std::vector<std::string> decls;
1000  std::vector<std::string> params;
1001  for (size_t i = 0; i < arity; i++) {
1002  decls.push_back("RamDomain a" + std::to_string(i));
1003  params.push_back("a" + std::to_string(i));
1004  }
1005  out << "bool insert(" << join(decls, ",") << ") {\nRamDomain data[";
1006  out << arity << "] = {" << join(params, ",") << "};\n";
1007  out << "return insert(data);\n";
1008  out << "}\n";
1009 
1010  // contains methods
1011  out << "bool contains(const t_tuple& t, context& h) const {\n";
1012  out << "return ind_" << masterIndex << ".contains(orderIn_" << masterIndex << "(t), h.hints_"
1013  << masterIndex << ");\n";
1014  out << "}\n";
1015 
1016  out << "bool contains(const t_tuple& t) const {\n";
1017  out << "context h;\n";
1018  out << "return contains(t, h);\n";
1019  out << "}\n";
1020 
1021  // size method
1022  out << "std::size_t size() const {\n";
1023  out << "return ind_" << masterIndex << ".size();\n";
1024  out << "}\n";
1025 
1026  // find methods
1027  if (arity > 1) {
1028  out << "iterator find(const t_tuple& t, context& h) const {\n";
1029  out << "return ind_" << masterIndex << ".find(orderIn_" << masterIndex << "(t), h.hints_"
1030  << masterIndex << ");\n";
1031  out << "}\n";
1032 
1033  out << "iterator find(const t_tuple& t) const {\n";
1034  out << "context h;\n";
1035  out << "return find(t, h);\n";
1036  out << "}\n";
1037  }
1038 
1039  // empty lowerUpperRange method
1040  out << "range<iterator> lowerUpperRange_0(const t_tuple& lower, const t_tuple& upper, context& h) const "
1041  "{\n";
1042  out << "return range<iterator>(ind_" << masterIndex << ".begin(),ind_" << masterIndex << ".end());\n";
1043  out << "}\n";
1044 
1045  out << "range<iterator> lowerUpperRange_0(const t_tuple& lower, const t_tuple& upper) const {\n";
1046  out << "return range<iterator>(ind_" << masterIndex << ".begin(),ind_" << masterIndex << ".end());\n";
1047  out << "}\n";
1048 
1049  // loweUpperRange methods
1050  for (auto search : getMinIndexSelection().getSearches()) {
1051  auto& lexOrder = getMinIndexSelection().getLexOrder(search);
1052  size_t indNum = indexToNumMap[lexOrder];
1053 
1054  out << "range<iterator_" << indNum << "> lowerUpperRange_" << search;
1055  out << "(const t_tuple& lower, const t_tuple& upper, context& h) const {\n";
1056 
1057  // compute size of sub-index
1058  size_t indSize = 0;
1059  for (size_t i = 0; i < arity; i++) {
1060  if (search[i] != analysis::AttributeConstraint::None) {
1061  indSize++;
1062  }
1063  }
1064 
1065  out << "auto r = ind_" << indNum << ".template getBoundaries<" << indSize << ">(orderIn_" << indNum
1066  << "(lower), h.hints_" << indNum << ");\n";
1067  out << "return make_range(iterator_" << indNum << "(r.begin()), iterator_" << indNum
1068  << "(r.end()));\n";
1069  out << "}\n";
1070 
1071  out << "range<iterator_" << indNum << "> lowerUpperRange_" << search;
1072  out << "(const t_tuple& lower, const t_tuple& upper) const {\n";
1073  out << "context h; return lowerUpperRange_" << search << "(lower,upper, h);\n";
1074  out << "}\n";
1075  }
1076 
1077  // empty method
1078  out << "bool empty() const {\n";
1079  out << "return ind_" << masterIndex << ".empty();\n";
1080  out << "}\n";
1081 
1082  // partition method
1083  out << "std::vector<range<iterator>> partition() const {\n";
1084  out << "std::vector<range<iterator>> res;\n";
1085  out << "for (const auto& cur : ind_" << masterIndex << ".partition(10000)) {\n";
1086  out << " res.push_back(make_range(iterator(cur.begin()), iterator(cur.end())));\n";
1087  out << "}\n";
1088  out << "return res;\n";
1089  out << "}\n";
1090 
1091  // purge method
1092  out << "void purge() {\n";
1093  for (size_t i = 0; i < numIndexes; i++) {
1094  out << "ind_" << i << ".clear();\n";
1095  }
1096  out << "}\n";
1097 
1098  // begin and end iterators
1099  out << "iterator begin() const {\n";
1100  out << "return iterator_" << masterIndex << "(ind_" << masterIndex << ".begin());\n";
1101  out << "}\n";
1102 
1103  out << "iterator end() const {\n";
1104  out << "return iterator_" << masterIndex << "(ind_" << masterIndex << ".end());\n";
1105  out << "}\n";
1106 
1107  // TODO: finish printStatistics method
1108  out << "void printStatistics(std::ostream& o) const {\n";
1109  for (size_t i = 0; i < numIndexes; i++) {
1110  out << "o << \" arity " << arity << " brie index " << i << " lex-order " << inds[i] << "\\n\";\n";
1111  ;
1112  out << "ind_" << i << ".printStats(o);\n";
1113  }
1114  out << "}\n";
1115 
1116  // orderOut and orderIn methods for reordering tuples according to index orders
1117  for (size_t i = 0; i < numIndexes; i++) {
1118  auto ind = inds[i];
1119  out << "static t_tuple orderIn_" << i << "(const t_tuple& t) {\n";
1120  out << "t_tuple res;\n";
1121  for (size_t j = 0; j < ind.size(); j++) {
1122  out << "res[" << j << "] = t[" << ind[j] << "];\n";
1123  }
1124  out << "return res;\n";
1125  out << "}\n";
1126 
1127  out << "static t_tuple orderOut_" << i << "(const t_tuple& t) {\n";
1128  out << "t_tuple res;\n";
1129  for (size_t j = 0; j < ind.size(); j++) {
1130  out << "res[" << ind[j] << "] = t[" << j << "];\n";
1131  }
1132  out << "return res;\n";
1133  out << "}\n";
1134  }
1135 
1136  // end class
1137  out << "};\n";
1138 }

References i, j, souffle::join(), and TCB_SPAN_NAMESPACE_NAME::detail::size().

Here is the call graph for this function:

◆ getTypeName()

std::string souffle::synthesiser::BrieRelation::getTypeName ( )
override

Generate type name of a brie relation.

Definition at line 880 of file Relation.cpp.

880  {
881  // collect all attributes used in the lex-order
882  std::unordered_set<uint32_t> attributesUsed;
883  for (auto& ind : getIndices()) {
884  for (auto& attr : ind) {
885  attributesUsed.insert(attr);
886  }
887  }
888 
889  std::stringstream res;
890  res << "t_brie_" << getTypeAttributeString(relation.getAttributeTypes(), attributesUsed);
891 
892  for (auto& ind : getIndices()) {
893  res << "__" << join(ind, "_");
894  }
895 
896  for (auto& search : getMinIndexSelection().getSearches()) {
897  res << "__" << search;
898  }
899 
900  return res.str();
901 }

References souffle::join(), and relation.

Here is the call graph for this function:

The documentation for this class was generated from the following files:
TCB_SPAN_NAMESPACE_NAME::detail::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: span.h:198
souffle::ram::Relation::arity
const size_t arity
Arity, i.e., number of attributes.
Definition: Relation.h:139
relation
Relation & relation
Definition: Reader.h:130
souffle::ram::Relation::Relation
Relation(std::string name, size_t arity, size_t auxiliaryArity, std::vector< std::string > attributeNames, std::vector< std::string > attributeTypes, RelationRepresentation representation)
Definition: Relation.h:42
souffle::ram::Relation::getArity
unsigned getArity() const
Get arity of relation.
Definition: Relation.h:86
j
var j
Definition: htmlJsChartistMin.h:15
i
size_t i
Definition: json11.h:663
souffle::join
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...
Definition: StreamUtil.h:175
souffle::synthesiser::BrieRelation::getTypeName
std::string getTypeName() override
Generate type name of a brie relation.
Definition: Relation.cpp:880
souffle::ram::analysis::MinIndexSelection::OrderCollection
std::vector< LexOrder > OrderCollection
Definition: Index.h:217