Fix race condition in BuildIndex

Reviewers: florijan

Reviewed By: florijan

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D871
This commit is contained in:
Mislav Bradac 2017-10-06 14:33:57 +02:00
parent c6f1920f8b
commit da3e46c2d6

View File

@ -58,19 +58,13 @@ void GraphDbAccessor::BuildIndex(const GraphDbTypes::Label &label,
const GraphDbTypes::Property &property) { const GraphDbTypes::Property &property) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); debug_assert(!commited_ && !aborted_, "Accessor committed or aborted");
const LabelPropertyIndex::Key key(label, property);
if (db_.label_property_index_.CreateIndex(key) == false) {
throw IndexExistsException(
"Index is either being created by another transaction or already "
"exists.");
}
{ {
// switch the build_in_progress to true // switch the build_in_progress to true
bool expected = false; bool expected = false;
if (!db_.index_build_in_progress_.compare_exchange_strong(expected, true)) if (!db_.index_build_in_progress_.compare_exchange_strong(expected, true))
throw IndexBuildInProgressException(); throw IndexBuildInProgressException();
} }
// on function exit switch the build_in_progress to false // on function exit switch the build_in_progress to false
utils::OnScopeExit on_exit([this] { utils::OnScopeExit on_exit([this] {
bool expected = true; bool expected = true;
@ -79,6 +73,13 @@ void GraphDbAccessor::BuildIndex(const GraphDbTypes::Label &label,
debug_assert(success, "BuildIndexInProgress flag was not set during build"); debug_assert(success, "BuildIndexInProgress flag was not set during build");
}); });
const LabelPropertyIndex::Key key(label, property);
if (db_.label_property_index_.CreateIndex(key) == false) {
throw IndexExistsException(
"Index is either being created by another transaction or already "
"exists.");
}
// Everything that happens after the line above ended will be added to the // 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 // index automatically, but we still have to add to index everything that
// happened earlier. We have to first wait for every transaction that // happened earlier. We have to first wait for every transaction that
@ -115,17 +116,17 @@ void GraphDbAccessor::UpdateLabelIndices(const GraphDbTypes::Label &label,
const VertexAccessor &vertex_accessor, const VertexAccessor &vertex_accessor,
const Vertex *const vertex) { const Vertex *const vertex) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); debug_assert(!commited_ && !aborted_, "Accessor committed or aborted");
this->db_.labels_index_.Update(label, vertex_accessor.vlist_, vertex); db_.labels_index_.Update(label, vertex_accessor.vlist_, vertex);
this->db_.label_property_index_.UpdateOnLabel(label, vertex_accessor.vlist_, db_.label_property_index_.UpdateOnLabel(label, vertex_accessor.vlist_,
vertex); vertex);
} }
void GraphDbAccessor::UpdatePropertyIndex( void GraphDbAccessor::UpdatePropertyIndex(
const GraphDbTypes::Property &property, const GraphDbTypes::Property &property,
const RecordAccessor<Vertex> &record_accessor, const Vertex *const vertex) { const RecordAccessor<Vertex> &record_accessor, const Vertex *const vertex) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); debug_assert(!commited_ && !aborted_, "Accessor committed or aborted");
this->db_.label_property_index_.UpdateOnProperty( db_.label_property_index_.UpdateOnProperty(property, record_accessor.vlist_,
property, record_accessor.vlist_, vertex); vertex);
} }
int64_t GraphDbAccessor::VerticesCount() const { int64_t GraphDbAccessor::VerticesCount() const {