1
0
Fork 0

Bug fix 3.4/fix prune memleak (#8716)

This commit is contained in:
Jan 2019-04-10 00:10:01 +02:00 committed by GitHub
parent e3ca0c252b
commit 7a28877522
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 40 deletions

View File

@ -1,6 +1,9 @@
v3.4.6 (XXXX-XX-XX) v3.4.6 (XXXX-XX-XX)
------------------- -------------------
* fixed a memory leak in PRUNE operation for traversals.
The leak occurred only when PRUNE was actively used in queries.
* fixed a crash (SIGSEGV) when opening a RocksDB database directory that * fixed a crash (SIGSEGV) when opening a RocksDB database directory that
contained an empty (0 bytes filesize) journal file and encryption was in use. contained an empty (0 bytes filesize) journal file and encryption was in use.

View File

@ -292,20 +292,28 @@ bool BreadthFirstEnumerator::prepareSearchOnNextDepth() {
} }
bool BreadthFirstEnumerator::shouldPrune() { bool BreadthFirstEnumerator::shouldPrune() {
if (_opts->usesPrune()) { if (!_opts->usesPrune()) {
auto* evaluator = _opts->getPruneEvaluator(); return false;
if (evaluator->needsVertex()) {
evaluator->injectVertex(vertexToAqlValue(_schreierIndex).slice());
}
if (evaluator->needsEdge()) {
evaluator->injectEdge(edgeToAqlValue(_schreierIndex).slice());
}
transaction::BuilderLeaser builder(_opts->trx());
if (evaluator->needsPath()) {
aql::AqlValue val = pathToIndexToAqlValue(*builder.get(), _schreierIndex);
evaluator->injectPath(val.slice());
}
return evaluator->evaluate();
} }
return false; auto* evaluator = _opts->getPruneEvaluator();
aql::AqlValue vertex;
aql::AqlValueGuard vertexGuard{vertex, true};
if (evaluator->needsVertex()) {
vertex = vertexToAqlValue(_schreierIndex);
evaluator->injectVertex(vertex.slice());
}
aql::AqlValue edge;
aql::AqlValueGuard edgeGuard{edge, true};
if (evaluator->needsEdge()) {
edge = edgeToAqlValue(_schreierIndex);
evaluator->injectEdge(edge.slice());
}
transaction::BuilderLeaser builder(_opts->trx());
aql::AqlValue path;
aql::AqlValueGuard pathGuard{path, true};
if (evaluator->needsPath()) {
path = pathToIndexToAqlValue(*builder.get(), _schreierIndex);
evaluator->injectPath(path.slice());
}
return evaluator->evaluate();
} }

View File

@ -153,15 +153,18 @@ void NeighborsEnumerator::swapLastAndCurrentDepth() {
bool NeighborsEnumerator::shouldPrune(arangodb::StringRef v) { bool NeighborsEnumerator::shouldPrune(arangodb::StringRef v) {
// Prune here // Prune here
if (_opts->usesPrune()) { if (!_opts->usesPrune()) {
auto* evaluator = _opts->getPruneEvaluator(); return false;
if (evaluator->needsVertex()) {
evaluator->injectVertex(_traverser->fetchVertexData(v).slice());
}
// We cannot support these two here
TRI_ASSERT(!evaluator->needsEdge());
TRI_ASSERT(!evaluator->needsPath());
return evaluator->evaluate();
} }
return false; auto* evaluator = _opts->getPruneEvaluator();
aql::AqlValue val;
aql::AqlValueGuard guard{val, true};
if (evaluator->needsVertex()) {
val = _traverser->fetchVertexData(v);
evaluator->injectVertex(val.slice());
}
// We cannot support these two here
TRI_ASSERT(!evaluator->needsEdge());
TRI_ASSERT(!evaluator->needsPath());
return evaluator->evaluate();
} }

View File

@ -214,20 +214,28 @@ arangodb::aql::AqlValue DepthFirstEnumerator::pathToAqlValue(arangodb::velocypac
bool DepthFirstEnumerator::shouldPrune() { bool DepthFirstEnumerator::shouldPrune() {
// We need to call prune here // We need to call prune here
if (_opts->usesPrune()) { if (!_opts->usesPrune()) {
auto* evaluator = _opts->getPruneEvaluator(); return false;
if (evaluator->needsVertex()) {
evaluator->injectVertex(lastVertexToAqlValue().slice());
}
if (evaluator->needsEdge()) {
evaluator->injectEdge(lastEdgeToAqlValue().slice());
}
transaction::BuilderLeaser builder(_opts->trx());
if (evaluator->needsPath()) {
aql::AqlValue val = pathToAqlValue(*builder.get());
evaluator->injectPath(val.slice());
}
return evaluator->evaluate();
} }
return false; auto* evaluator = _opts->getPruneEvaluator();
aql::AqlValue vertex;
aql::AqlValueGuard vertexGuard{vertex, true};
if (evaluator->needsVertex()) {
vertex = lastVertexToAqlValue();
evaluator->injectVertex(vertex.slice());
}
aql::AqlValue edge;
aql::AqlValueGuard edgeGuard{edge, true};
if (evaluator->needsEdge()) {
edge = lastEdgeToAqlValue();
evaluator->injectEdge(edge.slice());
}
transaction::BuilderLeaser builder(_opts->trx());
aql::AqlValue path;
aql::AqlValueGuard pathGuard{path, true};
if (evaluator->needsPath()) {
path = pathToAqlValue(*builder.get());
evaluator->injectPath(path.slice());
}
return evaluator->evaluate();
} }