Created EdgeRecord as class and changed in edge vector for map.
EdgeRecord now contains from,to fields as immutables. Vertex in place of in vector of edges has in RbHashMultimap of edges. Astar exepriment now uses real filters based on before mentioned map.
This commit is contained in:
parent
c3c8fb6620
commit
61eccc28ce
@ -1,11 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include "mvcc/version_list.hpp"
|
#include "mvcc/version_list.hpp"
|
||||||
#include "storage/edge.hpp"
|
#include "storage/edge.hpp"
|
||||||
|
|
||||||
// class EdgeRecord: public mvcc::VersionList<Edge>{
|
class EdgeRecord : public mvcc::VersionList<Edge>
|
||||||
// public:
|
{
|
||||||
// using mvcc::VersionList<Edge>;
|
public:
|
||||||
//
|
EdgeRecord(Id id, VertexRecord *from, VertexRecord *to)
|
||||||
// VertexRecord* get_key(){
|
: from_v(from), to_v(to), VersionList(id)
|
||||||
// //TODO
|
{
|
||||||
// }
|
}
|
||||||
// };
|
EdgeRecord(const VersionList &) = delete;
|
||||||
|
|
||||||
|
/* @brief Move constructs the version list
|
||||||
|
* Note: use only at the beginning of the "other's" lifecycle since this
|
||||||
|
* constructor doesn't move the RecordLock, but only the head pointer
|
||||||
|
*/
|
||||||
|
EdgeRecord(EdgeRecord &&other)
|
||||||
|
: from_v(other.from_v), to_v(other.to_v), VersionList(std::move(other))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexRecord *&get_key() { return from_v; }
|
||||||
|
|
||||||
|
auto from() const { return this->from_v; }
|
||||||
|
|
||||||
|
auto to() const { return this->to_v; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VertexRecord *from_v;
|
||||||
|
VertexRecord *to_v;
|
||||||
|
};
|
||||||
|
@ -24,6 +24,8 @@ public:
|
|||||||
throw std::bad_function_call::bad_function_call();
|
throw std::bad_function_call::bad_function_call();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool contains(VertexRecord *vr) { return edges.contains(vr); }
|
||||||
|
|
||||||
void clear() { edges.clear(); }
|
void clear() { edges.clear(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include <chrono>
|
||||||
|
#include <ctime>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@ -20,10 +22,15 @@ public:
|
|||||||
double cost;
|
double cost;
|
||||||
int depth = {0};
|
int depth = {0};
|
||||||
Vertex *vertex;
|
Vertex *vertex;
|
||||||
|
VertexRecord *record;
|
||||||
|
|
||||||
Node(Vertex *va, double cost) : cost(cost), vertex(va) {}
|
Node(Vertex *va, VertexRecord *record, double cost)
|
||||||
Node(Vertex *va, double cost, Node *parent)
|
: cost(cost), vertex(va), record(record)
|
||||||
: cost(cost), vertex(va), parent(parent), depth(parent->depth + 1)
|
{
|
||||||
|
}
|
||||||
|
Node(Vertex *va, VertexRecord *record, double cost, Node *parent)
|
||||||
|
: cost(cost), vertex(va), parent(parent), depth(parent->depth + 1),
|
||||||
|
record(record)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -82,10 +89,10 @@ double calc_heuristic_cost_dummy(Edge *edge, Vertex *vertex)
|
|||||||
return 1 - vertex->data.props.at("score").as<Double>().value;
|
return 1 - vertex->data.props.at("score").as<Double>().value;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef bool (*EdgeFilter)(tx::Transaction &t, Edge *, Node *before);
|
typedef bool (*EdgeFilter)(tx::Transaction &t, EdgeRecord *, Node *before);
|
||||||
typedef bool (*VertexFilter)(tx::Transaction &t, Vertex *, Node *before);
|
typedef bool (*VertexFilter)(tx::Transaction &t, Vertex *, Node *before);
|
||||||
|
|
||||||
bool edge_filter_dummy(tx::Transaction &t, Edge *e, Node *before)
|
bool edge_filter_dummy(tx::Transaction &t, EdgeRecord *e, Node *before)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -104,9 +111,8 @@ bool vertex_filter_contained_dummy(tx::Transaction &t, Vertex *v, Node *before)
|
|||||||
if (before == nullptr) {
|
if (before == nullptr) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (auto e : before->vertex->data.out) {
|
for (auto edge : before->vertex->data.out) {
|
||||||
Edge *edge = e->find(t);
|
Vertex *e_v = edge->to()->find(t);
|
||||||
Vertex *e_v = edge->data.to->find(t);
|
|
||||||
if (e_v == v) {
|
if (e_v == v) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@ -116,6 +122,19 @@ bool vertex_filter_contained_dummy(tx::Transaction &t, Vertex *v, Node *before)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vertex_filter_contained(tx::Transaction &t, Vertex *v, Node *before)
|
||||||
|
{
|
||||||
|
bool found;
|
||||||
|
do {
|
||||||
|
found = false;
|
||||||
|
before = before->parent;
|
||||||
|
if (before == nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} while (v->data.in.contains(before->record));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Vertex filter ima max_depth funkcija te edge filter ima max_depth funkcija.
|
// Vertex filter ima max_depth funkcija te edge filter ima max_depth funkcija.
|
||||||
// Jedan za svaku dubinu.
|
// Jedan za svaku dubinu.
|
||||||
// Filtri vracaju true ako element zadovoljava uvjete.
|
// Filtri vracaju true ako element zadovoljava uvjete.
|
||||||
@ -129,8 +148,8 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
|
|||||||
auto cmp = [](Node *left, Node *right) { return left->cost > right->cost; };
|
auto cmp = [](Node *left, Node *right) { return left->cost > right->cost; };
|
||||||
std::priority_queue<Node *, std::vector<Node *>, decltype(cmp)> queue(cmp);
|
std::priority_queue<Node *, std::vector<Node *>, decltype(cmp)> queue(cmp);
|
||||||
|
|
||||||
Node *start =
|
auto start_vr = db.graph.vertices.find(t, sys_id_start).vlist;
|
||||||
new Node(db.graph.vertices.find(t, sys_id_start).vlist->find(t), 0);
|
Node *start = new Node(start_vr->find(t), start_vr, 0);
|
||||||
queue.push(start);
|
queue.push(start);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
do {
|
do {
|
||||||
@ -145,13 +164,13 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto e : now->vertex->data.out) {
|
for (auto edge : now->vertex->data.out) {
|
||||||
Edge *edge = e->find(t);
|
|
||||||
if (e_filter[now->depth](t, edge, now)) {
|
if (e_filter[now->depth](t, edge, now)) {
|
||||||
Vertex *v = edge->data.to->find(t);
|
Vertex *v = edge->to()->find(t);
|
||||||
if (v_filter[now->depth](t, v, now)) {
|
if (v_filter[now->depth](t, v, now)) {
|
||||||
Node *n = new Node(
|
Node *n = new Node(
|
||||||
v, now->cost + calc_heuristic_cost(edge, v), now);
|
v, edge->to(),
|
||||||
|
now->cost + calc_heuristic_cost(edge->find(t), v), now);
|
||||||
queue.push(n);
|
queue.push(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,9 +191,14 @@ int main()
|
|||||||
//
|
//
|
||||||
EdgeFilter e_filters[] = {&edge_filter_dummy, &edge_filter_dummy,
|
EdgeFilter e_filters[] = {&edge_filter_dummy, &edge_filter_dummy,
|
||||||
&edge_filter_dummy, &edge_filter_dummy};
|
&edge_filter_dummy, &edge_filter_dummy};
|
||||||
VertexFilter f_filters[] = {&vertex_filter_dummy, &vertex_filter_dummy,
|
VertexFilter f_filters[] = {
|
||||||
&vertex_filter_dummy, &vertex_filter_dummy};
|
&vertex_filter_contained, &vertex_filter_contained,
|
||||||
|
&vertex_filter_contained, &vertex_filter_contained};
|
||||||
|
auto begin = clock();
|
||||||
a_star(db, 0, 3, e_filters, f_filters, &calc_heuristic_cost_dummy, 10);
|
a_star(db, 0, 3, e_filters, f_filters, &calc_heuristic_cost_dummy, 10);
|
||||||
|
clock_t end = clock();
|
||||||
|
double elapsed_ms = (double(end - begin) / CLOCKS_PER_SEC) * 1000;
|
||||||
|
std::cout << "A-star: " << elapsed_ms << " [ms]\n";
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -254,14 +278,11 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
|
|||||||
|
|
||||||
auto v2 = va[to - start_vertex_id];
|
auto v2 = va[to - start_vertex_id];
|
||||||
|
|
||||||
auto edge_accessor = db.graph.edges.insert(t);
|
auto edge_accessor = db.graph.edges.insert(t, v1.vlist, v2.vlist);
|
||||||
|
|
||||||
v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
|
v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
|
||||||
v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
|
v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
|
||||||
|
|
||||||
edge_accessor.from(v1.vlist);
|
|
||||||
edge_accessor.to(v2.vlist);
|
|
||||||
|
|
||||||
auto &edge_type = db.graph.edge_type_store.find_or_create(type);
|
auto &edge_type = db.graph.edge_type_store.find_or_create(type);
|
||||||
edge_accessor.edge_type(edge_type);
|
edge_accessor.edge_type(edge_type);
|
||||||
};
|
};
|
||||||
@ -299,14 +320,10 @@ void load_graph_dummy(Db &db)
|
|||||||
|
|
||||||
auto v2 = db.graph.vertices.find(t, va[to]);
|
auto v2 = db.graph.vertices.find(t, va[to]);
|
||||||
|
|
||||||
auto edge_accessor = db.graph.edges.insert(t);
|
auto edge_accessor = db.graph.edges.insert(t, v1.vlist, v2.vlist);
|
||||||
|
|
||||||
v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
|
v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
|
||||||
v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
|
v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
|
||||||
|
|
||||||
edge_accessor.from(v1.vlist);
|
|
||||||
edge_accessor.to(v2.vlist);
|
|
||||||
|
|
||||||
auto &edge_type = db.graph.edge_type_store.find_or_create(type);
|
auto &edge_type = db.graph.edge_type_store.find_or_create(type);
|
||||||
edge_accessor.edge_type(edge_type);
|
edge_accessor.edge_type(edge_type);
|
||||||
};
|
};
|
||||||
|
@ -130,6 +130,22 @@ public:
|
|||||||
|
|
||||||
RhHashMap() {}
|
RhHashMap() {}
|
||||||
|
|
||||||
|
RhHashMap(const RhHashMap &other)
|
||||||
|
{
|
||||||
|
capacity = other.capacity;
|
||||||
|
count = other.count;
|
||||||
|
if (capacity > 0) {
|
||||||
|
size_t bytes = sizeof(Combined) * capacity;
|
||||||
|
array = (Combined *)malloc(bytes);
|
||||||
|
memcpy(array, other.array, bytes);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
array = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~RhHashMap() { this->clear(); }
|
||||||
|
|
||||||
Iterator begin() { return Iterator(this); }
|
Iterator begin() { return Iterator(this); }
|
||||||
|
|
||||||
ConstIterator begin() const { return ConstIterator(this); }
|
ConstIterator begin() const { return ConstIterator(this); }
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "utils/crtp.hpp"
|
#include "utils/crtp.hpp"
|
||||||
#include "utils/option_ptr.hpp"
|
#include "utils/option_ptr.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
// HashMultiMap with RobinHood collision resolution policy.
|
// HashMultiMap with RobinHood collision resolution policy.
|
||||||
// Single threaded.
|
// Single threaded.
|
||||||
@ -165,16 +166,18 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RhHashMultiMap(RhHashMultiMap &&other)
|
// RhHashMultiMap(RhHashMultiMap &&other)
|
||||||
{
|
// {
|
||||||
capacity = other.capacity;
|
// capacity = other.capacity;
|
||||||
count = other.count;
|
// count = other.count;
|
||||||
array = other.array;
|
// array = other.array;
|
||||||
|
//
|
||||||
|
// other.array = nullptr;
|
||||||
|
// other.capacity = 0;
|
||||||
|
// other.count = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
other.array = nullptr;
|
~RhHashMultiMap() { this->clear(); }
|
||||||
other.capacity = 0;
|
|
||||||
other.count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator begin() { return Iterator(this); }
|
Iterator begin() { return Iterator(this); }
|
||||||
|
|
||||||
@ -192,7 +195,7 @@ public:
|
|||||||
{
|
{
|
||||||
size_t bytes = sizeof(Combined) * size;
|
size_t bytes = sizeof(Combined) * size;
|
||||||
array = (Combined *)malloc(bytes);
|
array = (Combined *)malloc(bytes);
|
||||||
memset(array, 0, bytes);
|
std::memset(array, 0, bytes);
|
||||||
capacity = size;
|
capacity = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +222,8 @@ public:
|
|||||||
free(a);
|
free(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool contains(const K &key) { return find(key) != end(); }
|
||||||
|
|
||||||
Iterator find(const K &key)
|
Iterator find(const K &key)
|
||||||
{
|
{
|
||||||
size_t mask = this->mask();
|
size_t mask = this->mask();
|
||||||
@ -227,7 +232,7 @@ public:
|
|||||||
|
|
||||||
bool bef_init = false;
|
bool bef_init = false;
|
||||||
size_t before_off;
|
size_t before_off;
|
||||||
K before_key = key;
|
auto before_key = key;
|
||||||
|
|
||||||
size_t border = 8 <= capacity ? 8 : capacity;
|
size_t border = 8 <= capacity ? 8 : capacity;
|
||||||
while (off < border) {
|
while (off < border) {
|
||||||
@ -270,7 +275,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inserts element with the given key.
|
// Inserts element with the given key.
|
||||||
void add(K key, D *data)
|
void add(K &key, D *data)
|
||||||
{
|
{
|
||||||
assert(key == data->get_key());
|
assert(key == data->get_key());
|
||||||
|
|
||||||
@ -280,7 +285,7 @@ public:
|
|||||||
|
|
||||||
bool bef_init = false;
|
bool bef_init = false;
|
||||||
size_t before_off;
|
size_t before_off;
|
||||||
K before_key = key;
|
auto before_key = key;
|
||||||
|
|
||||||
size_t border = 8 <= capacity ? 8 : capacity;
|
size_t border = 8 <= capacity ? 8 : capacity;
|
||||||
while (off < border) {
|
while (off < border) {
|
||||||
|
@ -172,4 +172,4 @@ class Vertex;
|
|||||||
class Edge;
|
class Edge;
|
||||||
|
|
||||||
using VertexRecord = mvcc::VersionList<Vertex>;
|
using VertexRecord = mvcc::VersionList<Vertex>;
|
||||||
using EdgeRecord = mvcc::VersionList<Edge>;
|
// using EdgeRecord = mvcc::VersionList<Edge>;
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
#include "database/db.hpp"
|
#include "database/db.hpp"
|
||||||
#include "query_engine/query_stripper.hpp"
|
#include "query_engine/query_stripper.hpp"
|
||||||
|
#include "query_engine/util.hpp"
|
||||||
#include "storage/model/properties/property.hpp"
|
#include "storage/model/properties/property.hpp"
|
||||||
#include "utils/command_line/arguments.hpp"
|
#include "utils/command_line/arguments.hpp"
|
||||||
#include "query_engine/util.hpp"
|
|
||||||
|
|
||||||
auto load_queries(Db& db)
|
auto load_queries(Db &db)
|
||||||
{
|
{
|
||||||
std::map<uint64_t, std::function<bool(const properties_t &)>> queries;
|
std::map<uint64_t, std::function<bool(const properties_t &)>> queries;
|
||||||
|
|
||||||
@ -72,14 +72,11 @@ auto load_queries(Db& db)
|
|||||||
auto v2 = db.graph.vertices.find(t, args[1]->as<Int32>().value);
|
auto v2 = db.graph.vertices.find(t, args[1]->as<Int32>().value);
|
||||||
if (!v2) return t.commit(), false;
|
if (!v2) return t.commit(), false;
|
||||||
|
|
||||||
auto edge_accessor = db.graph.edges.insert(t);
|
auto edge_accessor = db.graph.edges.insert(t, v1.vlist, v2.vlist);
|
||||||
|
|
||||||
v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
|
v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
|
||||||
v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
|
v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
|
||||||
|
|
||||||
edge_accessor.from(v1.vlist);
|
|
||||||
edge_accessor.to(v2.vlist);
|
|
||||||
|
|
||||||
auto &edge_type = db.graph.edge_type_store.find_or_create("IS");
|
auto &edge_type = db.graph.edge_type_store.find_or_create("IS");
|
||||||
edge_accessor.edge_type(edge_type);
|
edge_accessor.edge_type(edge_type);
|
||||||
|
|
||||||
@ -127,31 +124,28 @@ auto load_queries(Db& db)
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// MATCH (n1), (n2) WHERE ID(n1)=0 AND ID(n2)=1 CREATE (n1)<-[r:IS {age: 25, weight: 70}]-(n2) RETURN r
|
// MATCH (n1), (n2) WHERE ID(n1)=0 AND ID(n2)=1 CREATE (n1)<-[r:IS {age: 25,
|
||||||
auto create_edge_v2 = [&db](const properties_t &args)
|
// weight: 70}]-(n2) RETURN r
|
||||||
{
|
auto create_edge_v2 = [&db](const properties_t &args) {
|
||||||
auto& t = db.tx_engine.begin();
|
auto &t = db.tx_engine.begin();
|
||||||
auto n1 = db.graph.vertices.find(t, args[0]->as<Int64>().value);
|
auto n1 = db.graph.vertices.find(t, args[0]->as<Int64>().value);
|
||||||
if (!n1) return t.commit(), false;
|
if (!n1) return t.commit(), false;
|
||||||
auto n2 = db.graph.vertices.find(t, args[1]->as<Int64>().value);
|
auto n2 = db.graph.vertices.find(t, args[1]->as<Int64>().value);
|
||||||
if (!n2) return t.commit(), false;
|
if (!n2) return t.commit(), false;
|
||||||
auto r = db.graph.edges.insert(t);
|
auto r = db.graph.edges.insert(t, n2.vlist, n1.vlist);
|
||||||
r.property("age", args[2]);
|
r.property("age", args[2]);
|
||||||
r.property("weight", args[3]);
|
r.property("weight", args[3]);
|
||||||
auto &IS = db.graph.edge_type_store.find_or_create("IS");
|
auto &IS = db.graph.edge_type_store.find_or_create("IS");
|
||||||
r.edge_type(IS);
|
r.edge_type(IS);
|
||||||
n2.vlist->update(t)->data.out.add(r.vlist);
|
n2.vlist->update(t)->data.out.add(r.vlist);
|
||||||
n1.vlist->update(t)->data.in.add(r.vlist);
|
n1.vlist->update(t)->data.in.add(r.vlist);
|
||||||
r.from(n2.vlist);
|
|
||||||
r.to(n1.vlist);
|
|
||||||
t.commit();
|
t.commit();
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
queries[15648836733456301916u] = create_edge_v2;
|
queries[15648836733456301916u] = create_edge_v2;
|
||||||
|
|
||||||
// MATCH (n) RETURN n
|
// MATCH (n) RETURN n
|
||||||
auto match_all_nodes = [&db](const properties_t &args)
|
auto match_all_nodes = [&db](const properties_t &args) {
|
||||||
{
|
|
||||||
auto &t = db.tx_engine.begin();
|
auto &t = db.tx_engine.begin();
|
||||||
|
|
||||||
auto vertices_accessor = db.graph.vertices.access();
|
auto vertices_accessor = db.graph.vertices.access();
|
||||||
@ -171,8 +165,7 @@ auto load_queries(Db& db)
|
|||||||
queries[15284086425088081497u] = match_all_nodes;
|
queries[15284086425088081497u] = match_all_nodes;
|
||||||
|
|
||||||
// MATCH (n:LABEL) RETURN n
|
// MATCH (n:LABEL) RETURN n
|
||||||
auto find_by_label = [&db](const properties_t &args)
|
auto find_by_label = [&db](const properties_t &args) {
|
||||||
{
|
|
||||||
auto &t = db.tx_engine.begin();
|
auto &t = db.tx_engine.begin();
|
||||||
|
|
||||||
auto &label = db.graph.label_store.find_or_create("LABEL");
|
auto &label = db.graph.label_store.find_or_create("LABEL");
|
||||||
@ -181,7 +174,7 @@ auto load_queries(Db& db)
|
|||||||
db.graph.vertices.find_label_index(label);
|
db.graph.vertices.find_label_index(label);
|
||||||
auto accessor = index_record_collection.access();
|
auto accessor = index_record_collection.access();
|
||||||
cout << "VERTICES" << endl;
|
cout << "VERTICES" << endl;
|
||||||
for (auto& v : accessor) {
|
for (auto &v : accessor) {
|
||||||
cout << v.record->data.props.at("name").as<String>().value << endl;
|
cout << v.record->data.props.at("name").as<String>().value << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "mvcc/edge_record.hpp"
|
||||||
#include "storage/edge.hpp"
|
#include "storage/edge.hpp"
|
||||||
#include "storage/record_accessor.hpp"
|
#include "storage/record_accessor.hpp"
|
||||||
#include "utils/assert.hpp"
|
#include "utils/assert.hpp"
|
||||||
@ -8,7 +9,8 @@
|
|||||||
class Edges;
|
class Edges;
|
||||||
|
|
||||||
// TODO: Edge, Db, Edge::Accessor
|
// TODO: Edge, Db, Edge::Accessor
|
||||||
class Edge::Accessor : public RecordAccessor<Edge, Edges, Edge::Accessor>
|
class Edge::Accessor
|
||||||
|
: public RecordAccessor<Edge, Edges, Edge::Accessor, EdgeRecord>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using RecordAccessor::RecordAccessor;
|
using RecordAccessor::RecordAccessor;
|
||||||
@ -26,17 +28,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: VertexAccessor
|
// TODO: VertexAccessor
|
||||||
void from(VertexRecord *vertex_record)
|
// void from(VertexRecord *vertex_record)
|
||||||
{
|
// {
|
||||||
this->record->data.from = vertex_record;
|
// this->record->data.from = vertex_record;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// void to(VertexRecord *vertex_record)
|
||||||
|
// {
|
||||||
|
// this->record->data.to = vertex_record;
|
||||||
|
// }
|
||||||
|
|
||||||
void to(VertexRecord *vertex_record)
|
auto from() const { return this->vlist->from(); }
|
||||||
{
|
|
||||||
this->record->data.to = vertex_record;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto from() const { return this->record->data.from; }
|
auto to() const { return this->vlist->to(); }
|
||||||
|
|
||||||
auto to() const { return this->record->data.to; }
|
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
class Edges
|
class Edges
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Edge::Accessor find(tx::Transaction &t, const Id &id)
|
Edge::Accessor find(tx::Transaction &t, const Id &id)
|
||||||
{
|
{
|
||||||
auto edges_accessor = edges.access();
|
auto edges_accessor = edges.access();
|
||||||
@ -22,13 +22,14 @@ class Edges
|
|||||||
return Edge::Accessor(edge, &edges_iterator->second, this);
|
return Edge::Accessor(edge, &edges_iterator->second, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Edge::Accessor insert(tx::Transaction &t)
|
Edge::Accessor insert(tx::Transaction &t, VertexRecord *from,
|
||||||
|
VertexRecord *to)
|
||||||
{
|
{
|
||||||
// get next vertex id
|
// get next vertex id
|
||||||
auto next = counter.next(std::memory_order_acquire);
|
auto next = counter.next(std::memory_order_acquire);
|
||||||
|
|
||||||
// create new vertex record
|
// create new vertex record
|
||||||
EdgeRecord edge_record(next);
|
EdgeRecord edge_record(next, from, to);
|
||||||
|
|
||||||
// insert the new vertex record into the vertex store
|
// insert the new vertex record into the vertex store
|
||||||
auto edges_accessor = edges.access();
|
auto edges_accessor = edges.access();
|
||||||
@ -41,7 +42,7 @@ class Edges
|
|||||||
return Edge::Accessor(edge, &inserted_edge_record->second, this);
|
return Edge::Accessor(edge, &inserted_edge_record->second, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConcurrentMap<uint64_t, EdgeRecord> edges;
|
ConcurrentMap<uint64_t, EdgeRecord> edges;
|
||||||
AtomicCounter<uint64_t> counter;
|
AtomicCounter<uint64_t> counter;
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include "mvcc/edge_record.hpp"
|
||||||
#include "mvcc/version_list.hpp"
|
#include "mvcc/version_list.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class EdgeList
|
class EdgeList
|
||||||
{
|
{
|
||||||
@ -14,26 +15,17 @@ public:
|
|||||||
auto end() const { return edges.end(); }
|
auto end() const { return edges.end(); }
|
||||||
auto cend() const { return edges.end(); }
|
auto cend() const { return edges.end(); }
|
||||||
|
|
||||||
void add(EdgeRecord* edge)
|
void add(EdgeRecord *edge) { edges.push_back(edge); }
|
||||||
{
|
|
||||||
edges.push_back(edge);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t degree() const
|
size_t degree() const { return edges.size(); }
|
||||||
{
|
|
||||||
return edges.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove(EdgeRecord* edge)
|
void remove(EdgeRecord *edge)
|
||||||
{
|
{
|
||||||
edges.erase(std::remove(edges.begin(), edges.end(), edge), edges.end());
|
edges.erase(std::remove(edges.begin(), edges.end(), edge), edges.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear() { edges.clear(); }
|
||||||
{
|
|
||||||
edges.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<EdgeRecord*> edges;
|
std::vector<EdgeRecord *> edges;
|
||||||
};
|
};
|
||||||
|
@ -7,11 +7,8 @@
|
|||||||
class EdgeModel : public PropertyModel
|
class EdgeModel : public PropertyModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VertexRecord *from;
|
|
||||||
VertexRecord *to;
|
|
||||||
|
|
||||||
// TODO: here should be the reference
|
// TODO: here should be the reference
|
||||||
// but something that is copyable
|
// but something that is copyable
|
||||||
// because this model is copied all the time (mvcc)
|
// because this model is copied all the time (mvcc)
|
||||||
const EdgeType *edge_type {nullptr};
|
const EdgeType *edge_type{nullptr};
|
||||||
};
|
};
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
#include "edge_list.hpp"
|
#include "edge_list.hpp"
|
||||||
#include "property_model.hpp"
|
#include "property_model.hpp"
|
||||||
#include "storage/label/label_collection.hpp"
|
#include "storage/label/label_collection.hpp"
|
||||||
// #include "storage/model/edge_map.hpp"
|
#include "storage/model/edge_map.hpp"
|
||||||
|
|
||||||
class VertexModel : public PropertyModel
|
class VertexModel : public PropertyModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EdgeList out;
|
EdgeList out;
|
||||||
EdgeList in;
|
EdgeMap in;
|
||||||
LabelCollection labels;
|
LabelCollection labels;
|
||||||
};
|
};
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "transactions/transaction.hpp"
|
|
||||||
#include "mvcc/version_list.hpp"
|
#include "mvcc/version_list.hpp"
|
||||||
#include "storage/model/properties/property.hpp"
|
|
||||||
#include "storage/model/properties/properties.hpp"
|
#include "storage/model/properties/properties.hpp"
|
||||||
|
#include "storage/model/properties/property.hpp"
|
||||||
|
#include "transactions/transaction.hpp"
|
||||||
|
|
||||||
template <class T, class Store, class Derived>
|
template <class T, class Store, class Derived,
|
||||||
|
class vlist_t = mvcc::VersionList<T>>
|
||||||
class RecordAccessor
|
class RecordAccessor
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
using vlist_t = mvcc::VersionList<T>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RecordAccessor() = default;
|
RecordAccessor() = default;
|
||||||
|
|
||||||
RecordAccessor(T* record, vlist_t* vlist, Store* store)
|
RecordAccessor(T *record, vlist_t *vlist, Store *store)
|
||||||
: record(record), vlist(vlist), store(store)
|
: record(record), vlist(vlist), store(store)
|
||||||
{
|
{
|
||||||
assert(record != nullptr);
|
assert(record != nullptr);
|
||||||
@ -22,59 +20,50 @@ public:
|
|||||||
assert(store != nullptr);
|
assert(store != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const
|
bool empty() const { return record == nullptr; }
|
||||||
{
|
|
||||||
return record == nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Id& id() const
|
const Id &id() const
|
||||||
{
|
{
|
||||||
assert(!empty());
|
assert(!empty());
|
||||||
return vlist->id;
|
return vlist->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
Derived update(tx::Transaction& t) const
|
Derived update(tx::Transaction &t) const
|
||||||
{
|
{
|
||||||
assert(!empty());
|
assert(!empty());
|
||||||
|
|
||||||
return Derived(vlist->update(t), vlist, store);
|
return Derived(vlist->update(t), vlist, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool remove(tx::Transaction& t) const
|
bool remove(tx::Transaction &t) const
|
||||||
{
|
{
|
||||||
assert(!empty());
|
assert(!empty());
|
||||||
|
|
||||||
return vlist->remove(record, t);
|
return vlist->remove(record, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Property& property(const std::string& key) const
|
const Property &property(const std::string &key) const
|
||||||
{
|
{
|
||||||
return record->data.props.at(key);
|
return record->data.props.at(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class V, class... Args>
|
template <class V, class... Args>
|
||||||
void property(const std::string& key, Args&&... args)
|
void property(const std::string &key, Args &&... args)
|
||||||
{
|
{
|
||||||
record->data.props.template set<V>(key, std::forward<Args>(args)...);
|
record->data.props.template set<V>(key, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
void property(const std::string& key, Property::sptr value)
|
void property(const std::string &key, Property::sptr value)
|
||||||
{
|
{
|
||||||
record->data.props.set(key, std::move(value));
|
record->data.props.set(key, std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties& properties() const
|
Properties &properties() const { return record->data.props; }
|
||||||
{
|
|
||||||
return record->data.props;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit operator bool() const
|
explicit operator bool() const { return record != nullptr; }
|
||||||
{
|
|
||||||
return record != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// protected:
|
// protected:
|
||||||
T* const record {nullptr};
|
T *const record{nullptr};
|
||||||
vlist_t* const vlist {nullptr};
|
vlist_t *const vlist{nullptr};
|
||||||
Store* const store {nullptr};
|
Store *const store{nullptr};
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user