GraphDbAccessor::Transfer added

Summary: A helper function added for transferring graph elements into some GraphDbAccessor.

Reviewers: mislav.bradac, buda, teon.banek

Reviewed By: mislav.bradac

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D581
This commit is contained in:
florijan 2017-07-21 11:25:32 +02:00
parent 23329d66ee
commit f02c658ed4
2 changed files with 64 additions and 8 deletions

View File

@ -298,16 +298,45 @@ class GraphDbAccessor {
}
/**
* Adds an index for the given (label, property) and populates
* it with existing vertices that belong to it.
* Creates and returns a new accessor that represents the same graph element
* (node / version) as the given `accessor`, but in this `GraphDbAccessor`.
*
* 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.
* It is possible that the given `accessor` graph element is not visible in
* this `GraphDbAccessor`'s transaction. If that is the case, a `nullopt` is
* returned.
*
* 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).
* The returned accessor does NOT have the same `current_` set as the given
* `accessor`. It has default post-construction `current_` set (`old` if
* available, otherwise `new`).
*
* @param accessor The [Vertex/Edge]Accessor whose underlying graph
* element we want in this GraphDbAccessor.
* @return See above.
* @tparam TAccessor Either VertexAccessor or EdgeAccessor
*/
template <typename TAccessor>
std::experimental::optional<TAccessor> Transfer(const TAccessor &accessor) {
if (accessor.db_accessor_ == this)
return std::experimental::make_optional(accessor);
TAccessor accessor_in_this(*accessor.vlist_, *this);
if (accessor_in_this.current_)
return std::experimental::make_optional(std::move(accessor_in_this));
else
return std::experimental::nullopt;
}
/**
* 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).
*
* @param label - label to build for
* @param property - property to build for

View File

@ -1,3 +1,4 @@
#include <experimental/optional>
#include "gtest/gtest.h"
#include "database/graph_db.hpp"
@ -325,6 +326,32 @@ TEST(GraphDbAccessorTest, Properties) {
EXPECT_NE(prop, dbms.active()->property("surname"));
}
TEST(GraphDbAccessorTest, Transfer) {
Dbms dbms;
auto dba1 = dbms.active();
auto prop = dba1->property("property");
VertexAccessor v1 = dba1->insert_vertex();
v1.PropsSet(prop, 1);
VertexAccessor v2 = dba1->insert_vertex();
v2.PropsSet(prop, 2);
EdgeAccessor e12 = dba1->insert_edge(v1, v2, dba1->edge_type("et"));
e12.PropsSet(prop, 12);
// make dba2 that has dba1 in it's snapshot, so data isn't visible
auto dba2 = dbms.active();
EXPECT_EQ(dba2->Transfer(v1), std::experimental::nullopt);
EXPECT_EQ(dba2->Transfer(e12), std::experimental::nullopt);
// make dba3 that does not have dba1 in it's snapshot
dba1->commit();
auto dba3 = dbms.active();
// we can transfer accessors even though the GraphDbAccessor they
// belong to is not alive anymore
EXPECT_EQ(dba3->Transfer(v1)->PropsAt(prop).Value<int64_t>(), 1);
EXPECT_EQ(dba3->Transfer(e12)->PropsAt(prop).Value<int64_t>(), 12);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
// ::testing::GTEST_FLAG(filter) = "*.DetachRemoveVertex";