2017-02-04 16:01:15 +08:00
|
|
|
//
|
|
|
|
// Copyright 2017 Memgraph
|
|
|
|
// Created by Florijan Stamenkovic on 03.02.17.
|
|
|
|
//
|
|
|
|
|
2017-02-11 14:51:02 +08:00
|
|
|
#pragma once
|
2017-02-04 16:01:15 +08:00
|
|
|
|
2017-07-05 22:00:07 +08:00
|
|
|
#include <experimental/optional>
|
|
|
|
|
2017-03-03 20:59:38 +08:00
|
|
|
#include "cppitertools/filter.hpp"
|
2017-03-06 21:17:55 +08:00
|
|
|
#include "cppitertools/imap.hpp"
|
2017-03-03 20:59:38 +08:00
|
|
|
|
2017-02-04 16:01:15 +08:00
|
|
|
#include "graph_db.hpp"
|
2017-03-03 20:59:38 +08:00
|
|
|
#include "storage/edge_accessor.hpp"
|
2017-03-06 21:17:55 +08:00
|
|
|
#include "storage/vertex_accessor.hpp"
|
2017-07-05 22:00:07 +08:00
|
|
|
#include "transactions/transaction.hpp"
|
|
|
|
#include "utils/bound.hpp"
|
2017-03-03 20:59:38 +08:00
|
|
|
|
2017-07-03 16:38:58 +08:00
|
|
|
/** Thrown when creating an index which already exists. */
|
|
|
|
class IndexExistsException : public utils::BasicException {
|
|
|
|
using utils::BasicException::BasicException;
|
|
|
|
};
|
|
|
|
|
2017-02-16 22:47:55 +08:00
|
|
|
/**
|
|
|
|
* An accessor for the database object: exposes functions
|
|
|
|
* for operating on the database. All the functions in
|
|
|
|
* this class should be self-sufficient: for example the
|
|
|
|
* function for creating
|
|
|
|
* a new Vertex should take care of all the book-keeping around
|
|
|
|
* the creation.
|
|
|
|
*/
|
2017-03-06 21:17:55 +08:00
|
|
|
|
2017-02-04 16:01:15 +08:00
|
|
|
class GraphDbAccessor {
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
// We need to make friends with this guys since they need to access private
|
|
|
|
// methods for updating indices.
|
|
|
|
friend class RecordAccessor<Vertex>;
|
|
|
|
friend class RecordAccessor<Edge>;
|
|
|
|
friend class VertexAccessor;
|
|
|
|
friend class EdgeAccessor;
|
|
|
|
|
2017-02-18 18:54:37 +08:00
|
|
|
public:
|
2017-02-15 21:10:16 +08:00
|
|
|
/**
|
|
|
|
* Creates an accessor for the given database.
|
|
|
|
*
|
|
|
|
* @param db The database
|
|
|
|
*/
|
2017-04-03 17:26:32 +08:00
|
|
|
GraphDbAccessor(GraphDb &db);
|
2017-03-06 21:17:55 +08:00
|
|
|
~GraphDbAccessor();
|
2017-02-15 21:10:16 +08:00
|
|
|
|
2017-03-14 20:26:48 +08:00
|
|
|
// the GraphDbAccessor can NOT be copied nor moved because
|
|
|
|
// 1. it ensures transaction cleanup once it's destructed
|
|
|
|
// 2. it will contain index and side-effect bookkeeping data
|
|
|
|
// which is unique to the transaction (shared_ptr works but slower)
|
|
|
|
GraphDbAccessor(const GraphDbAccessor &other) = delete;
|
|
|
|
GraphDbAccessor(GraphDbAccessor &&other) = delete;
|
|
|
|
GraphDbAccessor &operator=(const GraphDbAccessor &other) = delete;
|
|
|
|
GraphDbAccessor &operator=(GraphDbAccessor &&other) = delete;
|
|
|
|
|
2017-02-15 21:10:16 +08:00
|
|
|
/**
|
|
|
|
* Returns the name of the database of this accessor.
|
|
|
|
*/
|
2017-04-03 17:26:32 +08:00
|
|
|
const std::string &name() const;
|
2017-02-15 21:10:16 +08:00
|
|
|
|
2017-02-06 19:40:55 +08:00
|
|
|
/**
|
|
|
|
* Creates a new Vertex and returns an accessor to it.
|
|
|
|
*
|
|
|
|
* @return See above.
|
|
|
|
*/
|
|
|
|
VertexAccessor insert_vertex();
|
|
|
|
|
2017-02-15 21:10:16 +08:00
|
|
|
/**
|
|
|
|
* Removes the vertex of the given accessor. If the vertex has any outgoing
|
|
|
|
* or incoming edges, it is not deleted. See `detach_remove_vertex` if you
|
|
|
|
* want to remove a vertex regardless of connectivity.
|
|
|
|
*
|
2017-04-14 21:03:18 +08:00
|
|
|
* If the vertex has already been deleted by the current transaction+command,
|
|
|
|
* this function will not do anything and will return true.
|
|
|
|
*
|
2017-02-15 21:10:16 +08:00
|
|
|
* @param vertex_accessor Accessor to vertex.
|
|
|
|
* @return If or not the vertex was deleted.
|
|
|
|
*/
|
2017-04-03 17:26:32 +08:00
|
|
|
bool remove_vertex(VertexAccessor &vertex_accessor);
|
2017-02-15 21:10:16 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes the vertex of the given accessor along with all it's outgoing
|
|
|
|
* and incoming connections.
|
|
|
|
*
|
|
|
|
* @param vertex_accessor Accessor to a vertex.
|
|
|
|
*/
|
2017-04-03 17:26:32 +08:00
|
|
|
void detach_remove_vertex(VertexAccessor &vertex_accessor);
|
2017-02-15 21:10:16 +08:00
|
|
|
|
2017-02-16 22:47:55 +08:00
|
|
|
/**
|
2017-03-03 20:59:38 +08:00
|
|
|
* Returns iterable over accessors to all the vertices in the graph
|
|
|
|
* visible to the current transaction.
|
2017-04-21 21:39:41 +08:00
|
|
|
*
|
|
|
|
* @param current_state If true then the graph state for the
|
|
|
|
* current transaction+command is returned (insertions, updates and
|
|
|
|
* deletions performed in the current transaction+command are not
|
|
|
|
* ignored).
|
2017-02-16 22:47:55 +08:00
|
|
|
*/
|
2017-06-07 15:49:51 +08:00
|
|
|
auto vertices(bool current_state) {
|
2017-04-03 17:12:15 +08:00
|
|
|
// wrap version lists into accessors, which will look for visible versions
|
|
|
|
auto accessors =
|
|
|
|
iter::imap([this](auto vlist) { return VertexAccessor(*vlist, *this); },
|
|
|
|
db_.vertices_.access());
|
2017-03-03 20:59:38 +08:00
|
|
|
|
2017-04-03 17:12:15 +08:00
|
|
|
// filter out the accessors not visible to the current transaction
|
|
|
|
return iter::filter(
|
2017-04-21 21:39:41 +08:00
|
|
|
[this, current_state](const VertexAccessor &accessor) {
|
|
|
|
return (accessor.old_ &&
|
|
|
|
!(current_state &&
|
|
|
|
accessor.old_->is_deleted_by(*transaction_))) ||
|
|
|
|
(current_state && accessor.new_ &&
|
|
|
|
!accessor.new_->is_deleted_by(*transaction_));
|
2017-04-03 17:12:15 +08:00
|
|
|
},
|
|
|
|
std::move(accessors));
|
2017-03-03 20:59:38 +08:00
|
|
|
}
|
2017-02-16 22:47:55 +08:00
|
|
|
|
2017-04-05 23:23:00 +08:00
|
|
|
/**
|
|
|
|
* Return VertexAccessors which contain the current label for the current
|
|
|
|
* transaction visibilty.
|
|
|
|
* @param label - label for which to return VertexAccessors
|
2017-04-21 21:39:41 +08:00
|
|
|
* @param current_state If true then the graph state for the
|
|
|
|
* current transaction+command is returned (insertions, updates and
|
|
|
|
* deletions performed in the current transaction+command are not
|
|
|
|
* ignored).
|
2017-04-05 23:23:00 +08:00
|
|
|
* @return iterable collection
|
|
|
|
*/
|
2017-06-07 15:49:51 +08:00
|
|
|
auto vertices(const GraphDbTypes::Label &label, bool current_state) {
|
2017-04-05 23:23:00 +08:00
|
|
|
return iter::imap(
|
2017-04-21 21:39:41 +08:00
|
|
|
[this, current_state](auto vlist) {
|
|
|
|
return VertexAccessor(*vlist, *this);
|
|
|
|
},
|
|
|
|
db_.labels_index_.GetVlists(label, *transaction_, current_state));
|
2017-04-05 23:23:00 +08:00
|
|
|
}
|
|
|
|
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
/**
|
|
|
|
* Return VertexAccessors which contain the current label and property for the
|
|
|
|
* given transaction visibility.
|
|
|
|
* @param label - label for which to return VertexAccessors
|
|
|
|
* @param property - property for which to return VertexAccessors
|
|
|
|
* @param current_state If true then the graph state for the
|
|
|
|
* current transaction+command is returned (insertions, updates and
|
|
|
|
* deletions performed in the current transaction+command are not
|
|
|
|
* ignored).
|
|
|
|
* @return iterable collection
|
|
|
|
*/
|
|
|
|
auto vertices(const GraphDbTypes::Label &label,
|
2017-06-07 15:49:51 +08:00
|
|
|
const GraphDbTypes::Property &property, bool current_state) {
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
debug_assert(db_.label_property_index_.IndexExists(
|
|
|
|
LabelPropertyIndex::Key(label, property)),
|
|
|
|
"Label+property index doesn't exist.");
|
|
|
|
return iter::imap([this, current_state](
|
|
|
|
auto vlist) { return VertexAccessor(*vlist, *this); },
|
|
|
|
db_.label_property_index_.GetVlists(
|
|
|
|
LabelPropertyIndex::Key(label, property),
|
|
|
|
*transaction_, current_state));
|
|
|
|
}
|
|
|
|
|
2017-06-07 15:49:51 +08:00
|
|
|
/**
|
|
|
|
* Return VertexAccessors which contain the current label + property, and
|
|
|
|
* those properties are equal to this 'value' for the given transaction
|
|
|
|
* visibility.
|
|
|
|
* @param label - label for which to return VertexAccessors
|
|
|
|
* @param property - property for which to return VertexAccessors
|
|
|
|
* @param value - property value for which to return VertexAccessors
|
|
|
|
* @param current_state If true then the graph state for the
|
|
|
|
* current transaction+command is returned (insertions, updates and
|
|
|
|
* deletions performed in the current transaction+command are not
|
|
|
|
* ignored).
|
|
|
|
* @return iterable collection
|
|
|
|
*/
|
|
|
|
auto vertices(const GraphDbTypes::Label &label,
|
|
|
|
const GraphDbTypes::Property &property,
|
|
|
|
const PropertyValue &value, bool current_state) {
|
|
|
|
debug_assert(db_.label_property_index_.IndexExists(
|
|
|
|
LabelPropertyIndex::Key(label, property)),
|
|
|
|
"Label+property index doesn't exist.");
|
|
|
|
debug_assert(value.type() != PropertyValue::Type::Null,
|
|
|
|
"Can't query index for propery value type null.");
|
|
|
|
return iter::imap([this, current_state](
|
|
|
|
auto vlist) { return VertexAccessor(*vlist, *this); },
|
|
|
|
db_.label_property_index_.GetVlists(
|
|
|
|
LabelPropertyIndex::Key(label, property), value,
|
|
|
|
*transaction_, current_state));
|
|
|
|
}
|
|
|
|
|
2017-07-13 17:24:18 +08:00
|
|
|
/**
|
|
|
|
* Return an iterable over VertexAccessors which contain the
|
|
|
|
* given label and whose property value (for the given property)
|
|
|
|
* falls within the given (lower, upper) @c Bound.
|
|
|
|
*
|
|
|
|
* The returned iterator will only contain
|
|
|
|
* vertices/edges whose property value is comparable with the
|
|
|
|
* given bounds (w.r.t. type). This has implications on Cypher
|
|
|
|
* query execuction semantics which have not been resovled yet.
|
|
|
|
*
|
|
|
|
* At least one of the bounds must be specified. Bonds can't be
|
|
|
|
* @c PropertyValue::Null. If both bounds are
|
|
|
|
* specified, their PropertyValue elments must be of comparable
|
|
|
|
* types.
|
|
|
|
*
|
|
|
|
* @param label - label for which to return VertexAccessors
|
|
|
|
* @param property - property for which to return VertexAccessors
|
|
|
|
* @param lower - Lower bound of the interval.
|
|
|
|
* @param upper - Upper bound of the interval.
|
|
|
|
* @param value - property value for which to return VertexAccessors
|
|
|
|
* @param current_state If true then the graph state for the
|
|
|
|
* current transaction+command is returned (insertions, updates and
|
|
|
|
* deletions performed in the current transaction+command are not
|
|
|
|
* ignored).
|
|
|
|
* @return iterable collection of record accessors
|
|
|
|
* satisfy the bounds and are visible to the current transaction.
|
|
|
|
*/
|
|
|
|
auto vertices(
|
|
|
|
const GraphDbTypes::Label &label, const GraphDbTypes::Property &property,
|
|
|
|
const std::experimental::optional<utils::Bound<PropertyValue>> lower,
|
|
|
|
const std::experimental::optional<utils::Bound<PropertyValue>> upper,
|
|
|
|
bool current_state) {
|
|
|
|
debug_assert(db_.label_property_index_.IndexExists(
|
|
|
|
LabelPropertyIndex::Key(label, property)),
|
|
|
|
"Label+property index doesn't exist.");
|
|
|
|
return iter::imap([this, current_state](
|
|
|
|
auto vlist) { return VertexAccessor(*vlist, *this); },
|
|
|
|
db_.label_property_index_.GetVlists(
|
|
|
|
LabelPropertyIndex::Key(label, property), lower,
|
|
|
|
upper, *transaction_, current_state));
|
|
|
|
}
|
|
|
|
|
2017-02-06 19:40:55 +08:00
|
|
|
/**
|
|
|
|
* Creates a new Edge and returns an accessor to it.
|
|
|
|
*
|
|
|
|
* @param from The 'from' vertex.
|
|
|
|
* @param to The 'to' vertex'
|
|
|
|
* @param type Edge type.
|
|
|
|
* @return An accessor to the edge.
|
|
|
|
*/
|
2017-04-03 17:26:32 +08:00
|
|
|
EdgeAccessor insert_edge(VertexAccessor &from, VertexAccessor &to,
|
2017-03-29 18:37:58 +08:00
|
|
|
GraphDbTypes::EdgeType type);
|
2017-02-06 19:40:55 +08:00
|
|
|
|
2017-02-15 21:10:16 +08:00
|
|
|
/**
|
|
|
|
* Removes an edge from the graph.
|
|
|
|
*
|
|
|
|
* @param edge_accessor The accessor to an edge.
|
|
|
|
*/
|
2017-04-03 17:26:32 +08:00
|
|
|
void remove_edge(EdgeAccessor &edge_accessor);
|
2017-02-15 21:10:16 +08:00
|
|
|
|
2017-02-16 22:47:55 +08:00
|
|
|
/**
|
2017-03-03 20:59:38 +08:00
|
|
|
* Returns iterable over accessors to all the edges in the graph
|
|
|
|
* visible to the current transaction.
|
2017-04-21 21:39:41 +08:00
|
|
|
*
|
|
|
|
* @param current_state If true then the graph state for the
|
|
|
|
* current transaction+command is returned (insertions, updates and
|
|
|
|
* deletions performed in the current transaction+command are not
|
|
|
|
* ignored).
|
2017-02-16 22:47:55 +08:00
|
|
|
*/
|
2017-06-07 15:49:51 +08:00
|
|
|
auto edges(bool current_state) {
|
2017-04-03 17:12:15 +08:00
|
|
|
// wrap version lists into accessors, which will look for visible versions
|
|
|
|
auto accessors =
|
|
|
|
iter::imap([this](auto vlist) { return EdgeAccessor(*vlist, *this); },
|
|
|
|
db_.edges_.access());
|
2017-03-03 20:59:38 +08:00
|
|
|
|
2017-04-03 17:12:15 +08:00
|
|
|
// filter out the accessors not visible to the current transaction
|
|
|
|
return iter::filter(
|
2017-04-21 21:39:41 +08:00
|
|
|
[this, current_state](const EdgeAccessor &accessor) {
|
|
|
|
return (accessor.old_ &&
|
|
|
|
!(current_state &&
|
|
|
|
accessor.old_->is_deleted_by(*transaction_))) ||
|
|
|
|
(current_state && accessor.new_ &&
|
|
|
|
!accessor.new_->is_deleted_by(*transaction_));
|
2017-04-03 17:12:15 +08:00
|
|
|
},
|
|
|
|
std::move(accessors));
|
2017-03-03 20:59:38 +08:00
|
|
|
}
|
2017-02-16 22:47:55 +08:00
|
|
|
|
2017-04-05 23:23:00 +08:00
|
|
|
/**
|
|
|
|
* Return EdgeAccessors which contain the edge_type for the current
|
2017-04-21 21:39:41 +08:00
|
|
|
* transaction visibility.
|
2017-04-05 23:23:00 +08:00
|
|
|
* @param edge_type - edge_type for which to return EdgeAccessors
|
2017-04-21 21:39:41 +08:00
|
|
|
* @param current_state If true then the graph state for the
|
|
|
|
* current transaction+command is returned (insertions, updates and
|
|
|
|
* deletions performed in the current transaction+command are not
|
|
|
|
* ignored).
|
2017-04-05 23:23:00 +08:00
|
|
|
* @return iterable collection
|
|
|
|
*/
|
2017-06-07 15:49:51 +08:00
|
|
|
auto edges(const GraphDbTypes::EdgeType &edge_type, bool current_state) {
|
2017-04-21 21:39:41 +08:00
|
|
|
return iter::imap([this, current_state](
|
|
|
|
auto vlist) { return EdgeAccessor(*vlist, *this); },
|
|
|
|
db_.edge_types_index_.GetVlists(edge_type, *transaction_,
|
|
|
|
current_state));
|
2017-04-05 23:23:00 +08:00
|
|
|
}
|
|
|
|
|
2017-04-03 17:26:32 +08:00
|
|
|
/**
|
2017-07-11 20:28:25 +08:00
|
|
|
* Adds an index for the given (label, property) and populates
|
|
|
|
* it with existing vertices that belong to it.
|
|
|
|
*
|
|
|
|
* You should never call BuildIndex on a GraphDbAccessor
|
|
|
|
* (transaction) on which new vertices have been inserted or
|
|
|
|
* existing ones updated. Do it in a new accessor instead.
|
|
|
|
*
|
|
|
|
* Build index throws if an index for the given
|
|
|
|
* (label, property) already exists (even if it's being built
|
|
|
|
* by a concurrent transaction and is not yet ready for use).
|
|
|
|
*
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
* @param label - label to build for
|
|
|
|
* @param property - property to build for
|
2017-04-03 17:26:32 +08:00
|
|
|
*/
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
void BuildIndex(const GraphDbTypes::Label &label,
|
|
|
|
const GraphDbTypes::Property &property) {
|
|
|
|
const LabelPropertyIndex::Key key(label, property);
|
|
|
|
if (db_.label_property_index_.CreateIndex(key) == false) {
|
2017-07-03 16:38:58 +08:00
|
|
|
throw IndexExistsException(
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
"Index is either being created by another transaction or already "
|
|
|
|
"exists.");
|
|
|
|
}
|
|
|
|
// Everything that happens after the line above ended will be added to the
|
|
|
|
// index automatically, but we still have to add to index everything that
|
|
|
|
// happened earlier. We have to first wait for every transaction that
|
|
|
|
// happend before, or a bit later than CreateIndex to end.
|
2017-06-12 16:21:19 +08:00
|
|
|
{
|
2017-07-14 19:58:25 +08:00
|
|
|
auto wait_transaction = db_.tx_engine_.Begin();
|
2017-06-12 16:21:19 +08:00
|
|
|
for (auto id : wait_transaction->snapshot()) {
|
|
|
|
if (id == transaction_->id_) continue;
|
2017-07-12 20:26:01 +08:00
|
|
|
while (wait_transaction->engine_.clog().is_active(id))
|
2017-06-12 16:21:19 +08:00
|
|
|
// TODO reconsider this constant, currently rule-of-thumb chosen
|
|
|
|
std::this_thread::sleep_for(std::chrono::microseconds(100));
|
|
|
|
}
|
|
|
|
wait_transaction->Commit();
|
|
|
|
}
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
|
|
|
|
// This transaction surely sees everything that happened before CreateIndex.
|
2017-07-14 19:58:25 +08:00
|
|
|
auto transaction = db_.tx_engine_.Begin();
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
|
|
|
|
for (auto vertex_vlist : db_.vertices_.access()) {
|
|
|
|
auto vertex_record = vertex_vlist->find(*transaction);
|
|
|
|
// Check if visible record exists, if it exists apply function on it.
|
|
|
|
if (vertex_record == nullptr) continue;
|
|
|
|
db_.label_property_index_.UpdateOnLabelProperty(vertex_vlist,
|
|
|
|
vertex_record);
|
|
|
|
}
|
|
|
|
// Commit transaction as we finished applying method on newest visible
|
|
|
|
// records.
|
2017-06-12 16:21:19 +08:00
|
|
|
transaction->Commit();
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
// After these two operations we are certain that everything is contained in
|
|
|
|
// the index under the assumption that this transaction contained no
|
|
|
|
// vertex/edge insert/update before this method was invoked.
|
|
|
|
db_.label_property_index_.IndexFinishedBuilding(key);
|
|
|
|
}
|
2017-04-03 17:26:32 +08:00
|
|
|
|
|
|
|
/**
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
* @brief - Returns true if the given label+property index already exists and
|
|
|
|
* is ready for use.
|
2017-04-03 17:26:32 +08:00
|
|
|
*/
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
bool LabelPropertyIndexExists(const GraphDbTypes::Label &label,
|
2017-07-07 16:30:44 +08:00
|
|
|
const GraphDbTypes::Property &property) const {
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
return db_.label_property_index_.IndexExists(
|
|
|
|
LabelPropertyIndex::Key(label, property));
|
|
|
|
}
|
2017-04-05 23:23:00 +08:00
|
|
|
|
2017-07-12 18:35:22 +08:00
|
|
|
/**
|
|
|
|
* @brief - Returns vector of keys of label-property indices.
|
|
|
|
*/
|
|
|
|
std::vector<LabelPropertyIndex::Key> GetIndicesKeys() {
|
|
|
|
return db_.label_property_index_.GetIndicesKeys();
|
|
|
|
}
|
|
|
|
|
2017-04-21 21:39:41 +08:00
|
|
|
/**
|
|
|
|
* Return approximate number of all vertices in the database.
|
|
|
|
* Note that this is always an over-estimate and never an under-estimate.
|
|
|
|
*/
|
2017-07-05 22:00:07 +08:00
|
|
|
int64_t vertices_count() const;
|
2017-04-21 21:39:41 +08:00
|
|
|
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
/*
|
|
|
|
* Return approximate number of all edges in the database.
|
|
|
|
* Note that this is always an over-estimate and never an under-estimate.
|
|
|
|
*/
|
2017-07-05 22:00:07 +08:00
|
|
|
int64_t edges_count() const;
|
2017-04-21 21:39:41 +08:00
|
|
|
|
2017-04-03 17:26:32 +08:00
|
|
|
/**
|
|
|
|
* Return approximate number of vertices under indexes with the given label.
|
|
|
|
* Note that this is always an over-estimate and never an under-estimate.
|
|
|
|
* @param label - label to check for
|
|
|
|
* @return number of vertices with the given label
|
|
|
|
*/
|
2017-07-05 22:00:07 +08:00
|
|
|
int64_t vertices_count(const GraphDbTypes::Label &label) const;
|
2017-04-05 23:23:00 +08:00
|
|
|
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
/**
|
|
|
|
* Return approximate number of vertices under indexes with the given label
|
|
|
|
* and property.
|
|
|
|
* Note that this is always an over-estimate and never an under-estimate.
|
|
|
|
* @param label - label to check for
|
|
|
|
* @param property - property to check for
|
|
|
|
* @return number of vertices with the given label, fails if no such
|
|
|
|
* label+property index exists.
|
|
|
|
*/
|
2017-07-05 22:00:07 +08:00
|
|
|
int64_t vertices_count(const GraphDbTypes::Label &label,
|
|
|
|
const GraphDbTypes::Property &property) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns approximate number of vertices that have the given label
|
|
|
|
* and the given value for the given property.
|
|
|
|
*
|
|
|
|
* Assumes that an index for that (label, property) exists.
|
|
|
|
*/
|
|
|
|
int64_t vertices_count(const GraphDbTypes::Label &label,
|
|
|
|
const GraphDbTypes::Property &property,
|
|
|
|
const PropertyValue &value) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns approximate number of vertices that have the given label
|
|
|
|
* and whose vaue is in the range defined by upper and lower @c Bound.
|
2017-07-13 17:24:18 +08:00
|
|
|
*
|
|
|
|
* At least one bound must be specified. Neither can be
|
|
|
|
* PropertyValue::Null.
|
2017-07-05 22:00:07 +08:00
|
|
|
*
|
|
|
|
* Assumes that an index for that (label, property) exists.
|
|
|
|
*/
|
|
|
|
int64_t vertices_count(
|
|
|
|
const GraphDbTypes::Label &label, const GraphDbTypes::Property &property,
|
|
|
|
const std::experimental::optional<utils::Bound<PropertyValue>> lower,
|
|
|
|
const std::experimental::optional<utils::Bound<PropertyValue>> upper)
|
|
|
|
const;
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
|
2017-04-05 23:23:00 +08:00
|
|
|
/**
|
|
|
|
* Return approximate number of edges under indexes with the given edge_type.
|
|
|
|
* Note that this is always an over-estimate and never an under-estimate.
|
|
|
|
* @param edge_type - edge_type to check for
|
|
|
|
* @return number of edges with the given edge_type
|
|
|
|
*/
|
2017-07-05 22:00:07 +08:00
|
|
|
int64_t edges_count(const GraphDbTypes::EdgeType &edge_type) const;
|
2017-04-03 17:26:32 +08:00
|
|
|
|
2017-02-06 19:40:55 +08:00
|
|
|
/**
|
|
|
|
* Obtains the Label for the label's name.
|
|
|
|
* @return See above.
|
|
|
|
*/
|
2017-04-03 17:26:32 +08:00
|
|
|
GraphDbTypes::Label label(const std::string &label_name);
|
2017-02-06 19:40:55 +08:00
|
|
|
|
2017-02-11 14:51:02 +08:00
|
|
|
/**
|
|
|
|
* Obtains the label name (a string) for the given label.
|
|
|
|
*
|
|
|
|
* @param label a Label.
|
|
|
|
* @return See above.
|
|
|
|
*/
|
2017-06-12 21:19:04 +08:00
|
|
|
const std::string &label_name(const GraphDbTypes::Label label) const;
|
2017-02-11 14:51:02 +08:00
|
|
|
|
2017-02-06 19:40:55 +08:00
|
|
|
/**
|
|
|
|
* Obtains the EdgeType for it's name.
|
|
|
|
* @return See above.
|
|
|
|
*/
|
2017-04-03 17:26:32 +08:00
|
|
|
GraphDbTypes::EdgeType edge_type(const std::string &edge_type_name);
|
2017-02-06 19:40:55 +08:00
|
|
|
|
2017-02-11 14:51:02 +08:00
|
|
|
/**
|
|
|
|
* Obtains the edge type name (a string) for the given edge type.
|
|
|
|
*
|
|
|
|
* @param edge_type an EdgeType.
|
|
|
|
* @return See above.
|
|
|
|
*/
|
2017-06-12 21:19:04 +08:00
|
|
|
const std::string &edge_type_name(
|
|
|
|
const GraphDbTypes::EdgeType edge_type) const;
|
2017-02-11 14:51:02 +08:00
|
|
|
|
2017-02-06 19:40:55 +08:00
|
|
|
/**
|
|
|
|
* Obtains the Property for it's name.
|
|
|
|
* @return See above.
|
|
|
|
*/
|
2017-04-03 17:26:32 +08:00
|
|
|
GraphDbTypes::Property property(const std::string &property_name);
|
2017-02-06 19:40:55 +08:00
|
|
|
|
2017-02-11 14:51:02 +08:00
|
|
|
/**
|
|
|
|
* Obtains the property name (a string) for the given property.
|
|
|
|
*
|
|
|
|
* @param property a Property.
|
|
|
|
* @return See above.
|
|
|
|
*/
|
2017-06-12 21:19:04 +08:00
|
|
|
const std::string &property_name(const GraphDbTypes::Property property) const;
|
2017-02-11 14:51:02 +08:00
|
|
|
|
2017-03-06 21:17:55 +08:00
|
|
|
/**
|
|
|
|
* Advances transaction's command id by 1.
|
|
|
|
*/
|
|
|
|
void advance_command();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Commit transaction.
|
|
|
|
*/
|
|
|
|
void commit();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Abort transaction.
|
|
|
|
*/
|
|
|
|
void abort();
|
|
|
|
|
2017-07-14 19:58:25 +08:00
|
|
|
/**
|
|
|
|
* Return true if transaction is hinted to abort.
|
|
|
|
*/
|
|
|
|
bool should_abort() const;
|
|
|
|
|
2017-03-06 21:17:55 +08:00
|
|
|
/**
|
2017-04-03 17:12:15 +08:00
|
|
|
* Initializes the record pointers in the given accessor.
|
|
|
|
* The old_ and new_ pointers need to be initialized
|
|
|
|
* with appropriate values, and current_ set to old_
|
|
|
|
* if it exists and to new_ otherwise.
|
2017-04-18 17:50:01 +08:00
|
|
|
*
|
|
|
|
* @return True if accessor is valid after reconstruction.
|
|
|
|
* This means that at least one record pointer was found
|
|
|
|
* (either new_ or old_), possibly both.
|
2017-03-06 21:17:55 +08:00
|
|
|
*/
|
|
|
|
template <typename TRecord>
|
2017-04-18 17:50:01 +08:00
|
|
|
bool Reconstruct(RecordAccessor<TRecord> &accessor) {
|
2017-04-21 21:39:41 +08:00
|
|
|
accessor.vlist_->find_set_old_new(*transaction_, accessor.old_,
|
2017-04-03 17:12:15 +08:00
|
|
|
accessor.new_);
|
|
|
|
accessor.current_ = accessor.old_ ? accessor.old_ : accessor.new_;
|
2017-04-18 17:50:01 +08:00
|
|
|
return accessor.old_ != nullptr || accessor.new_ != nullptr;
|
2017-04-03 17:12:15 +08:00
|
|
|
// TODO review: we should never use a record accessor that
|
|
|
|
// does not have either old_ or new_ (both are null), but
|
|
|
|
// we can't assert that here because we construct such an accessor
|
|
|
|
// and filter it out in GraphDbAccessor::[Vertices|Edges]
|
|
|
|
// any ideas?
|
2017-03-06 21:17:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update accessor record with vlist.
|
2017-04-03 17:12:15 +08:00
|
|
|
*
|
|
|
|
* It is not legal
|
|
|
|
* to call this function on a Vertex/Edge that has
|
|
|
|
* been deleted in the current transaction+command.
|
|
|
|
*
|
2017-03-06 21:17:55 +08:00
|
|
|
* @args accessor whose record to update if possible.
|
|
|
|
*/
|
|
|
|
template <typename TRecord>
|
2017-04-03 17:26:32 +08:00
|
|
|
void update(RecordAccessor<TRecord> &accessor) {
|
2017-04-03 17:12:15 +08:00
|
|
|
// can't update a deleted record if:
|
|
|
|
// - we only have old_ and it hasn't been deleted
|
|
|
|
// - we have new_ and it hasn't been deleted
|
|
|
|
if (!accessor.new_) {
|
|
|
|
debug_assert(
|
|
|
|
!accessor.old_->is_deleted_by(*transaction_),
|
|
|
|
"Can't update a record deleted in the current transaction+command");
|
|
|
|
} else {
|
|
|
|
debug_assert(
|
|
|
|
!accessor.new_->is_deleted_by(*transaction_),
|
|
|
|
"Can't update a record deleted in the current transaction+command");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!accessor.new_) accessor.new_ = accessor.vlist_->update(*transaction_);
|
2017-03-06 21:17:55 +08:00
|
|
|
}
|
2017-02-04 16:01:15 +08:00
|
|
|
|
2017-02-18 18:54:37 +08:00
|
|
|
private:
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
/**
|
|
|
|
* Insert this vertex into corresponding label and label+property (if it
|
|
|
|
* exists) index.
|
|
|
|
* @param label - label with which to insert vertex label record
|
|
|
|
* @param vertex_accessor - vertex_accessor to insert
|
|
|
|
* @param vertex - vertex record to insert
|
|
|
|
*/
|
|
|
|
void update_label_indices(const GraphDbTypes::Label &label,
|
|
|
|
const VertexAccessor &vertex_accessor,
|
|
|
|
const Vertex *const vertex);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Insert this edge into corresponding edge_type index.
|
|
|
|
* @param edge_type - edge_type index into which to insert record
|
|
|
|
* @param edge_accessor - edge_accessor to insert
|
|
|
|
* @param edge - edge record to insert
|
|
|
|
*/
|
|
|
|
void update_edge_type_index(const GraphDbTypes::EdgeType &edge_type,
|
|
|
|
const EdgeAccessor &edge_accessor,
|
|
|
|
const Edge *const edge);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Insert this vertex into corresponding any label + 'property' index.
|
|
|
|
* @param property - vertex will be inserted into indexes which contain this
|
|
|
|
* property
|
|
|
|
* @param record_accessor - record_accessor to insert
|
|
|
|
* @param vertex - vertex to insert
|
|
|
|
*/
|
|
|
|
void update_property_index(const GraphDbTypes::Property &property,
|
|
|
|
const RecordAccessor<Vertex> &record_accessor,
|
|
|
|
const Vertex *const vertex);
|
2017-04-03 17:26:32 +08:00
|
|
|
GraphDb &db_;
|
2017-03-06 21:17:55 +08:00
|
|
|
|
|
|
|
/** The current transaction */
|
2017-04-03 17:26:32 +08:00
|
|
|
tx::Transaction *const transaction_;
|
2017-03-06 21:17:55 +08:00
|
|
|
|
|
|
|
bool commited_{false};
|
|
|
|
bool aborted_{false};
|
2017-02-04 16:01:15 +08:00
|
|
|
};
|