2016-02-07 03:48:40 +08:00
|
|
|
#pragma once
|
|
|
|
|
2016-06-06 17:29:52 +08:00
|
|
|
#include <memory>
|
2016-02-07 03:48:40 +08:00
|
|
|
#include <string>
|
|
|
|
#include <unordered_map>
|
|
|
|
|
2016-02-08 05:56:52 +08:00
|
|
|
#include "config/config.hpp"
|
2016-08-10 16:39:02 +08:00
|
|
|
#include "query_engine/code_compiler.hpp"
|
|
|
|
#include "query_engine/code_generator.hpp"
|
|
|
|
#include "query_engine/memgraph_dynamic_lib.hpp"
|
|
|
|
#include "query_engine/query_program.hpp"
|
|
|
|
#include "query_engine/query_stripper.hpp"
|
2016-06-06 17:29:52 +08:00
|
|
|
#include "utils/hashing/fnv.hpp"
|
2016-08-11 11:47:30 +08:00
|
|
|
#include "logging/default.hpp"
|
2016-02-07 03:48:40 +08:00
|
|
|
|
|
|
|
using std::string;
|
|
|
|
|
2016-08-29 01:50:54 +08:00
|
|
|
template <typename Stream>
|
2016-02-22 05:21:15 +08:00
|
|
|
class ProgramLoader
|
2016-06-06 17:29:52 +08:00
|
|
|
{
|
2016-02-07 03:48:40 +08:00
|
|
|
public:
|
2016-08-29 01:50:54 +08:00
|
|
|
using code_lib_t = CodeLib<Stream>;
|
|
|
|
using sptr_code_lib = std::shared_ptr<code_lib_t>;
|
|
|
|
using query_program_t = QueryProgram<Stream>;
|
2016-02-07 03:48:40 +08:00
|
|
|
|
2016-08-11 11:47:30 +08:00
|
|
|
ProgramLoader() :
|
2016-08-19 00:47:49 +08:00
|
|
|
logger(logging::log->logger("ProgramLoader")),
|
|
|
|
stripper(make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL))
|
2016-06-06 17:29:52 +08:00
|
|
|
{
|
|
|
|
}
|
2016-02-07 03:48:40 +08:00
|
|
|
|
2016-06-06 17:29:52 +08:00
|
|
|
auto load(const string &query)
|
2016-02-07 03:48:40 +08:00
|
|
|
{
|
|
|
|
auto stripped = stripper.strip(query);
|
2016-08-11 11:47:30 +08:00
|
|
|
logger.debug("stripped_query = {}", stripped.query);
|
2016-02-22 05:21:15 +08:00
|
|
|
|
2016-07-02 05:05:03 +08:00
|
|
|
auto hash_string = std::to_string(stripped.hash);
|
2016-08-11 11:47:30 +08:00
|
|
|
logger.debug("query_hash = {}", hash_string);
|
2016-02-08 05:56:52 +08:00
|
|
|
|
2016-07-11 09:39:33 +08:00
|
|
|
auto code_lib_iter = code_libs.find(stripped.hash);
|
2016-02-08 05:56:52 +08:00
|
|
|
|
|
|
|
// code is already compiled and loaded, just return runnable
|
|
|
|
// instance
|
2016-02-22 05:21:15 +08:00
|
|
|
if (code_lib_iter != code_libs.end()) {
|
|
|
|
auto code = code_lib_iter->second->instance();
|
2016-08-29 01:50:54 +08:00
|
|
|
return query_program_t(code, std::move(stripped));
|
2016-02-22 05:21:15 +08:00
|
|
|
}
|
2016-02-08 05:56:52 +08:00
|
|
|
|
|
|
|
// code has to be generated, compiled and loaded
|
|
|
|
// TODO load output path from config
|
|
|
|
auto base_path = config::Config::instance()[config::COMPILE_CPU_PATH];
|
|
|
|
auto path_cpp = base_path + hash_string + ".cpp";
|
2016-07-24 10:47:48 +08:00
|
|
|
auto stripped_space = stripper.strip_space(query);
|
|
|
|
code_generator.generate_cpp(stripped_space.query, stripped.hash,
|
|
|
|
path_cpp);
|
2016-06-06 17:29:52 +08:00
|
|
|
|
2016-02-08 05:56:52 +08:00
|
|
|
auto path_so = base_path + hash_string + ".so";
|
|
|
|
code_compiler.compile(path_cpp, path_so);
|
|
|
|
|
|
|
|
// loads dynamic lib and store it
|
|
|
|
auto code_lib = load_code_lib(path_so);
|
2016-07-11 09:39:33 +08:00
|
|
|
code_libs.insert({{stripped.hash, code_lib}});
|
2016-02-07 03:48:40 +08:00
|
|
|
|
2016-07-18 01:32:35 +08:00
|
|
|
// return an instance of runnable code (ICodeCPU)
|
2016-08-29 01:50:54 +08:00
|
|
|
return query_program_t(code_lib->instance(), std::move(stripped));
|
2016-02-07 03:48:40 +08:00
|
|
|
}
|
|
|
|
|
2016-08-11 11:47:30 +08:00
|
|
|
protected:
|
|
|
|
Logger logger;
|
|
|
|
|
2016-02-07 03:48:40 +08:00
|
|
|
private:
|
|
|
|
// TODO somehow remove int.. from here
|
2016-02-22 05:21:15 +08:00
|
|
|
QueryStripper<int, int, int, int> stripper;
|
2016-07-18 01:32:35 +08:00
|
|
|
|
2016-02-07 03:48:40 +08:00
|
|
|
// TODO ifdef MEMGRAPH64 problem, how to use this kind
|
|
|
|
// of ifdef functions?
|
|
|
|
// uint64_t depends on fnv function
|
|
|
|
std::unordered_map<uint64_t, sptr_code_lib> code_libs;
|
|
|
|
|
2016-08-29 01:50:54 +08:00
|
|
|
CodeGenerator<Stream> code_generator;
|
2016-02-07 03:48:40 +08:00
|
|
|
CodeCompiler code_compiler;
|
|
|
|
|
2016-06-06 17:29:52 +08:00
|
|
|
sptr_code_lib load_code_lib(const string &path)
|
2016-02-07 03:48:40 +08:00
|
|
|
{
|
2016-08-29 01:50:54 +08:00
|
|
|
sptr_code_lib code_lib = std::make_shared<CodeLib<Stream>>(path);
|
2016-02-07 03:48:40 +08:00
|
|
|
code_lib->load();
|
|
|
|
return code_lib;
|
|
|
|
}
|
|
|
|
};
|