Fixed Query compiler to use new interface.

This commit is contained in:
Kruno Tomola Fabro 2016-08-19 18:40:04 +01:00
parent e5f161974f
commit eba7fd8be4
25 changed files with 292 additions and 161 deletions

View File

@ -146,6 +146,7 @@ endforeach()
# TODO: somehow automate (in destination dir should be only required include files)
FILE(COPY ${include_dir}/database/db.hpp DESTINATION ${build_include_dir}/database)
FILE(COPY ${include_dir}/database/db_transaction.hpp DESTINATION ${build_include_dir}/database)
FILE(COPY ${include_dir}/database/db_accessor.hpp DESTINATION ${build_include_dir}/database)
FILE(COPY ${include_dir}/storage/common.hpp DESTINATION ${build_include_dir}/storage)
FILE(COPY ${include_dir}/storage/graph.hpp DESTINATION ${build_include_dir}/storage)
@ -163,6 +164,7 @@ FILE(COPY ${include_dir}/storage/edge_type/edge_type_store.hpp DESTINATION ${bui
FILE(COPY ${include_dir}/storage/edge_type/edge_type.hpp DESTINATION ${build_include_dir}/storage/edge_type)
FILE(COPY ${include_dir}/storage/label/label_store.hpp DESTINATION ${build_include_dir}/storage/label)
FILE(COPY ${include_dir}/storage/model/edge_map.hpp DESTINATION ${build_include_dir}/storage/model)
FILE(COPY ${include_dir}/storage/model/properties/flags.hpp DESTINATION ${build_include_dir}/storage/model/properties)
FILE(COPY ${include_dir}/query_engine/util.hpp DESTINATION ${build_include_dir}/query_engine)
FILE(COPY ${include_dir}/query_engine/i_code_cpu.hpp DESTINATION ${build_include_dir}/query_engine)
@ -171,6 +173,7 @@ FILE(COPY ${include_dir}/query_engine/query_stripped.hpp DESTINATION ${build_inc
FILE(COPY ${include_dir}/data_structures/concurrent/concurrent_map.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
FILE(COPY ${include_dir}/data_structures/concurrent/concurrent_set.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
FILE(COPY ${include_dir}/data_structures/concurrent/concurrent_list.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
FILE(COPY ${include_dir}/data_structures/concurrent/common.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
FILE(COPY ${include_dir}/data_structures/concurrent/skiplist.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
FILE(COPY ${include_dir}/data_structures/concurrent/skiplist_gc.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
@ -236,6 +239,8 @@ FILE(COPY ${include_dir}/storage/label/label_store.hpp DESTINATION ${build_inclu
FILE(COPY ${include_dir}/storage/indexes/index.hpp DESTINATION ${build_include_dir}/storage/indexes)
FILE(COPY ${include_dir}/storage/indexes/index_record.hpp DESTINATION ${build_include_dir}/storage/indexes)
FILE(COPY ${include_dir}/storage/indexes/index_record_collection.hpp DESTINATION ${build_include_dir}/storage/indexes)
FILE(COPY ${include_dir}/storage/indexes/index_base.hpp DESTINATION ${build_include_dir}/storage/indexes)
FILE(COPY ${include_dir}/storage/indexes/impl/nonunique_unordered_index.hpp DESTINATION ${build_include_dir}/storage/indexes/impl)
FILE(COPY ${include_dir}/utils/sys.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/utils/bswap.hpp DESTINATION ${build_include_dir}/utils)
@ -257,7 +262,10 @@ FILE(COPY ${include_dir}/utils/exceptions/basic_exception.hpp DESTINATION ${buil
FILE(COPY ${include_dir}/utils/datetime/timestamp.hpp DESTINATION ${build_include_dir}/utils/datetime)
FILE(COPY ${include_dir}/utils/datetime/datetime_error.hpp DESTINATION ${build_include_dir}/utils/datetime)
FILE(COPY ${include_dir}/utils/types/byte.hpp DESTINATION ${build_include_dir}/utils/types)
FILE(COPY ${include_dir}/utils/iterator/iterator_base.hpp DESTINATION ${build_include_dir}/utils/iterator)
FILE(COPY ${include_dir}/utils/option_ptr.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/utils/option.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/utils/border.hpp DESTINATION ${build_include_dir}/utils)
FILE(COPY ${include_dir}/communication/communication.hpp DESTINATION ${build_include_dir}/communication)
FILE(COPY ${include_dir}/communication/bolt/v1/config.hpp DESTINATION ${build_include_dir}/communication/bolt/v1)
@ -463,7 +471,7 @@ execute_process(
COMMAND git rev-parse --short HEAD
)
execute_process(
OUTPUT_VARIABLE COMMIT_NO
OUTPUT_VARIABLE COMMIT_NO
COMMAND git rev-list --count HEAD
)
string(STRIP ${COMMIT_BRANCH} COMMIT_BRANCH)

View File

@ -56,7 +56,7 @@ public:
encoder.write_map_header(props.size());
for (auto &prop : props) {
write(prop.first);
write(prop.first.family_name());
write(*prop.second);
}
}
@ -93,7 +93,7 @@ public:
encoder.write_map_header(props.size());
for (auto &prop : props) {
write(prop.first);
write(prop.first.family_name());
write(*prop.second);
}
}

View File

@ -77,6 +77,13 @@ public:
PropertyFamily &edge_property_family_get(const std::string &name);
// ******************** PROPERTY HELPER METHODS
PropertyFamily::PropertyType::PropertyFamilyKey
vertex_property_key(const std::string &name, Type type);
PropertyFamily::PropertyType::PropertyFamilyKey
edge_property_key(const std::string &name, Type type);
// ******************** TRANSACTION METHODS
void commit();

View File

@ -4,6 +4,9 @@
#include <map>
#include <string>
#include "query_engine/code_generator/namer.hpp"
#include "storage/model/properties/flags.hpp"
// main states that are used while ast is traversed
// in order to generate ActionSequence
enum class CypherState : uint8_t
@ -36,10 +39,11 @@ class CypherStateData
private:
std::map<std::string, EntityStatus> entity_status;
std::map<std::string, EntityType> entity_type;
// TODO: container that keeps track about c++ variable names
public:
bool exist(const std::string& name) const
bool exist(const std::string &name) const
{
return entity_status.find(name) != entity_status.end();
}
@ -52,7 +56,7 @@ public:
return entity_status.at(name);
}
EntityType type(const std::string &name)
EntityType type(const std::string &name) const
{
if (entity_type.find(name) == entity_type.end())
return EntityType::NotFound;
@ -60,6 +64,11 @@ public:
return entity_type.at(name);
}
const std::map<std::string, EntityType> &all_typed_enteties()
{
return entity_type;
}
void node_matched(const std::string &name)
{
entity_type[name] = EntityType::Node;

View File

@ -1,9 +1,9 @@
#pragma once
#include "query_engine/code_generator/handlers/create.hpp"
#include "query_engine/code_generator/handlers/delete.hpp"
#include "query_engine/code_generator/handlers/match.hpp"
#include "query_engine/code_generator/handlers/return.hpp"
#include "query_engine/code_generator/handlers/set.hpp"
#include "query_engine/code_generator/handlers/delete.hpp"
#include "query_engine/code_generator/handlers/transaction_begin.hpp"
#include "query_engine/code_generator/handlers/transaction_commit.hpp"

View File

@ -16,7 +16,7 @@ auto create_query_action =
code += code_line(code::create_vertex, name);
// update properties
code += update_properties(action_data, name);
code += update_properties(cypher_data, action_data, name);
// update labels
auto entity_data = action_data.get_entity_property(name);
@ -30,19 +30,7 @@ auto create_query_action =
}
if (kv.second == ClauseAction::CreateRelationship) {
// create relationship
auto name = kv.first;
code += code_line(code::create_edge, name);
// update properties
code += update_properties(action_data, name);
// update tag
auto entity_data = action_data.get_entity_property(name);
for (auto &tag : entity_data.tags) {
code += code_line(code::find_type, tag);
code += code_line(code::set_type, name, tag);
}
// find start and end node
auto &relationships_data = action_data.relationship_data;
@ -63,19 +51,32 @@ auto create_query_action =
" can't be found");
}
// define direction
if (relationship_data.direction == Direction::Right) {
code += code_line(code::node_out, left_node, name);
code += code_line(code::node_in, right_node, name);
code += code_line(code::edge_from, name, left_node);
code += code_line(code::edge_to, name, right_node);
} else if (relationship_data.direction == Direction::Left) {
code += code_line(code::node_out, right_node, name);
code += code_line(code::node_in, left_node, name);
code += code_line(code::edge_from, name, right_node);
code += code_line(code::edge_to, name, left_node);
// create relationship
code += code_line(code::create_edge, name, left_node, right_node);
// update properties
code += update_properties(cypher_data, action_data, name);
// update tag
auto entity_data = action_data.get_entity_property(name);
for (auto &tag : entity_data.tags) {
code += code_line(code::find_type, tag);
code += code_line(code::set_type, name, tag);
}
// define direction
// if (relationship_data.direction == Direction::Right) {
// code += code_line(code::node_out, left_node, name);
// code += code_line(code::node_in, right_node, name);
// code += code_line(code::edge_from, name, left_node);
// code += code_line(code::edge_to, name, right_node);
// } else if (relationship_data.direction == Direction::Left) {
// code += code_line(code::node_out, right_node, name);
// code += code_line(code::node_in, left_node, name);
// code += code_line(code::edge_from, name, right_node);
// code += code_line(code::edge_to, name, left_node);
// }
// mark relationship as created
cypher_data.relationship_created(name);
}

View File

@ -6,11 +6,12 @@
#include <utility>
#include <vector>
#include "query_engine/util.hpp"
#include "query_engine/code_generator/cypher_state.hpp"
#include "query_engine/code_generator/namer.hpp"
#include "query_engine/code_generator/query_action_data.hpp"
#include "query_engine/traverser/code.hpp"
#include "query_engine/exceptions/errors.hpp"
#include "query_engine/traverser/code.hpp"
#include "query_engine/util.hpp"
using ParameterIndexKey::Type::InternalId;
using Direction = RelationshipData::Direction;
@ -18,7 +19,8 @@ using Direction = RelationshipData::Direction;
namespace
{
auto update_properties(const QueryActionData &action_data,
auto update_properties(const CypherStateData &cypher_state,
const QueryActionData &action_data,
const std::string &name)
{
std::string code = "";
@ -27,10 +29,14 @@ auto update_properties(const QueryActionData &action_data,
for (auto &property : entity_data.properties) {
auto index =
action_data.parameter_index.at(ParameterIndexKey(name, property));
code += code_line(code::set_property, name, property, index);
auto tmp_name = name::unique();
code += code_line((cypher_state.type(name) == EntityType::Node
? code::vertex_property_key
: code::edge_property_key),
tmp_name, property, index);
code += code_line(code::set_property, name, tmp_name, index);
}
return code;
}
}

View File

@ -20,7 +20,6 @@ auto fetch_internal_index(const QueryActionData &action_data,
{
return action_data.parameter_index.at(ParameterIndexKey(InternalId, name));
}
}
auto match_query_action =
@ -40,8 +39,7 @@ auto match_query_action =
auto place = action_data.csm.min(kv.first);
if (place == entity_search::search_internal_id) {
auto index = fetch_internal_index(action_data, name);
code +=
code_line(code::match_vertex_by_id, name, index);
code += code_line(code::match_vertex_by_id, name, index);
}
}

View File

@ -12,7 +12,7 @@ auto return_query_action =
code += code_line("// number of elements {}", elements.size());
// TODO: call bolt serialization
for (const auto& element : elements) {
for (const auto &element : elements) {
auto &entity = element.entity;
if (!cypher_data.exist(entity)) {
throw SemanticError(
@ -26,6 +26,6 @@ auto return_query_action =
// code += code_line(code::print_property, entity, property);
}
}
return code;
};

View File

@ -13,13 +13,13 @@ auto set_query_action = [](CypherStateData &cypher_data,
if (kv.second == ClauseAction::UpdateNode &&
cypher_data.status(name) == EntityStatus::Matched &&
cypher_data.type(name) == EntityType::Node) {
code += update_properties(action_data, name);
code += update_properties(cypher_data, action_data, name);
}
if (kv.second == ClauseAction::UpdateRelationship &&
cypher_data.status(name) == EntityStatus::Matched &&
cypher_data.type(name) == EntityType::Relationship) {
code += update_properties(action_data, name);
code += update_properties(cypher_data, action_data, name);
}
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "storage/model/properties/flags.hpp"
// This namespace names stuff
namespace
{
namespace name
{
std::string variable_property_key(const std::string &property_name, Type type)
{
return "prop_" + property_name + "_" + type.to_str();
}
std::string unique() { return "unique_" + std::to_string(std::rand()); }
}
}

View File

@ -4,9 +4,9 @@
#include <map>
#include <vector>
#include "query_engine/exceptions/exceptions.hpp"
#include "query_engine/code_generator/clause_action.hpp"
#include "query_engine/code_generator/entity_search.hpp"
#include "query_engine/exceptions/exceptions.hpp"
#include "storage/model/properties/all.hpp"
#include "utils/assert.hpp"
#include "utils/underlying_cast.hpp"
@ -97,9 +97,9 @@ struct RelationshipData
struct ReturnElement
{
ReturnElement(const std::string& entity) : entity(entity) {}
ReturnElement(const std::string& entity, const std::string& property) :
entity(entity), property(property) {};
ReturnElement(const std::string &entity) : entity(entity) {}
ReturnElement(const std::string &entity, const std::string &property)
: entity(entity), property(property){};
std::string entity;
std::string property;
@ -143,7 +143,7 @@ struct QueryActionData
}
// TODO: refactor name
auto get_entity_property(const std::string& entity) const
auto get_entity_property(const std::string &entity) const
{
if (entity_data.find(entity) == entity_data.end())
throw CppGeneratorException("Entity " + entity + " doesn't exist");

View File

@ -18,9 +18,7 @@ auto load_queries(Db &db)
// CREATE (n {prop: 0}) RETURN n)
auto create_node = [&db](const properties_t &args) {
DbAccessor t(db);
auto prop_key = t.vertex_property_family_get("prop")
.get(args[0]->flags)
.family_key();
auto prop_key = t.vertex_property_key("prop", args[0]->flags);
auto vertex_accessor = t.vertex_insert();
vertex_accessor.set(prop_key, args[0]);
@ -31,13 +29,11 @@ auto load_queries(Db &db)
auto create_labeled_and_named_node = [&db](const properties_t &args) {
DbAccessor t(db);
auto prop_key = t.vertex_property_family_get("name")
.get(args[0]->flags)
.family_key();
auto prop_key = t.vertex_property_key("name", args[0]->flags);
auto &label = t.label_find_or_create("LABEL");
auto vertex_accessor = t.vertex_insert();
vertex_accessor.set(prop_key, args[0]);
auto &label = t.label_find_or_create("LABEL");
vertex_accessor.add_label(label);
cout_properties(vertex_accessor.properties());
t.commit();
@ -46,24 +42,17 @@ auto load_queries(Db &db)
auto create_account = [&db](const properties_t &args) {
DbAccessor t(db);
auto prop_id =
t.vertex_property_family_get("id").get(args[0]->flags).family_key();
auto prop_name = t.vertex_property_family_get("name")
.get(args[1]->flags)
.family_key();
auto prop_country = t.vertex_property_family_get("country")
.get(args[2]->flags)
.family_key();
auto prop_created = t.vertex_property_family_get("created_at")
.get(args[3]->flags)
.family_key();
auto prop_id = t.vertex_property_key("id", args[0]->flags);
auto prop_name = t.vertex_property_key("name", args[1]->flags);
auto prop_country = t.vertex_property_key("country", args[2]->flags);
auto prop_created = t.vertex_property_key("created_at", args[3]->flags);
auto &label = t.label_find_or_create("ACCOUNT");
auto vertex_accessor = t.vertex_insert();
vertex_accessor.set(prop_id, args[0]);
vertex_accessor.set(prop_name, args[1]);
vertex_accessor.set(prop_country, args[2]);
vertex_accessor.set(prop_created, args[3]);
auto &label = t.label_find_or_create("ACCOUNT");
vertex_accessor.add_label(label);
cout_properties(vertex_accessor.properties());
t.commit();
@ -90,6 +79,7 @@ auto load_queries(Db &db)
auto create_edge = [&db](const properties_t &args) {
DbAccessor t(db);
auto &edge_type = t.type_find_or_create("IS");
auto v1 = t.vertex_find(args[0]->as<Int32>().value);
if (!option_fill(v1)) return t.commit(), false;
@ -99,7 +89,6 @@ auto load_queries(Db &db)
auto edge_accessor = t.edge_insert(v1.get(), v2.get());
auto &edge_type = t.type_find_or_create("IS");
edge_accessor.edge_type(edge_type);
t.commit();
@ -139,9 +128,7 @@ auto load_queries(Db &db)
auto update_node = [&db](const properties_t &args) {
DbAccessor t(db);
auto prop_name = t.vertex_property_family_get("name")
.get(args[1]->flags)
.family_key();
auto prop_name = t.vertex_property_key("name", args[1]->flags);
auto maybe_v = t.vertex_find(args[0]->as<Int32>().value);
if (!option_fill(maybe_v)) return t.commit(), false;
@ -160,11 +147,8 @@ auto load_queries(Db &db)
auto create_edge_v2 = [&db](const properties_t &args) {
DbAccessor t(db);
auto prop_age =
t.edge_property_family_get("age").get(args[2]->flags).family_key();
auto prop_weight = t.edge_property_family_get("weight")
.get(args[3]->flags)
.family_key();
auto prop_age = t.edge_property_key("age", args[2]->flags);
auto prop_weight = t.edge_property_key("weight", args[3]->flags);
auto n1 = t.vertex_find(args[0]->as<Int64>().value);
if (!option_fill(n1)) return t.commit(), false;
@ -202,8 +186,7 @@ auto load_queries(Db &db)
DbAccessor t(db);
auto &label = t.label_find_or_create("LABEL");
auto prop_key =
t.vertex_property_family_get("name").get(Type::String).family_key();
auto prop_key = t.vertex_property_key("name", Flags::String);
cout << "VERTICES" << endl;
iter::for_all(label.index->for_range_exact(t),

View File

@ -2,6 +2,7 @@
#include "communication/communication.hpp"
#include "database/db.hpp"
#include "database/db_accessor.hpp"
#include "query_engine/query_stripped.hpp"
class ICodeCPU

View File

@ -16,56 +16,53 @@ namespace code
// TODO: UNIT tests
const std::string transaction_begin = "auto& t = db.tx_engine.begin();";
const std::string transaction_begin = "DbAccessor t(db);";
const std::string transaction_commit = "t.commit();";
const std::string set_property = "{}.property(\"{}\", args[{}]);";
const std::string set_property = "{}.set({}, args[{}]);";
// create vertex e.g. CREATE (n:PERSON {name: "Test", age: 23})
const std::string create_vertex = "auto {} = db.graph.vertices.insert(t);";
const std::string create_label =
"auto &{0} = db.graph.label_store.find_or_create(\"{0}\");";
const std::string create_vertex = "auto {} = t.vertex_insert();";
const std::string create_label = "auto &{0} = t.label_find_or_create(\"{0}\");";
const std::string add_label = "{}.add_label({});";
const std::string vertex_property_key =
"auto {}=t.vertex_property_key(\"{}\",args[{}]->flags);";
const std::string edge_property_key =
"auto {}=t.edge_property_key(\"{}\",args[{}]->flags);";
// create edge e.g CREATE (n1)-[r:COST {cost: 100}]->(n2)
const std::string create_edge = "auto {} = db.graph.edges.insert(t);";
const std::string find_type =
"auto &{0} = db.graph.edge_type_store.find_or_create(\"{0}\");";
const std::string create_edge = "auto {} = t.edge_insert({},{});";
const std::string find_type = "auto &{0} = t.type_find_or_create(\"{0}\");";
const std::string set_type = "{}.edge_type({});";
const std::string node_out = "{}.vlist->update(t)->data.out.add({}.vlist);";
const std::string node_in = "{}.vlist->update(t)->data.in.add({}.vlist);";
const std::string edge_from = "{}.from({}.vlist);";
const std::string edge_to = "{}.to({}.vlist);";
const std::string args_id = "auto id = args[{}]->as<Int32>();";
const std::string vertex_accessor_args_id =
"auto vertex_accessor = db.graph.vertices.find(t, id.value);";
"auto vertex_accessor = t.vertex_find(id.value);";
const std::string match_vertex_by_id =
"auto {0} = db.graph.vertices.find(t, args[{1}]->as<Int64>().value);\n"
" if (!{0}) return t.commit(), false;";
"auto option_{0} = t.vertex_find(args[{1}]->as<Int64>().value);\n"
" if (!option_fill(option_{0})) return t.commit(), false;\n"
" auto {0}=option_{0}.take();";
const std::string match_edge_by_id =
"auto {0} = db.graph.edges.find(t, args[{1}]->as<Int64>().value);\n"
" if (!{0}) return t.commit(), false;";
"auto option_{0} = t.edge_find(args[{1}]->as<Int64>().value);\n"
" if (!option_fill(option_{0})) return t.commit(), false;\n"
" auto {0}=option_{0}.take();";
const std::string write_entity =
"stream.write_field(\"{0}\");\n"
" stream.write_record();\n"
" stream.write_list_header(1);\n"
" stream.write({0});\n"
" stream.write_success_empty();\n";
const std::string write_entity = "stream.write_field(\"{0}\");\n"
" stream.write_record();\n"
" stream.write_list_header(1);\n"
" stream.write({0});\n"
" stream.write_success_empty();\n";
const std::string return_true = "return true;";
const std::string update_property = "{}.property(\"{}\", args[{}]);";
const std::string todo = "// TODO: {}";
const std::string print_properties =
"cout << \"{0}\" << endl;\n"
" cout_properties({0}.properties());";
const std::string print_property =
"cout_property(\"{0}\", {0}.property(\"{1}\"));";
}

View File

@ -8,8 +8,6 @@
#include "storage/vertex_accessor.hpp"
#include "utils/reference_wrapper.hpp"
#include "utils/total_ordering.hpp"
#include "utils/void.hpp"
using LabelIndexRecord = VertexIndexRecord<std::nullptr_t>;
class Label : public TotalOrdering<Label>

View File

@ -1,5 +1,9 @@
#pragma once
#include <cassert>
#include "utils/total_ordering.hpp"
#include "utils/underlying_cast.hpp"
enum class Flags : unsigned
{
// Type | Mask
@ -42,4 +46,64 @@ enum class Flags : unsigned
Array = 0x1000,
type_mask = 0xFFF
};
// Mask to turn flags into type. It passes all bits except 0x2 and 0x4 which
// correspond
// to True and False.
const unsigned flags_equal_mask = 0xFF9;
class Type : public TotalOrdering<Type>
{
public:
Type(Flags f) : value(underlying_cast(f) & flags_equal_mask)
{
Flags o = Flags(value);
assert(o == Flags::Null || o == Flags::Bool || o == Flags::String ||
o == Flags::Int32 || o == Flags::Int64 || o == Flags::Float ||
o == Flags::Double || o == Flags::Array);
}
const std::string to_str()
{
switch (Flags(value)) {
case Flags::Null:
return "null";
case Flags::Bool:
return "bool";
case Flags::String:
return "str";
case Flags::Int32:
return "int32";
case Flags::Int64:
return "int64";
case Flags::Float:
return "float";
case Flags::Double:
return "double";
case Flags::Array:
return "array";
default:
assert(false);
return "err_unknown_type_" + std::to_string(value);
}
}
bool operator==(Flags other) const { return *this == Type(other); }
bool operator!=(Flags other) const { return *this != Type(other); }
friend bool operator<(const Type &lhs, const Type &rhs)
{
return lhs.value < rhs.value;
}
friend bool operator==(const Type &lhs, const Type &rhs)
{
return lhs.value == rhs.value;
}
private:
const unsigned value;
};

View File

@ -24,6 +24,8 @@ public:
size_t size() const { return props.size(); }
const Property &at(PropertyFamily &key) const;
const Property &at(prop_key_t &key) const;
template <class T>
@ -36,6 +38,8 @@ public:
void clear(prop_key_t &key);
void clear(PropertyFamily &key);
template <class Handler>
void accept(Handler &handler) const
{

View File

@ -7,8 +7,6 @@
#include "utils/total_ordering.hpp"
#include "utils/underlying_cast.hpp"
typedef Flags Type;
// Family of properties with the same name but different types.
// Ordered on name.
class PropertyFamily : public TotalOrdering<PropertyFamily>
@ -28,7 +26,10 @@ public:
public:
// Ordered on POINTERS to PropertyFamily
class PropertyFamilyKey : public TotalOrdering<PropertyFamilyKey>
class PropertyFamilyKey
: public TotalOrdering<PropertyFamilyKey>,
public TotalOrdering<PropertyFamilyKey, PropertyFamily>,
public TotalOrdering<PropertyFamily, PropertyFamilyKey>
{
friend class PropertyType;
friend class PropertyTypeKey;
@ -48,6 +49,30 @@ public:
return &(lhs.type->family) < &(rhs.type->family);
}
friend bool operator==(const PropertyFamilyKey &lhs,
const PropertyFamily &rhs)
{
return &(lhs.type->family) == &(rhs);
}
friend bool operator<(const PropertyFamilyKey &lhs,
const PropertyFamily &rhs)
{
return &(lhs.type->family) < &(rhs);
}
friend bool operator==(const PropertyFamily &lhs,
const PropertyFamilyKey &rhs)
{
return &(lhs) == &(rhs.type->family);
}
friend bool operator<(const PropertyFamily &lhs,
const PropertyFamilyKey &rhs)
{
return &(lhs) < &(rhs.type->family);
}
Type prop_type() const { return type->type; }
std::string const &family_name() const
@ -62,10 +87,7 @@ public:
// Ordered on POINTERS to PropertyType.
// When compared with PropertyFamilyKey behaves as PropertyFamilyKey.
template <class T>
class PropertyTypeKey
: public TotalOrdering<PropertyTypeKey<T>>,
public TotalOrdering<PropertyFamilyKey, PropertyTypeKey<T>>,
public TotalOrdering<PropertyTypeKey<T>, PropertyFamilyKey>
class PropertyTypeKey : public TotalOrdering<PropertyTypeKey<T>>
{
friend class PropertyType;
@ -87,30 +109,6 @@ public:
return &(lhs.type) < &(rhs.type);
}
friend bool operator==(const PropertyFamilyKey &lhs,
const PropertyTypeKey &rhs)
{
return &(lhs.type->family) == &(rhs.type.family);
}
friend bool operator<(const PropertyFamilyKey &lhs,
const PropertyTypeKey &rhs)
{
return &(lhs.type->family) < &(rhs.type.family);
}
friend bool operator==(const PropertyTypeKey &lhs,
const PropertyFamilyKey &rhs)
{
return &(lhs.type.family) == &(rhs.type->family);
}
friend bool operator<(const PropertyTypeKey &lhs,
const PropertyFamilyKey &rhs)
{
return &(lhs.type.family) < &(rhs.type->family);
}
private:
const PropertyType &type;
};
@ -124,7 +122,7 @@ public:
template <class T>
bool is() const
{
return underlying_cast(type) & underlying_cast(T::type);
return type == T::type;
}
bool is(Type &t) const;
@ -167,6 +165,9 @@ public:
// Returns type if it exists otherwise creates it.
PropertyType &get(Type type);
// Return pointer for NULL type. Extremly fast.
PropertyType &getNull() { return *null_type; }
friend bool operator<(const PropertyFamily &lhs, const PropertyFamily &rhs);
friend bool operator==(const PropertyFamily &lhs,
@ -174,7 +175,8 @@ public:
private:
const std::string name_v;
// This is exclusivly for getNull method.
PropertyType *null_type{nullptr};
// TODO: Because types wont be removed this could be done with more efficent
// data structure.
ConcurrentMap<Type, std::unique_ptr<PropertyType>> types;

View File

@ -39,11 +39,7 @@ public:
return record != nullptr;
}
const Id &id() const
{
assert(!empty());
return vlist->id;
}
const Id &id() const { return vlist->id; }
Derived update() const
{
@ -59,6 +55,11 @@ public:
return vlist->remove(record, db.trans);
}
const Property &at(PropertyFamily &key) const
{
return properties().at(key);
}
const Property &at(prop_key_t &key) const { return properties().at(key); }
template <class V>
@ -77,6 +78,8 @@ public:
void clear(prop_key_t &key) { properties().clear(key); }
void clear(PropertyFamily &key) { properties().clear(key); }
template <class Handler>
void accept(Handler &handler) const
{

View File

@ -189,7 +189,7 @@ auto a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
{
DbAccessor t(db);
type_key_t<Double> tkey = t.vertex_property_family_get("score")
.get(Type::Double)
.get(Flags::Double)
.type_key<Double>();
auto best_found = new std::map<Id, Score>[max_depth];
@ -366,16 +366,16 @@ int load_csv(Db &db, char *file_path, char *edge_file_path)
DbAccessor t(db);
auto key_id =
t.vertex_property_family_get("id").get(Type::Int32).family_key();
t.vertex_property_family_get("id").get(Flags::Int32).family_key();
auto key_garment_id = t.vertex_property_family_get("garment_id")
.get(Type::Int32)
.get(Flags::Int32)
.family_key();
auto key_garment_category_id =
t.vertex_property_family_get("garment_category_id")
.get(Type::Int32)
.get(Flags::Int32)
.family_key();
auto key_score =
t.vertex_property_family_get("score").get(Type::Double).family_key();
t.vertex_property_family_get("score").get(Flags::Double).family_key();
int max_score = 1000000;
@ -457,7 +457,7 @@ int load_csv(Db &db, char *file_path, char *edge_file_path)
void load_graph_dummy(Db &db)
{
DbAccessor t(db);
// TODO: update code
// auto v = [&](auto id, auto score) {
// auto vertex_accessor = t.vertex_insert();

View File

@ -1,5 +1,5 @@
#include "database/db_accessor.hpp"
#include "database/db.hpp"
#include "database/db_accessor.hpp"
#include "utils/iterator/iterator.hpp"
DbAccessor::DbAccessor(Db &db)
@ -70,6 +70,7 @@ bool DbAccessor::type_contains(const std::string &name)
std::forward<const std::string &>(name));
}
// PROPERTY METHODS
PropertyFamily &DbAccessor::vertex_property_family_get(const std::string &name)
{
return db_transaction.db.graph.vertices.property_family_find_or_create(
@ -81,6 +82,19 @@ PropertyFamily &DbAccessor::edge_property_family_get(const std::string &name)
return db_transaction.db.graph.edges.property_family_find_or_create(name);
}
// PROPERTY HELPER METHODS
PropertyFamily::PropertyType::PropertyFamilyKey
DbAccessor::vertex_property_key(const std::string &name, Type type)
{
return vertex_property_family_get(name).get(type).family_key();
}
PropertyFamily::PropertyType::PropertyFamilyKey
DbAccessor::edge_property_key(const std::string &name, Type type)
{
return edge_property_family_get(name).get(type).family_key();
}
// TRANSACTION METHODS
void DbAccessor::commit() { db_transaction.trans.commit(); }
void DbAccessor::abort() { db_transaction.trans.abort(); }

View File

@ -24,12 +24,12 @@ public:
};
extern "C" ICodeCPU* produce()
extern "C" ICodeCPU* produce()
{
return new {{class_name}}();
}
extern "C" void destruct(ICodeCPU* p)
extern "C" void destruct(ICodeCPU* p)
{
delete p;
}

View File

@ -4,11 +4,26 @@
#include "storage/model/properties/property_family.hpp"
#include "utils/option.hpp"
const Property &Properties::at(PropertyFamily &fam) const
{
// It doesn't matter whit which type
// find is called, thats why getNull
// method is here to give fast access
// to such key.
auto key = fam.getNull().family_key();
auto it = props.find(key);
if (it == props.end()) return Property::Null;
return *it->second.get();
}
const Property &Properties::at(prop_key_t &key) const
{
auto it = props.find(key);
if (it == props.end()) return Property::Null;
if (it == props.end() || it->first.prop_type() != key.prop_type())
return Property::Null;
return *it->second.get();
}
@ -59,14 +74,15 @@ void Properties::set(prop_key_t &key, Property::sptr value)
void Properties::clear(prop_key_t &key) { props.erase(key); }
// template <class Handler>
// void Properties::accept(Handler& handler) const
// {
// for(auto& kv : props)
// handler.handle(kv.first, *kv.second);
//
// handler.finish();
// }
void Properties::clear(PropertyFamily &fam)
{
// It doesn't matter whit which type
// find is called, thats why getNull
// method is here to give fast access
// to such key.
auto key = fam.getNull().family_key();
props.erase(key);
}
template <>
inline void Properties::set<Null>(type_key_t<Null> &key)

View File

@ -3,9 +3,11 @@
PropertyFamily::PropertyFamily(std::string const &name_v)
: name_v(std::forward<const std::string>(name_v))
{
null_type = &get(Flags::Null);
}
PropertyFamily::PropertyFamily(std::string &&name_v) : name_v(std::move(name_v))
{
null_type = &get(Flags::Null);
}
std::string const &PropertyFamily::name() const { return name_v; }