Skip to content

Commit

Permalink
Cleaned up, fixed warnings, and formatted.
Browse files Browse the repository at this point in the history
  • Loading branch information
joka921 committed Nov 17, 2021
1 parent be2c676 commit 6c3cc5d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 149 deletions.
7 changes: 1 addition & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,6 @@ if (${PERFTOOLS_PROFILER})
message(STATUS "Adding -lprofiler (make sure your have google-perftools installed.)")
endif ()

if (${ALLOW_SHUTDOWN})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DALLOW_SHUTDOWN")
message(STATUS "Adding -DALLOW_SHUTDOWN")
endif ()


set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")

Expand Down Expand Up @@ -223,7 +218,7 @@ add_executable(SparqlEngineMain src/SparqlEngineMain.cpp)
target_link_libraries (SparqlEngineMain engine ${CMAKE_THREAD_LIBS_INIT})

add_executable(ServerMain src/ServerMain.cpp)
target_link_libraries (ServerMain engine ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (ServerMain engine server ${CMAKE_THREAD_LIBS_INIT})

add_executable(WriteIndexListsMain src/WriteIndexListsMain.cpp)
target_link_libraries (WriteIndexListsMain engine ${CMAKE_THREAD_LIBS_INIT})
Expand Down
8 changes: 6 additions & 2 deletions src/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_subdirectory(sparqlExpressions)
add_library(SortPerformanceEstimator SortPerformanceEstimator.cpp SortPerformanceEstimator.h)

add_library(engine
Engine.h
IndexSequence.h
Expand All @@ -19,7 +20,6 @@ add_library(engine
Distinct.h Distinct.cpp
OrderBy.h OrderBy.cpp
Filter.h Filter.cpp
Server.h Server.cpp
QueryPlanner.cpp QueryPlanner.h
QueryPlanningCostFactors.cpp QueryPlanningCostFactors.h
TwoColumnJoin.cpp TwoColumnJoin.h
Expand All @@ -37,4 +37,8 @@ add_library(engine
Minus.h Minus.cpp
ResultType.h)

target_link_libraries(engine index parser sparqlExpressions SortPerformanceEstimator absl::flat_hash_set uWebSockets ${ICU_LIBRARIES})
target_link_libraries(engine index parser sparqlExpressions SortPerformanceEstimator absl::flat_hash_set ${ICU_LIBRARIES})

add_library(server Server.h Server.cpp)
target_compile_options(server PUBLIC -Wno-unused-parameter -Wno-sign-compare)
target_link_libraries(server engine uWebSockets)
165 changes: 45 additions & 120 deletions src/engine/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "../util/Log.h"
#include "../util/StringUtils.h"
#include "./Server.h"
#include "App.h"
#include "QueryPlanner.h"

// _____________________________________________________________________________
Expand Down Expand Up @@ -80,7 +79,7 @@ void Server::process(uWS::HttpResponse<false>* resp, uWS::HttpRequest* req) {
LOG(INFO) << "GET request for " << file << std::endl;
// Use hardcoded white-listing for index.html and style.css
// can be changed if more should ever be needed, for now keep it simple.
if (req->getQuery().size() == 0) {
if (req->getQuery().empty()) {
LOG(DEBUG) << "file: " << file << '\n';
if (file == "/index.html" || file == "/style.css" || file == "/script.js") {
serveFile(resp, "." + file);
Expand Down Expand Up @@ -142,14 +141,7 @@ void Server::process(uWS::HttpResponse<false>* resp, uWS::HttpRequest* req) {
if (!send.empty()) {
maxSend = static_cast<size_t>(stoul(std::string(send)));
}
#ifdef ALLOW_SHUTDOWN
if (ad_utility::getLowercase(req->getQuery("cmd")) == "shutdown") {
LOG(INFO) << "Shutdown triggered by HTTP request "
<< "(deactivate by compiling without -DALLOW_SHUTDOWN)"
<< std::endl;
exit(0);
}
#endif

const bool pinSubtrees =
ad_utility::getLowercase(req->getQuery("pinsubtrees")) == "true";
const bool pinResult =
Expand Down Expand Up @@ -209,80 +201,14 @@ void Server::process(uWS::HttpResponse<false>* resp, uWS::HttpRequest* req) {
// Print the runtime info. This needs to be done after the query
// was computed.
LOG(INFO) << '\n' << qet.getRootOperation()->getRuntimeInfo().toString();
} catch (const ad_semsearch::Exception& e) {
resp->writeStatus("500 Internal Server Error");
resp->end(composeResponseJson(query, e, requestTimer));
} catch (const std::exception& e) {
resp->writeStatus("500 Internal Server Error");
resp->end(composeResponseJson(query, e, requestTimer));
}
}

// _____________________________________________________________________________
Server::ParamValueMap Server::parseHttpRequest(
const string& httpRequest) const {
LOG(DEBUG) << "Parsing HTTP Request." << endl;
ParamValueMap params;
// Parse the HTTP Request.

size_t indexOfGET = httpRequest.find("GET");
size_t indexOfHTTP = httpRequest.find("HTTP");

if (indexOfGET == httpRequest.npos || indexOfHTTP == httpRequest.npos) {
AD_THROW(ad_semsearch::Exception::BAD_REQUEST,
"Invalid request. Only supporting proper HTTP GET requests!\n" +
httpRequest);
}

string request =
httpRequest.substr(indexOfGET + 3, indexOfHTTP - (indexOfGET + 3));

size_t index = request.find("?");
if (index == request.npos) {
AD_THROW(ad_semsearch::Exception::BAD_REQUEST,
"Invalid request. At least one parameters is "
"required for meaningful queries!\n" +
httpRequest);
}
size_t next = request.find('&', index + 1);
while (next != request.npos) {
size_t posOfEq = request.find('=', index + 1);
if (posOfEq == request.npos) {
AD_THROW(ad_semsearch::Exception::BAD_REQUEST,
"Parameter without \"=\" in HTTP Request.\n" + httpRequest);
}
string param = ad_utility::getLowercaseUtf8(
request.substr(index + 1, posOfEq - (index + 1)));
string value = ad_utility::decodeUrl(
request.substr(posOfEq + 1, next - (posOfEq + 1)));
if (params.count(param) > 0) {
AD_THROW(ad_semsearch::Exception::BAD_REQUEST,
"Duplicate HTTP parameter: " + param);
}
params[param] = value;
index = next;
next = request.find('&', index + 1);
}
size_t posOfEq = request.find('=', index + 1);
if (posOfEq == request.npos) {
AD_THROW(ad_semsearch::Exception::BAD_REQUEST,
"Parameter without \"=\" in HTTP Request." + httpRequest);
}
string param = ad_utility::getLowercaseUtf8(
request.substr(index + 1, posOfEq - (index + 1)));
string value = ad_utility::decodeUrl(
request.substr(posOfEq + 1, request.size() - 1 - (posOfEq + 1)));
if (params.count(param) > 0) {
AD_THROW(ad_semsearch::Exception::BAD_REQUEST, "Duplicate HTTP parameter.");
}
params[param] = value;

LOG(DEBUG) << "Done parsing HTTP Request." << endl;
return params;
}

// _____________________________________________________________________________
string Server::createQueryFromHttpParams(uWS::HttpRequest* req) const {
string Server::createQueryFromHttpParams(uWS::HttpRequest* req) {
// Construct a Query object from the parsed request.
std::string_view query = req->getQuery("query");
if (query.empty()) {
Expand All @@ -294,7 +220,7 @@ string Server::createQueryFromHttpParams(uWS::HttpRequest* req) const {

// _____________________________________________________________________________
string Server::createHttpResponse(const string& content,
const string& contentType) const {
const string& contentType) {
std::ostringstream os;
os << "HTTP/1.1 200 OK\r\n"
<< "Content-Length: " << content.size() << "\r\n"
Expand All @@ -310,13 +236,13 @@ string Server::createHttpResponse(const string& content,
}

// _____________________________________________________________________________
void Server::create404HttpResponse(uWS::HttpResponse<false>* resp) const {
void Server::create404HttpResponse(uWS::HttpResponse<false>* resp) {
resp->writeStatus("404 Not Found");
resp->end("404 Not Found");
}

// _____________________________________________________________________________
void Server::create400HttpResponse(uWS::HttpResponse<false>* resp) const {
void Server::create400HttpResponse(uWS::HttpResponse<false>* resp) {
resp->writeStatus("400 Bad Request");
resp->end("400 Bad Request");
}
Expand All @@ -325,7 +251,7 @@ void Server::create400HttpResponse(uWS::HttpResponse<false>* resp) const {
string Server::composeResponseJson(const ParsedQuery& query,
const QueryExecutionTree& qet,
ad_utility::Timer& requestTimer,
size_t maxSend) const {
size_t maxSend) {
shared_ptr<const ResultTable> rt = qet.getResult();
requestTimer.stop();
off_t compResultUsecs = requestTimer.usecs();
Expand All @@ -343,40 +269,43 @@ string Server::composeResponseJson(const ParsedQuery& query,
qet.getRootOperation()->getRuntimeInfo());

{
size_t limit = MAX_NOF_ROWS_IN_RESULT;
size_t offset = 0;
if (query._limit.size() > 0) {
limit = static_cast<size_t>(atol(query._limit.c_str()));
}
if (query._offset.size() > 0) {
offset = static_cast<size_t>(atol(query._offset.c_str()));
}
auto [limit, offset] = parseLimitAndOffset(query, MAX_NOF_ROWS_IN_RESULT);
requestTimer.cont();
j["res"] = qet.writeResultAsJson(query._selectClause._selectedVariables,
std::min(limit, maxSend), offset);
requestTimer.stop();
}

requestTimer.stop();
j["time"]["total"] = std::to_string(requestTimer.usecs() / 1000.0) + "ms";
j["time"]["computeResult"] = std::to_string(compResultUsecs / 1000.0) + "ms";
j["time"]["total"] =
std::to_string(static_cast<double>(requestTimer.usecs()) / 1000.0) + "ms";
j["time"]["computeResult"] =
std::to_string(static_cast<double>(compResultUsecs) / 1000.0) + "ms";

return j.dump(4);
}

// _________________________________________________________________________________
std::pair<size_t, size_t> Server::parseLimitAndOffset(const ParsedQuery& query,
size_t defaultLimit) {
size_t limit = defaultLimit;
if (!query._limit.empty() > 0) {
limit = stoul(query._limit);
}

size_t offset = 0;
if (!query._offset.empty()) {
offset = stoul(query._offset);
}
return std::pair{limit, offset};
}

// _____________________________________________________________________________
string Server::composeResponseSepValues(const ParsedQuery& query,
const QueryExecutionTree& qet,
char sep) const {
char sep) {
std::ostringstream os;
size_t limit = std::numeric_limits<size_t>::max();
size_t offset = 0;
if (query._limit.size() > 0) {
limit = static_cast<size_t>(atol(query._limit.c_str()));
}
if (query._offset.size() > 0) {
offset = static_cast<size_t>(atol(query._offset.c_str()));
}
auto [limit, offset] = parseLimitAndOffset(query);
qet.writeResultToStream(os, query._selectClause._selectedVariables, limit,
offset, sep);

Expand All @@ -386,7 +315,7 @@ string Server::composeResponseSepValues(const ParsedQuery& query,
// _____________________________________________________________________________
string Server::composeResponseJson(const string& query,
const std::exception& exception,
ad_utility::Timer& requestTimer) const {
ad_utility::Timer& requestTimer) {
std::ostringstream os;
requestTimer.stop();

Expand All @@ -402,7 +331,7 @@ string Server::composeResponseJson(const string& query,

// _____________________________________________________________________________
void Server::serveFile(uWS::HttpResponse<false>* resp,
const string& requestedFile) const {
const string& requestedFile) {
string contentString;
string contentType = "text/plain";
string statusString = "200 OK";
Expand Down Expand Up @@ -436,27 +365,23 @@ void Server::serveFile(uWS::HttpResponse<false>* resp,

// _____________________________________________________________________________
string Server::composeStatsJson() const {
std::ostringstream os;
os << "{\n"
<< "\"kbindex\": \"" << _index.getKbName() << "\",\n"
<< "\"permutations\": \"" << (_index.hasAllPermutations() ? "6" : "2")
<< "\",\n";
nlohmann::json result;
result["kbindex"] = _index.getKbName();
result["permutations"] = (_index.hasAllPermutations() ? "6" : "2");
if (_index.hasAllPermutations()) {
os << "\"nofsubjects\": \"" << _index.getNofSubjects() << "\",\n";
os << "\"nofpredicates\": \"" << _index.getNofPredicates() << "\",\n";
os << "\"nofobjects\": \"" << _index.getNofObjects() << "\",\n";
result["nofsubjects"] = _index.getNofSubjects();
result["nofpredicates"] = _index.getNofPredicates();
result["nofobjects"] = _index.getNofObjects();
}

auto [actualTriples, addedTriples] = _index.getNumTriplesActuallyAndAdded();
os << "\"noftriples\": \"" << _index.getNofTriples() << "\",\n"
<< "\"nofActualTriples\": \"" << actualTriples << "\",\n"
<< "\"nofAddedTriples\": \"" << addedTriples << "\",\n"
<< "\"textindex\": \"" << _index.getTextName() << "\",\n"
<< "\"nofrecords\": \"" << _index.getNofTextRecords() << "\",\n"
<< "\"nofwordpostings\": \"" << _index.getNofWordPostings() << "\",\n"
<< "\"nofentitypostings\": \"" << _index.getNofEntityPostings() << "\"\n"
<< "}\n";
return os.str();
result["noftriples"] = _index.getNofTriples();
result["nofActualTriples"] = actualTriples;
result["nofAddedTriples"] = addedTriples;
result["textindex"] = _index.getTextName();
result["nofrecords"] = _index.getNofTextRecords();
result["nofwordpostings"] = _index.getNofWordPostings();
result["nofentitypostings"] = _index.getNofEntityPostings();
return result.dump(4);
}

// _______________________________________
Expand Down
39 changes: 21 additions & 18 deletions src/engine/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,32 +75,35 @@ class Server {

void process(uWS::HttpResponse<false>* resp, uWS::HttpRequest* req);

void serveFile(uWS::HttpResponse<false>* resp,
const string& requestedFile) const;
static void serveFile(uWS::HttpResponse<false>* resp,
const string& requestedFile);

ParamValueMap parseHttpRequest(const string& request) const;
static string createQueryFromHttpParams(uWS::HttpRequest* req);

string createQueryFromHttpParams(uWS::HttpRequest* req) const;
static string createHttpResponse(const string& content,
const string& contentType);

string createHttpResponse(const string& content,
const string& contentType) const;
static void create404HttpResponse(uWS::HttpResponse<false>* resp);
static void create400HttpResponse(uWS::HttpResponse<false>* resp);

void create404HttpResponse(uWS::HttpResponse<false>* resp) const;
void create400HttpResponse(uWS::HttpResponse<false>* resp) const;
static string composeResponseJson(const ParsedQuery& query,
const QueryExecutionTree& qet,
ad_utility::Timer& requestTimer,
size_t sendMax = MAX_NOF_ROWS_IN_RESULT);

string composeResponseJson(const ParsedQuery& query,
const QueryExecutionTree& qet,
ad_utility::Timer& requestTimer,
size_t sendMax = MAX_NOF_ROWS_IN_RESULT) const;
static string composeResponseSepValues(const ParsedQuery& query,
const QueryExecutionTree& qet,
char sep);

string composeResponseSepValues(const ParsedQuery& query,
const QueryExecutionTree& qet,
char sep) const;

string composeResponseJson(const string& query, const std::exception& e,
ad_utility::Timer& requestTimer) const;
static string composeResponseJson(const string& query,
const std::exception& e,
ad_utility::Timer& requestTimer);

string composeStatsJson() const;

json composeCacheStatsJson() const;

static std::pair<size_t, size_t> parseLimitAndOffset(
const ParsedQuery& query,
size_t defaultLimit = std::numeric_limits<size_t>::max());
};
4 changes: 1 addition & 3 deletions third_party/uWebSockets/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ find_package(OpenSSL REQUIRED)

add_custom_command(
OUTPUT "${CMAKE_CURRENT_LIST_DIR}/src/uSockets/uSockets.a"
COMMAND ${CMAKE_COMMAND} -E env WITH_OPENSSL=1 CXX=${CMAKE_CXX_COMPILER} CC=${CMAKE_C_COMPILER} make
COMMAND ${CMAKE_COMMAND} -E env WITH_OPENSSL=1 CXX=${CMAKE_CXX_COMPILER} CC=${CMAKE_C_COMPILER} CXXFLAGS="-Wno-unused-parameter" make
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/src")

add_custom_target(uSocketsBuild ALL
Expand All @@ -21,5 +21,3 @@ target_include_directories(uWebSockets INTERFACE
${CMAKE_CURRENT_LIST_DIR}/src/src
${CMAKE_CURRENT_LIST_DIR}/src/uSockets/src)
target_link_libraries(uWebSockets INTERFACE z uSockets)


0 comments on commit 6c3cc5d

Please sign in to comment.