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-22 05:21:15 +08:00
|
|
|
#define NOT_LOG_INFO
|
2016-02-11 06:34:49 +08:00
|
|
|
|
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"
|
|
|
|
#include "utils/log/logger.hpp"
|
2016-02-07 03:48:40 +08:00
|
|
|
|
|
|
|
using std::string;
|
|
|
|
using std::cout;
|
|
|
|
using std::endl;
|
|
|
|
|
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:
|
|
|
|
using sptr_code_lib = std::shared_ptr<CodeLib>;
|
|
|
|
|
2016-02-22 05:21:15 +08:00
|
|
|
ProgramLoader()
|
2016-07-24 10:47:48 +08:00
|
|
|
: 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-07-18 01:32:35 +08:00
|
|
|
LOG_INFO("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-07-18 01:32:35 +08:00
|
|
|
LOG_INFO("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();
|
|
|
|
return QueryProgram(code, std::move(stripped));
|
|
|
|
}
|
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-02-22 05:21:15 +08:00
|
|
|
return QueryProgram(code_lib->instance(), std::move(stripped));
|
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;
|
|
|
|
|
|
|
|
CodeGenerator code_generator;
|
|
|
|
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
|
|
|
{
|
|
|
|
sptr_code_lib code_lib = std::make_shared<CodeLib>(path);
|
|
|
|
code_lib->load();
|
|
|
|
return code_lib;
|
|
|
|
}
|
|
|
|
};
|