Skip to content

Commit c6dc9dc

Browse files
author
Bernhard Scholz
authored
Merge pull request souffle-lang#1781 from SamArch27/index-analysis-refactor
Index analysis refactor #1
2 parents bbe7516 + 5e219c5 commit c6dc9dc

15 files changed

+285
-172
lines changed

src/interpreter/BTreeIndex.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@
2121

2222
namespace souffle::interpreter {
2323

24-
#define CREATE_BTREE_REL(Structure, Arity, ...) \
25-
case (Arity): { \
26-
return mk<Relation<Arity, interpreter::Btree>>(id.getAuxiliaryArity(), id.getName(), orderSet); \
24+
#define CREATE_BTREE_REL(Structure, Arity, ...) \
25+
case (Arity): { \
26+
return mk<Relation<Arity, interpreter::Btree>>( \
27+
id.getAuxiliaryArity(), id.getName(), indexSelection); \
2728
}
2829

2930
Own<RelationWrapper> createBTreeRelation(
30-
const ram::Relation& id, const ram::analysis::MinIndexSelection& orderSet) {
31+
const ram::Relation& id, const ram::analysis::FinalIndexSelection& indexSelection) {
3132
switch (id.getArity()) {
3233
FOR_EACH_BTREE(CREATE_BTREE_REL);
3334

src/interpreter/BrieIndex.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121

2222
namespace souffle::interpreter {
2323

24-
#define CREATE_BRIE_REL(Structure, Arity, ...) \
25-
case (Arity): { \
26-
return mk<Relation<Arity, interpreter::Brie>>(id.getAuxiliaryArity(), id.getName(), orderSet); \
24+
#define CREATE_BRIE_REL(Structure, Arity, ...) \
25+
case (Arity): { \
26+
return mk<Relation<Arity, interpreter::Brie>>(id.getAuxiliaryArity(), id.getName(), indexSelection); \
2727
}
2828

2929
Own<RelationWrapper> createBrieRelation(
30-
const ram::Relation& id, const ram::analysis::MinIndexSelection& /* orderSet */) {
30+
const ram::Relation& id, const ram::analysis::FinalIndexSelection& /* orderSet */) {
3131
switch (id.getArity()) {
3232
FOR_EACH_BRIE(CREATE_BRIE_REL);
3333

src/interpreter/Engine.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,14 @@ void Engine::createRelation(const ram::Relation& id, const size_t idx) {
198198
}
199199

200200
RelationHandle res;
201-
const auto& orderSet = isa->getIndexes(id.getName());
201+
202202
if (id.getRepresentation() == RelationRepresentation::EQREL) {
203-
res = createEqrelRelation(id, orderSet);
203+
res = createEqrelRelation(id, isa->getIndexSelection(id.getName()));
204204
} else {
205205
if (isProvenance) {
206-
res = createProvenanceRelation(id, orderSet);
206+
res = createProvenanceRelation(id, isa->getIndexSelection(id.getName()));
207207
} else {
208-
res = createBTreeRelation(id, orderSet);
208+
res = createBTreeRelation(id, isa->getIndexSelection(id.getName()));
209209
}
210210
}
211211
relations[idx] = mk<RelationHandle>(std::move(res));

src/interpreter/EqrelIndex.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
namespace souffle::interpreter {
2222

2323
Own<RelationWrapper> createEqrelRelation(
24-
const ram::Relation& id, const ram::analysis::MinIndexSelection& orderSet) {
24+
const ram::Relation& id, const ram::analysis::FinalIndexSelection& indexSelection) {
2525
assert(id.getArity() == 2 && "Eqivalence relation must have arity size 2.");
26-
return mk<EqrelRelation>(id.getAuxiliaryArity(), id.getName(), orderSet);
26+
return mk<EqrelRelation>(id.getAuxiliaryArity(), id.getName(), indexSelection);
2727
}
2828

2929
} // namespace souffle::interpreter

src/interpreter/Generator.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -491,13 +491,12 @@ size_t NodeGenerator::getNextViewId() {
491491
template <class RamNode>
492492
size_t NodeGenerator::encodeIndexPos(RamNode& node) {
493493
const std::string& name = node.getRelation();
494-
auto& orderSet = engine.isa->getIndexes(name);
495494
ram::analysis::SearchSignature signature = engine.isa->getSearchSignature(&node);
496495
// A zero signature is equivalent as a full order signature.
497496
if (signature.empty()) {
498497
signature = ram::analysis::SearchSignature::getFullSearchSignature(signature.arity());
499498
}
500-
auto i = orderSet.getLexOrderNum(signature);
499+
auto i = engine.isa->getIndexSelection(name).getLexOrderNum(signature);
501500
indexTable[&node] = i;
502501
return i;
503502
};

src/interpreter/ProvenanceIndex.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@
1818

1919
namespace souffle::interpreter {
2020

21-
#define CREATE_PROVENANCE_REL(Structure, Arity, ...) \
22-
case (Arity): { \
23-
return mk<Relation<Arity, interpreter::Provenance>>(id.getAuxiliaryArity(), id.getName(), orderSet); \
21+
#define CREATE_PROVENANCE_REL(Structure, Arity, ...) \
22+
case (Arity): { \
23+
return mk<Relation<Arity, interpreter::Provenance>>( \
24+
id.getAuxiliaryArity(), id.getName(), indexSelection); \
2425
}
2526

2627
Own<RelationWrapper> createProvenanceRelation(
27-
const ram::Relation& id, const ram::analysis::MinIndexSelection& orderSet) {
28+
const ram::Relation& id, const ram::analysis::FinalIndexSelection& indexSelection) {
2829
switch (id.getArity()) {
2930
FOR_EACH_PROVENANCE(CREATE_PROVENANCE_REL);
3031

src/interpreter/Relation.h

+13-14
Original file line numberDiff line numberDiff line change
@@ -180,21 +180,23 @@ class Relation : public RelationWrapper {
180180
/**
181181
* Creates a relation, build all necessary indexes.
182182
*/
183-
Relation(size_t auxiliaryArity, std::string name, const ram::analysis::MinIndexSelection& orderSet)
184-
: RelationWrapper(Arity, auxiliaryArity, std::move(name)) {
185-
for (auto order : orderSet.getAllOrders()) {
183+
Relation(size_t auxiliaryArity, const std::string& name,
184+
const ram::analysis::FinalIndexSelection& indexSelection)
185+
: RelationWrapper(Arity, auxiliaryArity, name) {
186+
for (const auto& order : indexSelection.getAllOrders()) {
187+
ram::analysis::LexOrder fullOrder = order;
186188
// Expand the order to a total order
187-
ram::analysis::MinIndexSelection::AttributeSet set{order.begin(), order.end()};
189+
ram::analysis::AttributeSet set{order.begin(), order.end()};
188190

189191
// This operation is not performance critical.
190192
// Not using constexpr Arity to avoid compiler warning. (When Arity == 0)
191193
for (size_t i = 0; i < getArity(); ++i) {
192194
if (set.find(i) == set.end()) {
193-
order.push_back(i);
195+
fullOrder.push_back(i);
194196
}
195197
}
196198

197-
indexes.push_back(mk<Index>(order));
199+
indexes.push_back(mk<Index>(fullOrder));
198200
}
199201

200202
// Use the first index as default main index
@@ -413,22 +415,19 @@ class EqrelRelation : public Relation<2, Eqrel> {
413415

414416
// The type of relation factory functions.
415417
using RelationFactory = Own<RelationWrapper> (*)(
416-
const ram::Relation& id, const ram::analysis::MinIndexSelection& orderSet);
418+
const ram::Relation& id, const ram::analysis::FinalIndexSelection& indexSelection);
417419

418420
// A factory for BTree based relation.
419421
Own<RelationWrapper> createBTreeRelation(
420-
const ram::Relation& id, const ram::analysis::MinIndexSelection& orderSet);
422+
const ram::Relation& id, const ram::analysis::FinalIndexSelection& indexSelection);
421423

422424
// A factory for BTree provenance index.
423425
Own<RelationWrapper> createProvenanceRelation(
424-
const ram::Relation& id, const ram::analysis::MinIndexSelection& orderSet);
425-
426+
const ram::Relation& id, const ram::analysis::FinalIndexSelection& indexSelection);
426427
// A factory for Brie based index.
427428
Own<RelationWrapper> createBrieRelation(
428-
const ram::Relation& id, const ram::analysis::MinIndexSelection& orderSet);
429-
429+
const ram::Relation& id, const ram::analysis::FinalIndexSelection& indexSelection);
430430
// A factory for Eqrel index.
431431
Own<RelationWrapper> createEqrelRelation(
432-
const ram::Relation& id, const ram::analysis::MinIndexSelection& orderSet);
433-
432+
const ram::Relation& id, const ram::analysis::FinalIndexSelection& indexSelection);
434433
} // namespace souffle::interpreter

src/interpreter/tests/interpreter_relation_test.cpp

+90-31
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,26 @@
2727

2828
namespace souffle::interpreter::test {
2929

30-
using ::souffle::ram::analysis::MinIndexSelection;
30+
using ::souffle::ram::analysis::AttributeConstraint;
31+
using ::souffle::ram::analysis::FinalIndexSelection;
32+
using ::souffle::ram::analysis::LexOrder;
33+
using ::souffle::ram::analysis::OrderCollection;
34+
using ::souffle::ram::analysis::SearchSet;
35+
using ::souffle::ram::analysis::SearchSignature;
36+
using ::souffle::ram::analysis::SignatureOrderMap;
3137

3238
TEST(Relation0, Construction) {
3339
// create a nullary relation
3440
SymbolTable symbolTable;
35-
MinIndexSelection order{};
36-
order.insertDefaultTotalIndex(0);
37-
Relation<0, interpreter::Btree> rel(0, "test", order);
41+
42+
// create an index selection from no searches to a default index for arity 0
43+
SignatureOrderMap mapping;
44+
SearchSet searches;
45+
LexOrder emptyOrder;
46+
OrderCollection orders = {emptyOrder};
47+
FinalIndexSelection indexSelection(mapping, searches, orders);
48+
49+
Relation<0, interpreter::Btree> rel(0, "test", indexSelection);
3850

3951
souffle::Tuple<RamDomain, 0> tuple;
4052
// add some values
@@ -48,9 +60,15 @@ TEST(Relation0, Construction) {
4860
TEST(Relation0, Iteration) {
4961
// create a nullary relation
5062
SymbolTable symbolTable;
51-
MinIndexSelection order{};
52-
order.insertDefaultTotalIndex(0);
53-
Relation<0, interpreter::Btree> rel(0, "test", order);
63+
64+
// create an index selection from no searches to a default index for arity 0
65+
SignatureOrderMap mapping;
66+
SearchSet searches;
67+
LexOrder emptyOrder;
68+
OrderCollection orders = {emptyOrder};
69+
FinalIndexSelection indexSelection(mapping, searches, orders);
70+
71+
Relation<0, interpreter::Btree> rel(0, "test", indexSelection);
5472
RelationWrapper* wrapper = &rel;
5573

5674
souffle::Tuple<RamDomain, 0> tuple;
@@ -67,9 +85,17 @@ TEST(Relation0, Iteration) {
6785
TEST(Relation1, Construction) {
6886
// create a single attribute relation
6987
SymbolTable symbolTable;
70-
MinIndexSelection order{};
71-
order.insertDefaultTotalIndex(1);
72-
Relation<1, interpreter::Btree> rel(0, "test", order);
88+
89+
// create an index selection for a relation with arity 1 with only an existence check
90+
SignatureOrderMap mapping;
91+
SearchSignature existenceCheck = SearchSignature::getFullSearchSignature(1);
92+
SearchSet searches = {existenceCheck};
93+
LexOrder fullOrder = {0};
94+
OrderCollection orders = {fullOrder};
95+
mapping.insert({existenceCheck, fullOrder});
96+
FinalIndexSelection indexSelection(mapping, searches, orders);
97+
98+
Relation<1, interpreter::Btree> rel(0, "test", indexSelection);
7399
RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
74100

75101
tuple d1(&relInt, {1});
@@ -88,9 +114,17 @@ TEST(Relation1, Construction) {
88114
TEST(Basic, Iteration) {
89115
// create a relation
90116
SymbolTable symbolTable;
91-
MinIndexSelection order{};
92-
order.insertDefaultTotalIndex(1);
93-
Relation<1, interpreter::Btree> rel(0, "test", order);
117+
118+
// create an index selection for a relation with arity 1 with only an existence check
119+
SignatureOrderMap mapping;
120+
SearchSignature existenceCheck = SearchSignature::getFullSearchSignature(1);
121+
SearchSet searches = {existenceCheck};
122+
LexOrder fullOrder = {0};
123+
OrderCollection orders = {fullOrder};
124+
mapping.insert({existenceCheck, fullOrder});
125+
FinalIndexSelection indexSelection(mapping, searches, orders);
126+
127+
Relation<1, interpreter::Btree> rel(0, "test", indexSelection);
94128
RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
95129

96130
// add some values
@@ -115,9 +149,17 @@ TEST(Basic, Iteration) {
115149
TEST(Independence, Iteration) {
116150
// create a table
117151
SymbolTable symbolTable;
118-
MinIndexSelection order{};
119-
order.insertDefaultTotalIndex(1);
120-
Relation<1, interpreter::Btree> rel(0, "test", order);
152+
153+
// create an index selection for a relation with arity 1 with only an existence check
154+
SignatureOrderMap mapping;
155+
SearchSignature existenceCheck = SearchSignature::getFullSearchSignature(1);
156+
SearchSet searches = {existenceCheck};
157+
LexOrder fullOrder = {0};
158+
OrderCollection orders = {fullOrder};
159+
mapping.insert({existenceCheck, fullOrder});
160+
FinalIndexSelection indexSelection(mapping, searches, orders);
161+
162+
Relation<1, interpreter::Btree> rel(0, "test", indexSelection);
121163
RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
122164

123165
// add a value
@@ -143,9 +185,17 @@ TEST(Independence, Iteration) {
143185
TEST(IndependentMoving, Iteration) {
144186
// create a table
145187
SymbolTable symbolTable;
146-
MinIndexSelection order{};
147-
order.insertDefaultTotalIndex(1);
148-
Relation<1, interpreter::Btree> rel(0, "test", order);
188+
189+
// create an index selection for a relation with arity 1 with only an existence check
190+
SignatureOrderMap mapping;
191+
SearchSignature existenceCheck = SearchSignature::getFullSearchSignature(1);
192+
SearchSet searches = {existenceCheck};
193+
LexOrder fullOrder = {0};
194+
OrderCollection orders = {fullOrder};
195+
mapping.insert({existenceCheck, fullOrder});
196+
FinalIndexSelection indexSelection(mapping, searches, orders);
197+
198+
Relation<1, interpreter::Btree> rel(0, "test", indexSelection);
149199
RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
150200

151201
// add a value
@@ -166,9 +216,17 @@ TEST(IndependentMoving, Iteration) {
166216
TEST(IndependentCopying, Iteration) {
167217
// create a table
168218
SymbolTable symbolTable;
169-
MinIndexSelection order{};
170-
order.insertDefaultTotalIndex(1);
171-
Relation<1, interpreter::Btree> rel(0, "test", order);
219+
220+
// create an index selection for a relation with arity 1 with only an existence check
221+
SignatureOrderMap mapping;
222+
SearchSignature existenceCheck = SearchSignature::getFullSearchSignature(1);
223+
SearchSet searches = {existenceCheck};
224+
LexOrder fullOrder = {0};
225+
OrderCollection orders = {fullOrder};
226+
mapping.insert({existenceCheck, fullOrder});
227+
FinalIndexSelection indexSelection(mapping, searches, orders);
228+
229+
Relation<1, interpreter::Btree> rel(0, "test", indexSelection);
172230
RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
173231

174232
// add a value
@@ -190,16 +248,17 @@ TEST(Reordering, Iteration) {
190248
// create a relation, with a non-default ordering.
191249
SymbolTable symbolTable;
192250

251+
// create an index selection for a relation with arity 1 with only an existence check
252+
SignatureOrderMap mapping;
253+
SearchSignature existenceCheck = SearchSignature::getFullSearchSignature(3);
254+
SearchSet searches = {existenceCheck};
193255
// create an index of order {0, 2, 1}
194-
MinIndexSelection order{};
195-
ram::analysis::SearchSignature cols(3);
196-
cols[0] = ram::analysis::AttributeConstraint::Equal;
197-
cols[1] = ram::analysis::AttributeConstraint::None;
198-
cols[2] = ram::analysis::AttributeConstraint::Equal;
199-
order.addSearch(cols);
200-
order.solve();
201-
202-
Relation<3, interpreter::Btree> rel(0, "test", order);
256+
LexOrder fullOrder = {0, 2, 1};
257+
OrderCollection orders = {fullOrder};
258+
mapping.insert({existenceCheck, fullOrder});
259+
FinalIndexSelection indexSelection(mapping, searches, orders);
260+
261+
Relation<3, interpreter::Btree> rel(0, "test", indexSelection);
203262
souffle::Tuple<RamDomain, 3> tuple{0, 1, 2};
204263
rel.insert(tuple);
205264

0 commit comments

Comments
 (0)