1
0
Fork 0

Started reimplementing ShortestPath wth new transactions and VPack

This commit is contained in:
Michael Hackstein 2016-03-15 18:34:37 +01:00
parent 84454f49c4
commit 6bcbf1241b
3 changed files with 69 additions and 348 deletions

View File

@ -69,6 +69,7 @@ OperationCursor EdgeCollectionInfo::getEdges(TRI_edge_direction_e direction,
_searchBuilder.clear();
EdgeIndex::buildSearchValue(direction, vertexId, _searchBuilder);
LOG(INFO) << _searchBuilder.slice().toJson();
return _trx->indexScan(_collectionName,
arangodb::Transaction::CursorType::INDEX, _indexId,
_searchBuilder.slice(), 0, UINT64_MAX, 1000, false);
@ -254,28 +255,19 @@ class SimpleEdgeExpander {
void BasicOptions::addVertexFilter(v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
ExplicitTransaction* trx,
TRI_document_collection_t* col,
VocShaper* shaper, TRI_voc_cid_t const& cid,
arangodb::Transaction* trx,
std::string const& name,
std::string& errorMessage) {
auto it = _vertexFilter.find(cid);
auto it = _vertexFilter.find(name);
if (example->IsArray()) {
if (it == _vertexFilter.end()) {
_vertexFilter.emplace(
cid, VertexFilterInfo(
trx, col, new ExampleMatcher(
isolate, v8::Handle<v8::Array>::Cast(example),
errorMessage)));
}
} else {
// Has to be Object
if (it == _vertexFilter.end()) {
_vertexFilter.emplace(
cid, VertexFilterInfo(
trx, col, new ExampleMatcher(
isolate, v8::Handle<v8::Array>::Cast(example),
errorMessage)));
if (it == _vertexFilter.end()) {
if (example->IsArray()) {
_vertexFilter.emplace(name, new ExampleMatcher(
isolate, v8::Handle<v8::Array>::Cast(example), errorMessage));
} else {
// Has to be Object
_vertexFilter.emplace(name, new ExampleMatcher(
isolate, v8::Handle<v8::Object>::Cast(example), errorMessage));
}
}
}

View File

@ -60,22 +60,6 @@ struct EdgeInfo {
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Template for information required by vertex filter.
/// Contains transaction, barrier and the Matcher Class.
////////////////////////////////////////////////////////////////////////////////
struct VertexFilterInfo {
arangodb::ExplicitTransaction* trx;
TRI_document_collection_t* col;
arangodb::ExampleMatcher* matcher;
VertexFilterInfo(arangodb::ExplicitTransaction* trx,
TRI_document_collection_t* col,
arangodb::ExampleMatcher* matcher)
: trx(trx), col(col), matcher(matcher) {}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief typedef the template instantiation of the PathFinder
////////////////////////////////////////////////////////////////////////////////
@ -94,7 +78,7 @@ namespace traverser {
struct BasicOptions {
protected:
std::unordered_map<std::string, arangodb::ExampleMatcher*> _edgeFilter;
std::unordered_map<TRI_voc_cid_t, VertexFilterInfo> _vertexFilter;
std::unordered_map<std::string, arangodb::ExampleMatcher*> _vertexFilter;
BasicOptions() : useEdgeFilter(false), useVertexFilter(false) {}
@ -104,8 +88,7 @@ struct BasicOptions {
delete it.second;
}
for (auto& it : _vertexFilter) {
delete it.second.matcher;
it.second.matcher = nullptr;
delete it.second;
}
}
@ -123,9 +106,9 @@ struct BasicOptions {
void addVertexFilter(v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
arangodb::ExplicitTransaction* trx,
TRI_document_collection_t* col, VocShaper* shaper,
TRI_voc_cid_t const& cid, std::string& errorMessage);
arangodb::Transaction* trx,
std::string const&,
std::string& errorMessage);
bool matchesEdge(arangodb::velocypack::Slice edge) const;
@ -391,40 +374,6 @@ class EdgeCollectionInfo {
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Information required internally of the traverser.
/// Used to easily pass around collections.
////////////////////////////////////////////////////////////////////////////////
class VertexCollectionInfo {
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief vertex collection
//////////////////////////////////////////////////////////////////////////////
TRI_voc_cid_t _vertexCollectionCid;
//////////////////////////////////////////////////////////////////////////////
/// @brief vertex collection
//////////////////////////////////////////////////////////////////////////////
TRI_document_collection_t* _vertexCollection;
public:
VertexCollectionInfo(TRI_voc_cid_t& vertexCollectionCid,
TRI_document_collection_t* vertexCollection)
: _vertexCollectionCid(vertexCollectionCid),
_vertexCollection(vertexCollection) {}
TRI_voc_cid_t getCid() { return _vertexCollectionCid; }
TRI_document_collection_t* getCollection() { return _vertexCollection; }
VocShaper* getShaper() {
return _vertexCollection->getShaper();
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Wrapper for the shortest path computation
////////////////////////////////////////////////////////////////////////////////

View File

@ -1699,27 +1699,6 @@ static void JS_ThrowCollectionNotLoaded(
TRI_V8_TRY_CATCH_END
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Transforms VertexId to v8String
////////////////////////////////////////////////////////////////////////////////
static v8::Local<v8::String> VertexIdToString(
v8::Isolate* isolate,
std::string const& id) {
return TRI_V8_STD_STRING(id);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Transforms EdgeId to v8String
////////////////////////////////////////////////////////////////////////////////
static v8::Local<v8::String> EdgeIdToString(
v8::Isolate* isolate, CollectionNameResolver const* resolver,
EdgeId const& id) {
return TRI_V8_STD_STRING(
(resolver->getCollectionName(id.cid) + "/" + std::string(id.key)));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Transforms VertexId to v8 object
/// NOTE: Collection has to be known to the transaction.
@ -1764,96 +1743,6 @@ static v8::Handle<v8::Value> EdgeIdToData(
return VertexIdToData(isolate, trx, edgeId);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Extracts all touched collections from ArangoDBPathFinder::Path
////////////////////////////////////////////////////////////////////////////////
/*
static void ExtractCidsFromPath(TRI_vocbase_t* vocbase,
ArangoDBPathFinder::Path const& p,
std::vector<TRI_voc_cid_t>& result) {
std::unordered_set<TRI_voc_cid_t> found;
uint32_t const vn = static_cast<uint32_t>(p.vertices.size());
uint32_t const en = static_cast<uint32_t>(p.edges.size());
for (uint32_t j = 0; j < vn; ++j) {
TRI_voc_cid_t cid = p.vertices[j].cid;
auto it = found.find(cid);
if (it == found.end()) {
// Not yet found. Insert it if it exists
if (TRI_LookupCollectionByIdVocBase(vocbase, cid) != nullptr) {
result.emplace_back(cid);
found.insert(cid);
}
}
}
for (uint32_t j = 0; j < en; ++j) {
TRI_voc_cid_t cid = p.edges[j].cid;
auto it = found.find(cid);
if (it == found.end()) {
// Not yet found. Insert it if it exists
if (TRI_LookupCollectionByIdVocBase(vocbase, cid) != nullptr) {
result.emplace_back(cid);
found.insert(cid);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Extracts all touched collections from ArangoDBPathFinder::Path
////////////////////////////////////////////////////////////////////////////////
static void ExtractCidsFromPath(TRI_vocbase_t* vocbase,
ArangoDBConstDistancePathFinder::Path const& p,
std::vector<TRI_voc_cid_t>& result) {
std::unordered_set<TRI_voc_cid_t> found;
uint32_t const vn = static_cast<uint32_t>(p.vertices.size());
uint32_t const en = static_cast<uint32_t>(p.edges.size());
for (uint32_t j = 0; j < vn; ++j) {
TRI_voc_cid_t cid = p.vertices[j].cid;
auto it = found.find(cid);
if (it == found.end()) {
// Not yet found. Insert it if it exists
if (TRI_LookupCollectionByIdVocBase(vocbase, cid) != nullptr) {
result.emplace_back(cid);
found.insert(cid);
}
}
}
for (uint32_t j = 0; j < en; ++j) {
TRI_voc_cid_t cid = p.edges[j].cid;
auto it = found.find(cid);
if (it == found.end()) {
// Not yet found. Insert it if it exists
if (TRI_LookupCollectionByIdVocBase(vocbase, cid) != nullptr) {
result.emplace_back(cid);
found.insert(cid);
}
}
}
}
*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Request a ditch for the given collection
////////////////////////////////////////////////////////////////////////////////
static void AddDitch(
ExplicitTransaction* trx, TRI_voc_cid_t const& cid,
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo>& ditches) {
TRI_document_collection_t* col = trx->documentCollection(cid);
auto ditch = trx->orderDitch(cid); // will throw when it fails
ditches.emplace(cid, CollectionDitchInfo(ditch, col));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Start a new transaction for the given collections and request
/// all necessary ditches.
@ -1863,10 +1752,8 @@ static void AddDitch(
static ExplicitTransaction* BeginTransaction(
std::shared_ptr<V8TransactionContext> transactionContext,
std::vector<TRI_voc_cid_t> const& readCollections,
std::vector<TRI_voc_cid_t> const& writeCollections,
CollectionNameResolver const* resolver,
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo>& ditches) {
std::vector<std::string> const& readCollections,
std::vector<std::string> const& writeCollections) {
// IHHF isCoordinator
double lockTimeout =
(double)(TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
@ -1876,34 +1763,24 @@ static ExplicitTransaction* BeginTransaction(
// Start Transaction to collect all parts of the path
auto trx = std::make_unique<ExplicitTransaction>(
transactionContext, readCollections, writeCollections, lockTimeout, waitForSync,
embed);
embed, true);
int res = trx->begin();
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
}
// Get all ditches at once
for (auto const& it : readCollections) {
AddDitch(trx.get(), it, ditches);
}
for (auto const& it : writeCollections) {
AddDitch(trx.get(), it, ditches);
}
return trx.release();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Transforms an ArangoDBPathFinder::Path to v8 json values
////////////////////////////////////////////////////////////////////////////////
/*
static v8::Handle<v8::Value> PathIdsToV8(
v8::Isolate* isolate, TRI_vocbase_t* vocbase,
CollectionNameResolver const* resolver, ArangoDBPathFinder::Path const& p,
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo>& ditches,
bool& includeData) {
static v8::Handle<v8::Value> PathIdsToV8(v8::Isolate* isolate,
TRI_vocbase_t* vocbase,
arangodb::Transaction* trx,
ArangoDBPathFinder::Path const& p,
bool& includeData) {
v8::EscapableHandleScope scope(isolate);
v8::Handle<v8::Object> result = v8::Object::New(isolate);
@ -1915,31 +1792,18 @@ static v8::Handle<v8::Value> PathIdsToV8(
v8::Handle<v8::Array> edges = v8::Array::New(isolate, static_cast<int>(en));
if (includeData) {
std::vector<TRI_voc_cid_t> readCollections;
ExtractCidsFromPath(vocbase, p, readCollections);
std::vector<TRI_voc_cid_t> writeCollections;
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo> ditches;
auto transactionContext = std::make_shared<V8TransactionContext>(vocbase, true);
std::unique_ptr<ExplicitTransaction> trx;
trx.reset(BeginTransaction(transactionContext, readCollections, writeCollections,
resolver, ditches));
for (uint32_t j = 0; j < vn; ++j) {
vertices->Set(j, VertexIdToData(isolate, resolver, trx.get(), ditches,
p.vertices[j]));
vertices->Set(j, VertexIdToData(isolate, trx, p.vertices[j]));
}
for (uint32_t j = 0; j < en; ++j) {
edges->Set(
j, EdgeIdToData(isolate, resolver, trx.get(), ditches, p.edges[j]));
edges->Set(j, EdgeIdToData(isolate, trx, p.edges[j]));
}
trx->finish(TRI_ERROR_NO_ERROR);
} else {
for (uint32_t j = 0; j < vn; ++j) {
vertices->Set(j, VertexIdToString(isolate, resolver, p.vertices[j]));
vertices->Set(j, TRI_V8_STD_STRING(p.vertices[j]));
}
for (uint32_t j = 0; j < en; ++j) {
edges->Set(j, EdgeIdToString(isolate, resolver, p.edges[j]));
edges->Set(j, TRI_V8_STD_STRING(p.edges[j]));
}
}
@ -1950,17 +1814,14 @@ static v8::Handle<v8::Value> PathIdsToV8(
return scope.Escape<v8::Value>(result);
}
*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Transforms an ConstDistanceFinder::Path to v8 json values
////////////////////////////////////////////////////////////////////////////////
/*
static v8::Handle<v8::Value> PathIdsToV8(
v8::Isolate* isolate, TRI_vocbase_t* vocbase,
CollectionNameResolver const* resolver,
ArangoDBConstDistancePathFinder::Path const& p,
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo>& ditches,
bool& includeData) {
v8::Isolate* isolate, TRI_vocbase_t* vocbase, arangodb::Transaction* trx,
ArangoDBConstDistancePathFinder::Path const& p, bool& includeData) {
v8::EscapableHandleScope scope(isolate);
v8::Handle<v8::Object> result = v8::Object::New(isolate);
@ -1972,31 +1833,18 @@ static v8::Handle<v8::Value> PathIdsToV8(
v8::Handle<v8::Array> edges = v8::Array::New(isolate, static_cast<int>(en));
if (includeData) {
std::vector<TRI_voc_cid_t> readCollections;
ExtractCidsFromPath(vocbase, p, readCollections);
std::vector<TRI_voc_cid_t> writeCollections;
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo> ditches;
auto transactionContext = std::make_shared<V8TransactionContext>(vocbase, true);
std::unique_ptr<ExplicitTransaction> trx;
trx.reset(BeginTransaction(transactionContext, readCollections, writeCollections,
resolver, ditches));
for (uint32_t j = 0; j < vn; ++j) {
vertices->Set(j, VertexIdToData(isolate, resolver, trx.get(), ditches,
p.vertices[j]));
vertices->Set(j, VertexIdToData(isolate, trx, p.vertices[j]));
}
for (uint32_t j = 0; j < en; ++j) {
edges->Set(
j, EdgeIdToData(isolate, resolver, trx.get(), ditches, p.edges[j]));
edges->Set(j, EdgeIdToData(isolate, trx, p.edges[j]));
}
trx->finish(TRI_ERROR_NO_ERROR);
} else {
for (uint32_t j = 0; j < vn; ++j) {
vertices->Set(j, VertexIdToString(isolate, resolver, p.vertices[j]));
vertices->Set(j, TRI_V8_STD_STRING(p.vertices[j]));
}
for (uint32_t j = 0; j < en; ++j) {
edges->Set(j, EdgeIdToString(isolate, resolver, p.edges[j]));
edges->Set(j, TRI_V8_STD_STRING(p.edges[j]));
}
}
@ -2007,7 +1855,6 @@ static v8::Handle<v8::Value> PathIdsToV8(
return scope.Escape<v8::Value>(result);
}
*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Extract collection names from v8 array.
@ -2076,12 +1923,6 @@ class AttributeWeightCalculator {
static void JS_QueryShortestPath(
v8::FunctionCallbackInfo<v8::Value> const& args) {
#warning Re-implement Shortest Path with new TRX and VPAck
TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
TRI_V8_TRY_CATCH_END
/*
TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate);
@ -2194,76 +2035,57 @@ static void JS_QueryShortestPath(
}
}
std::vector<TRI_voc_cid_t> readCollections;
std::vector<TRI_voc_cid_t> writeCollections;
auto transactionContext = std::make_shared<V8TransactionContext>(vocbase, true);
int res = TRI_ERROR_NO_ERROR;
CollectionNameResolver const* resolver = transactionContext->getResolver();
std::vector<std::string> readCollections;
std::vector<std::string> writeCollections;
for (auto const& it : edgeCollectionNames) {
readCollections.emplace_back(resolver->getCollectionIdLocal(it));
readCollections.emplace_back(it);
}
for (auto const& it : vertexCollectionNames) {
readCollections.emplace_back(resolver->getCollectionIdLocal(it));
readCollections.emplace_back(it);
}
// Start the transaction and order ditches
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo> ditches;
std::unique_ptr<ExplicitTransaction> trx;
try {
trx.reset(BeginTransaction(transactionContext, readCollections, writeCollections,
resolver, ditches));
trx.reset(BeginTransaction(transactionContext, readCollections,
writeCollections));
} catch (Exception& e) {
TRI_V8_THROW_EXCEPTION(e.code());
}
std::vector<EdgeCollectionInfo*> edgeCollectionInfos;
std::vector<VertexCollectionInfo*> vertexCollectionInfos;
arangodb::basics::ScopeGuard guard{
[]() -> void {},
[&edgeCollectionInfos, &vertexCollectionInfos]() -> void {
[&edgeCollectionInfos]() -> void {
for (auto& p : edgeCollectionInfos) {
delete p;
}
for (auto& p : vertexCollectionInfos) {
delete p;
}
}};
if (opts.useWeight) {
for (auto const& it : edgeCollectionNames) {
auto cid = resolver->getCollectionIdLocal(it);
TRI_document_collection_t* colObj = ditches.find(cid)->second.col;
edgeCollectionInfos.emplace_back(new EdgeCollectionInfo(
trx.get(), cid, colObj,
AttributeWeightCalculator(opts.weightAttribute, opts.defaultWeight,
colObj->getShaper())));
trx.get(), it,
AttributeWeightCalculator(opts.weightAttribute, opts.defaultWeight)));
}
} else {
for (auto const& it : edgeCollectionNames) {
auto cid = resolver->getCollectionIdLocal(it);
TRI_document_collection_t* colObj = ditches.find(cid)->second.col;
edgeCollectionInfos.emplace_back(new EdgeCollectionInfo(
trx.get(), cid, colObj, HopWeightCalculator()));
edgeCollectionInfos.emplace_back(
new EdgeCollectionInfo(trx.get(), it, HopWeightCalculator()));
}
}
for (auto const& it : vertexCollectionNames) {
auto cid = resolver->getCollectionIdLocal(it);
TRI_document_collection_t* colObj = ditches.find(cid)->second.col;
vertexCollectionInfos.emplace_back(new VertexCollectionInfo(cid, colObj));
}
if (opts.useEdgeFilter) {
std::string errorMessage;
for (auto const& it : edgeCollectionInfos) {
try {
opts.addEdgeFilter(isolate, edgeExample, it->getShaper(), it->getCid(),
errorMessage);
opts.addEdgeFilter(isolate, edgeExample, it->getName(), errorMessage);
} catch (Exception& e) {
// ELEMENT not found is expected, if there is no shape of this type in
// this collection
@ -2276,10 +2098,9 @@ static void JS_QueryShortestPath(
if (opts.useVertexFilter) {
std::string errorMessage;
for (auto const& it : vertexCollectionInfos) {
for (auto const& it : vertexCollectionNames) {
try {
opts.addVertexFilter(isolate, vertexExample, trx.get(),
it->getCollection(), it->getShaper(), it->getCid(),
opts.addVertexFilter(isolate, vertexExample, trx.get(), it,
errorMessage);
} catch (Exception& e) {
// ELEMENT not found is expected, if there is no shape of this type in
@ -2292,8 +2113,8 @@ static void JS_QueryShortestPath(
}
try {
opts.start = IdStringToVertexId(resolver, startVertex);
opts.end = IdStringToVertexId(resolver, targetVertex);
opts.start = startVertex;
opts.end = targetVertex;
} catch (Exception& e) {
// Id string might have illegal collection name
trx->finish(e.code());
@ -2318,19 +2139,9 @@ static void JS_QueryShortestPath(
TRI_V8_RETURN(scope.Escape<v8::Value>(v8::Null(isolate)));
}
trx->finish(res);
// must finish "old" transaction first before starting a new in PathIdsToV8
delete trx.release();
// Potential inconsistency here. Graph is outside a transaction in this very
// second.
// Adding additional locks on vertex collections at this point to the
// transaction
// would cause dead-locks.
// Will be fixed automatically with new MVCC version.
try {
auto result =
PathIdsToV8(isolate, vocbase, resolver, *path, ditches, includeData);
auto result = PathIdsToV8(isolate, vocbase, trx.get(), *path, includeData);
TRI_V8_RETURN(result);
} catch (Exception& e) {
TRI_V8_THROW_EXCEPTION(e.code());
@ -2354,26 +2165,15 @@ static void JS_QueryShortestPath(
TRI_V8_RETURN(scope.Escape<v8::Value>(v8::Null(isolate)));
}
trx->finish(res);
// must finish "old" transaction first before starting a new in PathIdsToV8
delete trx.release();
// Potential inconsistency here. Graph is outside a transaction in this very
// second.
// Adding additional locks on vertex collections at this point to the
// transaction
// would cause dead-locks.
// Will be fixed automatically with new MVCC version.
try {
auto result =
PathIdsToV8(isolate, vocbase, resolver, *path, ditches, includeData);
auto result = PathIdsToV8(isolate, vocbase, trx.get(), *path, includeData);
TRI_V8_RETURN(result);
} catch (Exception& e) {
TRI_V8_THROW_EXCEPTION(e.code());
}
}
trx->finish(res);
TRI_V8_TRY_CATCH_END
*/
}
////////////////////////////////////////////////////////////////////////////////
@ -2382,8 +2182,7 @@ static void JS_QueryShortestPath(
static v8::Handle<v8::Value> VertexIdsToV8(
v8::Isolate* isolate, ExplicitTransaction* trx,
CollectionNameResolver const* resolver, std::unordered_set<std::string>& ids,
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo>& ditches,
std::unordered_set<std::string>& ids,
bool includeData = false) {
v8::EscapableHandleScope scope(isolate);
uint32_t const vn = static_cast<uint32_t>(ids.size());
@ -2398,7 +2197,7 @@ static v8::Handle<v8::Value> VertexIdsToV8(
}
} else {
for (auto& it : ids) {
vertices->Set(j, VertexIdToString(isolate, it));
vertices->Set(j, TRI_V8_STD_STRING(it));
++j;
}
}
@ -2519,43 +2318,37 @@ static void JS_QueryNeighbors(v8::FunctionCallbackInfo<v8::Value> const& args) {
}
}
std::vector<TRI_voc_cid_t> readCollections;
std::vector<TRI_voc_cid_t> writeCollections;
std::vector<std::string> readCollections;
std::vector<std::string> writeCollections;
auto transactionContext = std::make_shared<V8TransactionContext>(vocbase, true);
int res = TRI_ERROR_NO_ERROR;
CollectionNameResolver const* resolver = transactionContext->getResolver();
for (auto const& it : edgeCollectionNames) {
readCollections.emplace_back(resolver->getCollectionIdLocal(it));
readCollections.emplace_back(it);
}
for (auto const& it : vertexCollectionNames) {
readCollections.emplace_back(resolver->getCollectionIdLocal(it));
readCollections.emplace_back(it);
}
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo> ditches;
std::unique_ptr<ExplicitTransaction> trx;
try {
trx.reset(BeginTransaction(transactionContext, readCollections, writeCollections,
resolver, ditches));
trx.reset(BeginTransaction(transactionContext, readCollections,
writeCollections));
} catch (Exception& e) {
TRI_V8_THROW_EXCEPTION(e.code());
}
std::vector<EdgeCollectionInfo*> edgeCollectionInfos;
std::vector<VertexCollectionInfo*> vertexCollectionInfos;
arangodb::basics::ScopeGuard guard{
[]() -> void {},
[&edgeCollectionInfos, &vertexCollectionInfos]() -> void {
[&edgeCollectionInfos]() -> void {
for (auto& p : edgeCollectionInfos) {
delete p;
}
for (auto& p : vertexCollectionInfos) {
delete p;
}
}};
for (auto const& it : edgeCollectionNames) {
@ -2566,17 +2359,6 @@ static void JS_QueryNeighbors(v8::FunctionCallbackInfo<v8::Value> const& args) {
}
}
for (auto it : vertexCollectionNames) {
auto cid = resolver->getCollectionIdLocal(it);
TRI_document_collection_t* colObj = ditches.find(cid)->second.col;
vertexCollectionInfos.emplace_back(new VertexCollectionInfo(cid, colObj));
// Explicitly allow all collections.
opts.addCollectionRestriction(cid);
TRI_IF_FAILURE("VertexCollectionDitchOOM") {
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
}
}
std::unordered_set<std::string> neighbors;
if (opts.useEdgeFilter) {
@ -2596,10 +2378,9 @@ static void JS_QueryNeighbors(v8::FunctionCallbackInfo<v8::Value> const& args) {
if (opts.useVertexFilter) {
std::string errorMessage;
for (auto const& it : vertexCollectionInfos) {
for (auto const& it : vertexCollectionNames) {
try {
opts.addVertexFilter(isolate, vertexExample, trx.get(),
it->getCollection(), it->getShaper(), it->getCid(),
opts.addVertexFilter(isolate, vertexExample, trx.get(), it,
errorMessage);
} catch (Exception& e) {
// ELEMENT not found is expected, if there is no shape of this type in
@ -2621,8 +2402,7 @@ static void JS_QueryNeighbors(v8::FunctionCallbackInfo<v8::Value> const& args) {
}
}
auto result = VertexIdsToV8(isolate, trx.get(), resolver, neighbors, ditches,
includeData);
auto result = VertexIdsToV8(isolate, trx.get(), neighbors, includeData);
trx->finish(res);