Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Several internal relations needed for QLeverUI autocomplete #112

Closed
wants to merge 10 commits into from
12 changes: 10 additions & 2 deletions src/ServerMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct option options[] = {{"all-permutations", no_argument, NULL, 'a'},
{"patterns", no_argument, NULL, 'P'},
{"text", no_argument, NULL, 't'},
{"unopt-optional", no_argument, NULL, 'u'},
{"added-predicates", no_argument, NULL, 'r'},
{NULL, 0, NULL, 0}};

void printUsage(char* execName) {
Expand Down Expand Up @@ -61,6 +62,9 @@ void printUsage(char* execName) {
cout << " " << std::setw(20) << "u, unopt-optional" << std::setw(1) << " "
<< "Always place optional joins at the root of the query execution tree."
<< endl;
cout << " " << std::setw(20) << "r, added-predicates" << std::setw(1)
<< " "
<< "Create additional predicates that can be used in queries." << endl;
cout.copyfmt(coutState);
}

Expand All @@ -79,14 +83,15 @@ int main(int argc, char** argv) {
bool text = false;
bool allPermutations = false;
bool optimizeOptionals = true;
bool addedPredicates = false;
int port = -1;
int numThreads = 1;
bool usePatterns = false;

optind = 1;
// Process command line arguments.
while (true) {
int c = getopt_long(argc, argv, "i:p:j:tauhPml", options, NULL);
int c = getopt_long(argc, argv, "i:p:j:tauhPmlr", options, NULL);
if (c == -1) break;
switch (c) {
case 'i':
Expand Down Expand Up @@ -119,6 +124,9 @@ int main(int argc, char** argv) {
"will be ignored for ServerMain. The correct setting for "
"this flag is read directly from the index\n";
break;
case 'r':
addedPredicates = true;
break;
default:
cout << endl
<< "! ERROR in processing options (getopt returned '" << c
Expand Down Expand Up @@ -150,7 +158,7 @@ int main(int argc, char** argv) {
try {
Server server(port, numThreads);
server.initialize(index, text, allPermutations, optimizeOptionals,
usePatterns);
usePatterns, addedPredicates);
server.run();
} catch (const ad_semsearch::Exception& e) {
LOG(ERROR) << e.getFullErrorMessage() << '\n';
Expand Down
172 changes: 172 additions & 0 deletions src/engine/AddedPredicatesScan.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// Copyright 2018, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Julian Bürklin (buerklij@informatik.uni-freiburg.de)s

#include "AddedPredicatesScan.h"
#include <limits>
#include <string>
#include <vector>

// _____________________________________________________________________________
AddedPredicatesScan::AddedPredicatesScan(QueryExecutionContext* qec, Id statId,
ScanType type)
: Operation(qec),
_sizeEstimate(std::numeric_limits<size_t>::max()),
_statId(statId),
_type(type) {}

// _____________________________________________________________________________
string AddedPredicatesScan::asString(size_t indent) const {
std::ostringstream os;
for (size_t i = 0; i < indent; ++i) {
os << " ";
}

string stat;
switch (_statId) {
case 0:
stat = NUM_TRIPLES_PREDICATE;
break;
case 1:
stat = ENTITY_TYPE_PREDICATE;
break;
case 2:
stat = NUM_OCCURRENCES_PREDICATE;
break;
default:
AD_THROW(ad_semsearch::Exception::BAD_INPUT,
"Added predicate not supported.");
}

os << "SCAN ADDED_PREDICATES_";
switch (_type) {
case POS_BOUND_O:
os << "POS with stat = " << stat << ", O = \"" << _object << "\"";
break;
case PSO_BOUND_S:
os << "PSO with stat = " << stat << ", S = \"" << _subject << "\"";
break;
case PSO_FREE_S:
default:
os << "PSO with stat = " << stat;
}
return os.str();
}

// _____________________________________________________________________________
size_t AddedPredicatesScan::getResultWidth() const {
switch (_type) {
case POS_BOUND_O:
case PSO_BOUND_S:
return 1;
case PSO_FREE_S:
case POS_FREE_O:
return 2;
default:
AD_THROW(ad_semsearch::Exception::BAD_INPUT,
"Added Predicate scan type not supported.");
}
}

// _____________________________________________________________________________
void AddedPredicatesScan::determineMultiplicities() {
_multiplicity.clear();
if (getResultWidth() == 1) {
_multiplicity.emplace_back(1);
} else {
switch (_type) {
case PSO_FREE_S:
_multiplicity = getIndex().getAddedPredicatesPsoMultiplicities(_statId);
break;
case POS_FREE_O:
_multiplicity = getIndex().getAddedPredicatesPosMultiplicities(_statId);
break;
default:
AD_THROW(ad_semsearch::Exception::ASSERT_FAILED,
"Switch reached default block unexpectedly!");
}
}
}

// _____________________________________________________________________________
size_t AddedPredicatesScan::computeSizeEstimate() const {
return getIndex().addedPredicatesSizeEstimate(_statId);
}

// _____________________________________________________________________________
void AddedPredicatesScan::computeResult(ResultTable* result) const {
switch (_type) {
case POS_BOUND_O:
computePOSboundO(result);
break;
case PSO_BOUND_S:
computePSOboundS(result);
break;
case PSO_FREE_S:
computePSOfreeS(result);
break;
case POS_FREE_O:
computePOSfreeO(result);
break;
}
}

// _____________________________________________________________________________
void AddedPredicatesScan::computePSOfreeS(ResultTable* result) const {
result->_nofColumns = 2;
result->_resultTypes.push_back(ResultTable::ResultType::KB);
if (_statId == Id(0) || _statId == Id(2)) {
result->_resultTypes.push_back(ResultTable::ResultType::VERBATIM);
} else if (_statId == Id(1)) {
result->_resultTypes.push_back(ResultTable::ResultType::ENTITY_TYPE);
}
result->_sortedBy = 0;
result->_fixedSizeData = new vector<array<Id, 2>>();
_executionContext->getIndex().scanAddedPredicatesPso(
_statId, static_cast<vector<array<Id, 2>>*>(result->_fixedSizeData));
result->finish();
}

// _____________________________________________________________________________
void AddedPredicatesScan::computePOSfreeO(ResultTable* result) const {
result->_nofColumns = 2;
if (_statId == Id(0) || _statId == Id(2)) {
result->_resultTypes.push_back(ResultTable::ResultType::VERBATIM);
} else if (_statId == Id(1)) {
result->_resultTypes.push_back(ResultTable::ResultType::ENTITY_TYPE);
}
result->_resultTypes.push_back(ResultTable::ResultType::KB);
result->_sortedBy = 0;
result->_fixedSizeData = new vector<array<Id, 2>>();
_executionContext->getIndex().scanAddedPredicatesPos(
_statId, static_cast<vector<array<Id, 2>>*>(result->_fixedSizeData));
result->finish();
}

// _____________________________________________________________________________
void AddedPredicatesScan::computePOSboundO(ResultTable* result) const {
result->_nofColumns = 1;
result->_resultTypes.push_back(ResultTable::ResultType::KB);
result->_sortedBy = 0;
result->_fixedSizeData = new vector<array<Id, 1>>();
_executionContext->getIndex().scanAddedPredicatesPos(
_statId, _object,
static_cast<vector<array<Id, 1>>*>(result->_fixedSizeData));
result->finish();
}

// _____________________________________________________________________________
void AddedPredicatesScan::computePSOboundS(ResultTable* result) const {
result->_nofColumns = 1;
if (_statId == Id(0) || _statId == Id(2)) {
result->_resultTypes.push_back(ResultTable::ResultType::VERBATIM);
} else if (_statId == Id(1)) {
result->_resultTypes.push_back(ResultTable::ResultType::ENTITY_TYPE);
}
result->_sortedBy = 0;
result->_fixedSizeData = new vector<array<Id, 1>>();
_executionContext->getIndex().scanAddedPredicatesPso(
_statId, _subject,
static_cast<vector<array<Id, 1>>*>(result->_fixedSizeData));
result->finish();
}
82 changes: 82 additions & 0 deletions src/engine/AddedPredicatesScan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2018, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Julian Bürklin (buerklij@informatik.uni-freiburg.de)

#pragma once

#include <limits>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "../global/Pattern.h"
#include "../parser/ParsedQuery.h"
#include "./Operation.h"
#include "./QueryExecutionTree.h"

using std::string;
using std::vector;

class AddedPredicatesScan : public Operation {
public:
enum ScanType {
POS_BOUND_O = 0,
PSO_BOUND_S = 1,
PSO_FREE_S = 2,
POS_FREE_O = 3
};

AddedPredicatesScan(QueryExecutionContext* qec, Id statId, ScanType type);

void setSubject(const string& subject) { _subject = subject; }
void setObject(const string& object) { _object = object; }

virtual string asString(size_t indent = 0) const;

virtual size_t getResultWidth() const;

virtual size_t resultSortedOn() const { return 0; }

void determineMultiplicities();

virtual float getMultiplicity(size_t col) {
if (_multiplicity.size() == 0) {
determineMultiplicities();
}
assert(col < _multiplicity.size());
return _multiplicity[col];
}

virtual void setTextLimit(size_t) {
// Do nothing.
}

virtual size_t getSizeEstimate() {
if (_sizeEstimate == std::numeric_limits<size_t>::max()) {
_sizeEstimate = computeSizeEstimate();
}
return _sizeEstimate;
}

virtual size_t getCostEstimate() { return getSizeEstimate(); }

virtual bool knownEmptyResult() { return getSizeEstimate() == 0; }

protected:
size_t _sizeEstimate;
vector<float> _multiplicity;

size_t computeSizeEstimate() const;

private:
virtual void computeResult(ResultTable* result) const;
virtual void computePSOfreeS(ResultTable* result) const;
virtual void computePOSfreeO(ResultTable* result) const;
virtual void computePOSboundO(ResultTable* result) const;
virtual void computePSOboundS(ResultTable* result) const;
Id _statId;
ScanType _type;
string _subject;
string _object;
};
1 change: 1 addition & 0 deletions src/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ add_library(engine
CountAvailablePredicates.cpp CountAvailablePredicates.h
GroupBy.cpp GroupBy.h
HasPredicateScan.cpp HasPredicateScan.h
AddedPredicatesScan.cpp AddedPredicatesScan.h
)

target_link_libraries(engine index parser)
39 changes: 38 additions & 1 deletion src/engine/QueryExecutionTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class QueryExecutionTree {
OPTIONAL_JOIN = 11,
COUNT_AVAILABLE_PREDICATES = 12,
GROUP_BY = 13,
HAS_RELATION_SCAN = 14
HAS_RELATION_SCAN = 14,
SCAN_ADDED_PREDICATES = 15
};

void setOperation(OperationType type, std::shared_ptr<Operation> op);
Expand Down Expand Up @@ -176,6 +177,24 @@ class QueryExecutionTree {
os << ad_utility::toJson(entity.value()) << ",";
break;
}
case ResultTable::ResultType::ENTITY_TYPE: {
os << "\"";
switch (row[validIndices[j].first]) {
case 0:
os << "subject";
break;
case 1:
os << "predicate";
break;
case 2:
os << "object";
break;
default:
os << row[validIndices[j].first];
}
os << "\",";
break;
}
default:
AD_THROW(ad_semsearch::Exception::INVALID_PARAMETER_VALUE,
"Cannot deduce output type.");
Expand Down Expand Up @@ -216,6 +235,24 @@ class QueryExecutionTree {
os << ad_utility::toJson(entity.value()) << "]";
break;
}
case ResultTable::ResultType::ENTITY_TYPE: {
os << "\"";
switch (row[validIndices[validIndices.size() - 1].first]) {
case 0:
os << "subject";
break;
case 1:
os << "predicate";
break;
case 2:
os << "object";
break;
default:
os << row[validIndices[validIndices.size() - 1].first];
}
os << "\"]";
break;
}
default:
AD_THROW(ad_semsearch::Exception::INVALID_PARAMETER_VALUE,
"Cannot deduce output type.");
Expand Down