mirror of https://gitee.com/bigwinds/arangodb
Started reimplementing ShortestPath wth new transactions and VPack
This commit is contained in:
parent
84454f49c4
commit
6bcbf1241b
|
@ -69,6 +69,7 @@ OperationCursor EdgeCollectionInfo::getEdges(TRI_edge_direction_e direction,
|
||||||
|
|
||||||
_searchBuilder.clear();
|
_searchBuilder.clear();
|
||||||
EdgeIndex::buildSearchValue(direction, vertexId, _searchBuilder);
|
EdgeIndex::buildSearchValue(direction, vertexId, _searchBuilder);
|
||||||
|
LOG(INFO) << _searchBuilder.slice().toJson();
|
||||||
return _trx->indexScan(_collectionName,
|
return _trx->indexScan(_collectionName,
|
||||||
arangodb::Transaction::CursorType::INDEX, _indexId,
|
arangodb::Transaction::CursorType::INDEX, _indexId,
|
||||||
_searchBuilder.slice(), 0, UINT64_MAX, 1000, false);
|
_searchBuilder.slice(), 0, UINT64_MAX, 1000, false);
|
||||||
|
@ -254,28 +255,19 @@ class SimpleEdgeExpander {
|
||||||
|
|
||||||
void BasicOptions::addVertexFilter(v8::Isolate* isolate,
|
void BasicOptions::addVertexFilter(v8::Isolate* isolate,
|
||||||
v8::Handle<v8::Value> const& example,
|
v8::Handle<v8::Value> const& example,
|
||||||
ExplicitTransaction* trx,
|
arangodb::Transaction* trx,
|
||||||
TRI_document_collection_t* col,
|
std::string const& name,
|
||||||
VocShaper* shaper, TRI_voc_cid_t const& cid,
|
|
||||||
std::string& errorMessage) {
|
std::string& errorMessage) {
|
||||||
auto it = _vertexFilter.find(cid);
|
auto it = _vertexFilter.find(name);
|
||||||
|
|
||||||
if (example->IsArray()) {
|
|
||||||
if (it == _vertexFilter.end()) {
|
if (it == _vertexFilter.end()) {
|
||||||
_vertexFilter.emplace(
|
if (example->IsArray()) {
|
||||||
cid, VertexFilterInfo(
|
_vertexFilter.emplace(name, new ExampleMatcher(
|
||||||
trx, col, new ExampleMatcher(
|
isolate, v8::Handle<v8::Array>::Cast(example), errorMessage));
|
||||||
isolate, v8::Handle<v8::Array>::Cast(example),
|
|
||||||
errorMessage)));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Has to be Object
|
// Has to be Object
|
||||||
if (it == _vertexFilter.end()) {
|
_vertexFilter.emplace(name, new ExampleMatcher(
|
||||||
_vertexFilter.emplace(
|
isolate, v8::Handle<v8::Object>::Cast(example), errorMessage));
|
||||||
cid, VertexFilterInfo(
|
|
||||||
trx, col, new ExampleMatcher(
|
|
||||||
isolate, v8::Handle<v8::Array>::Cast(example),
|
|
||||||
errorMessage)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
/// @brief typedef the template instantiation of the PathFinder
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -94,7 +78,7 @@ namespace traverser {
|
||||||
struct BasicOptions {
|
struct BasicOptions {
|
||||||
protected:
|
protected:
|
||||||
std::unordered_map<std::string, arangodb::ExampleMatcher*> _edgeFilter;
|
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) {}
|
BasicOptions() : useEdgeFilter(false), useVertexFilter(false) {}
|
||||||
|
|
||||||
|
@ -104,8 +88,7 @@ struct BasicOptions {
|
||||||
delete it.second;
|
delete it.second;
|
||||||
}
|
}
|
||||||
for (auto& it : _vertexFilter) {
|
for (auto& it : _vertexFilter) {
|
||||||
delete it.second.matcher;
|
delete it.second;
|
||||||
it.second.matcher = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +106,9 @@ struct BasicOptions {
|
||||||
|
|
||||||
void addVertexFilter(v8::Isolate* isolate,
|
void addVertexFilter(v8::Isolate* isolate,
|
||||||
v8::Handle<v8::Value> const& example,
|
v8::Handle<v8::Value> const& example,
|
||||||
arangodb::ExplicitTransaction* trx,
|
arangodb::Transaction* trx,
|
||||||
TRI_document_collection_t* col, VocShaper* shaper,
|
std::string const&,
|
||||||
TRI_voc_cid_t const& cid, std::string& errorMessage);
|
std::string& errorMessage);
|
||||||
|
|
||||||
bool matchesEdge(arangodb::velocypack::Slice edge) const;
|
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
|
/// @brief Wrapper for the shortest path computation
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1699,27 +1699,6 @@ static void JS_ThrowCollectionNotLoaded(
|
||||||
TRI_V8_TRY_CATCH_END
|
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
|
/// @brief Transforms VertexId to v8 object
|
||||||
/// NOTE: Collection has to be known to the transaction.
|
/// NOTE: Collection has to be known to the transaction.
|
||||||
|
@ -1764,96 +1743,6 @@ static v8::Handle<v8::Value> EdgeIdToData(
|
||||||
return VertexIdToData(isolate, trx, edgeId);
|
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
|
/// @brief Start a new transaction for the given collections and request
|
||||||
/// all necessary ditches.
|
/// all necessary ditches.
|
||||||
|
@ -1863,10 +1752,8 @@ static void AddDitch(
|
||||||
|
|
||||||
static ExplicitTransaction* BeginTransaction(
|
static ExplicitTransaction* BeginTransaction(
|
||||||
std::shared_ptr<V8TransactionContext> transactionContext,
|
std::shared_ptr<V8TransactionContext> transactionContext,
|
||||||
std::vector<TRI_voc_cid_t> const& readCollections,
|
std::vector<std::string> const& readCollections,
|
||||||
std::vector<TRI_voc_cid_t> const& writeCollections,
|
std::vector<std::string> const& writeCollections) {
|
||||||
CollectionNameResolver const* resolver,
|
|
||||||
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo>& ditches) {
|
|
||||||
// IHHF isCoordinator
|
// IHHF isCoordinator
|
||||||
double lockTimeout =
|
double lockTimeout =
|
||||||
(double)(TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
|
(double)(TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
|
||||||
|
@ -1876,33 +1763,23 @@ static ExplicitTransaction* BeginTransaction(
|
||||||
// Start Transaction to collect all parts of the path
|
// Start Transaction to collect all parts of the path
|
||||||
auto trx = std::make_unique<ExplicitTransaction>(
|
auto trx = std::make_unique<ExplicitTransaction>(
|
||||||
transactionContext, readCollections, writeCollections, lockTimeout, waitForSync,
|
transactionContext, readCollections, writeCollections, lockTimeout, waitForSync,
|
||||||
embed);
|
embed, true);
|
||||||
|
|
||||||
int res = trx->begin();
|
int res = trx->begin();
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
THROW_ARANGO_EXCEPTION(res);
|
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();
|
return trx.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Transforms an ArangoDBPathFinder::Path to v8 json values
|
/// @brief Transforms an ArangoDBPathFinder::Path to v8 json values
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/*
|
|
||||||
static v8::Handle<v8::Value> PathIdsToV8(
|
static v8::Handle<v8::Value> PathIdsToV8(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, TRI_vocbase_t* vocbase,
|
TRI_vocbase_t* vocbase,
|
||||||
CollectionNameResolver const* resolver, ArangoDBPathFinder::Path const& p,
|
arangodb::Transaction* trx,
|
||||||
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo>& ditches,
|
ArangoDBPathFinder::Path const& p,
|
||||||
bool& includeData) {
|
bool& includeData) {
|
||||||
v8::EscapableHandleScope scope(isolate);
|
v8::EscapableHandleScope scope(isolate);
|
||||||
v8::Handle<v8::Object> result = v8::Object::New(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));
|
v8::Handle<v8::Array> edges = v8::Array::New(isolate, static_cast<int>(en));
|
||||||
|
|
||||||
if (includeData) {
|
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) {
|
for (uint32_t j = 0; j < vn; ++j) {
|
||||||
vertices->Set(j, VertexIdToData(isolate, resolver, trx.get(), ditches,
|
vertices->Set(j, VertexIdToData(isolate, trx, p.vertices[j]));
|
||||||
p.vertices[j]));
|
|
||||||
}
|
}
|
||||||
for (uint32_t j = 0; j < en; ++j) {
|
for (uint32_t j = 0; j < en; ++j) {
|
||||||
edges->Set(
|
edges->Set(j, EdgeIdToData(isolate, trx, p.edges[j]));
|
||||||
j, EdgeIdToData(isolate, resolver, trx.get(), ditches, p.edges[j]));
|
|
||||||
}
|
}
|
||||||
trx->finish(TRI_ERROR_NO_ERROR);
|
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t j = 0; j < vn; ++j) {
|
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) {
|
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);
|
return scope.Escape<v8::Value>(result);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Transforms an ConstDistanceFinder::Path to v8 json values
|
/// @brief Transforms an ConstDistanceFinder::Path to v8 json values
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/*
|
|
||||||
static v8::Handle<v8::Value> PathIdsToV8(
|
static v8::Handle<v8::Value> PathIdsToV8(
|
||||||
v8::Isolate* isolate, TRI_vocbase_t* vocbase,
|
v8::Isolate* isolate, TRI_vocbase_t* vocbase, arangodb::Transaction* trx,
|
||||||
CollectionNameResolver const* resolver,
|
ArangoDBConstDistancePathFinder::Path const& p, bool& includeData) {
|
||||||
ArangoDBConstDistancePathFinder::Path const& p,
|
|
||||||
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo>& ditches,
|
|
||||||
bool& includeData) {
|
|
||||||
v8::EscapableHandleScope scope(isolate);
|
v8::EscapableHandleScope scope(isolate);
|
||||||
v8::Handle<v8::Object> result = v8::Object::New(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));
|
v8::Handle<v8::Array> edges = v8::Array::New(isolate, static_cast<int>(en));
|
||||||
|
|
||||||
if (includeData) {
|
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) {
|
for (uint32_t j = 0; j < vn; ++j) {
|
||||||
vertices->Set(j, VertexIdToData(isolate, resolver, trx.get(), ditches,
|
vertices->Set(j, VertexIdToData(isolate, trx, p.vertices[j]));
|
||||||
p.vertices[j]));
|
|
||||||
}
|
}
|
||||||
for (uint32_t j = 0; j < en; ++j) {
|
for (uint32_t j = 0; j < en; ++j) {
|
||||||
edges->Set(
|
edges->Set(j, EdgeIdToData(isolate, trx, p.edges[j]));
|
||||||
j, EdgeIdToData(isolate, resolver, trx.get(), ditches, p.edges[j]));
|
|
||||||
}
|
}
|
||||||
trx->finish(TRI_ERROR_NO_ERROR);
|
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t j = 0; j < vn; ++j) {
|
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) {
|
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);
|
return scope.Escape<v8::Value>(result);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Extract collection names from v8 array.
|
/// @brief Extract collection names from v8 array.
|
||||||
|
@ -2076,12 +1923,6 @@ class AttributeWeightCalculator {
|
||||||
|
|
||||||
static void JS_QueryShortestPath(
|
static void JS_QueryShortestPath(
|
||||||
v8::FunctionCallbackInfo<v8::Value> const& args) {
|
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);
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
||||||
v8::HandleScope scope(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);
|
auto transactionContext = std::make_shared<V8TransactionContext>(vocbase, true);
|
||||||
|
|
||||||
int res = TRI_ERROR_NO_ERROR;
|
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) {
|
for (auto const& it : edgeCollectionNames) {
|
||||||
readCollections.emplace_back(resolver->getCollectionIdLocal(it));
|
readCollections.emplace_back(it);
|
||||||
}
|
}
|
||||||
for (auto const& it : vertexCollectionNames) {
|
for (auto const& it : vertexCollectionNames) {
|
||||||
readCollections.emplace_back(resolver->getCollectionIdLocal(it));
|
readCollections.emplace_back(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the transaction and order ditches
|
// Start the transaction and order ditches
|
||||||
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo> ditches;
|
|
||||||
std::unique_ptr<ExplicitTransaction> trx;
|
std::unique_ptr<ExplicitTransaction> trx;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
trx.reset(BeginTransaction(transactionContext, readCollections, writeCollections,
|
trx.reset(BeginTransaction(transactionContext, readCollections,
|
||||||
resolver, ditches));
|
writeCollections));
|
||||||
} catch (Exception& e) {
|
} catch (Exception& e) {
|
||||||
TRI_V8_THROW_EXCEPTION(e.code());
|
TRI_V8_THROW_EXCEPTION(e.code());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<EdgeCollectionInfo*> edgeCollectionInfos;
|
std::vector<EdgeCollectionInfo*> edgeCollectionInfos;
|
||||||
std::vector<VertexCollectionInfo*> vertexCollectionInfos;
|
|
||||||
|
|
||||||
arangodb::basics::ScopeGuard guard{
|
arangodb::basics::ScopeGuard guard{
|
||||||
[]() -> void {},
|
[]() -> void {},
|
||||||
[&edgeCollectionInfos, &vertexCollectionInfos]() -> void {
|
[&edgeCollectionInfos]() -> void {
|
||||||
for (auto& p : edgeCollectionInfos) {
|
for (auto& p : edgeCollectionInfos) {
|
||||||
delete p;
|
delete p;
|
||||||
}
|
}
|
||||||
for (auto& p : vertexCollectionInfos) {
|
|
||||||
delete p;
|
|
||||||
}
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
if (opts.useWeight) {
|
if (opts.useWeight) {
|
||||||
for (auto const& it : edgeCollectionNames) {
|
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(
|
edgeCollectionInfos.emplace_back(new EdgeCollectionInfo(
|
||||||
trx.get(), cid, colObj,
|
trx.get(), it,
|
||||||
AttributeWeightCalculator(opts.weightAttribute, opts.defaultWeight,
|
AttributeWeightCalculator(opts.weightAttribute, opts.defaultWeight)));
|
||||||
colObj->getShaper())));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto const& it : edgeCollectionNames) {
|
for (auto const& it : edgeCollectionNames) {
|
||||||
auto cid = resolver->getCollectionIdLocal(it);
|
edgeCollectionInfos.emplace_back(
|
||||||
TRI_document_collection_t* colObj = ditches.find(cid)->second.col;
|
new EdgeCollectionInfo(trx.get(), it, HopWeightCalculator()));
|
||||||
edgeCollectionInfos.emplace_back(new EdgeCollectionInfo(
|
|
||||||
trx.get(), cid, colObj, 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) {
|
if (opts.useEdgeFilter) {
|
||||||
std::string errorMessage;
|
std::string errorMessage;
|
||||||
for (auto const& it : edgeCollectionInfos) {
|
for (auto const& it : edgeCollectionInfos) {
|
||||||
try {
|
try {
|
||||||
opts.addEdgeFilter(isolate, edgeExample, it->getShaper(), it->getCid(),
|
opts.addEdgeFilter(isolate, edgeExample, it->getName(), errorMessage);
|
||||||
errorMessage);
|
|
||||||
} catch (Exception& e) {
|
} catch (Exception& e) {
|
||||||
// ELEMENT not found is expected, if there is no shape of this type in
|
// ELEMENT not found is expected, if there is no shape of this type in
|
||||||
// this collection
|
// this collection
|
||||||
|
@ -2276,10 +2098,9 @@ static void JS_QueryShortestPath(
|
||||||
|
|
||||||
if (opts.useVertexFilter) {
|
if (opts.useVertexFilter) {
|
||||||
std::string errorMessage;
|
std::string errorMessage;
|
||||||
for (auto const& it : vertexCollectionInfos) {
|
for (auto const& it : vertexCollectionNames) {
|
||||||
try {
|
try {
|
||||||
opts.addVertexFilter(isolate, vertexExample, trx.get(),
|
opts.addVertexFilter(isolate, vertexExample, trx.get(), it,
|
||||||
it->getCollection(), it->getShaper(), it->getCid(),
|
|
||||||
errorMessage);
|
errorMessage);
|
||||||
} catch (Exception& e) {
|
} catch (Exception& e) {
|
||||||
// ELEMENT not found is expected, if there is no shape of this type in
|
// ELEMENT not found is expected, if there is no shape of this type in
|
||||||
|
@ -2292,8 +2113,8 @@ static void JS_QueryShortestPath(
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
opts.start = IdStringToVertexId(resolver, startVertex);
|
opts.start = startVertex;
|
||||||
opts.end = IdStringToVertexId(resolver, targetVertex);
|
opts.end = targetVertex;
|
||||||
} catch (Exception& e) {
|
} catch (Exception& e) {
|
||||||
// Id string might have illegal collection name
|
// Id string might have illegal collection name
|
||||||
trx->finish(e.code());
|
trx->finish(e.code());
|
||||||
|
@ -2318,19 +2139,9 @@ static void JS_QueryShortestPath(
|
||||||
TRI_V8_RETURN(scope.Escape<v8::Value>(v8::Null(isolate)));
|
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 {
|
try {
|
||||||
auto result =
|
auto result = PathIdsToV8(isolate, vocbase, trx.get(), *path, includeData);
|
||||||
PathIdsToV8(isolate, vocbase, resolver, *path, ditches, includeData);
|
|
||||||
TRI_V8_RETURN(result);
|
TRI_V8_RETURN(result);
|
||||||
} catch (Exception& e) {
|
} catch (Exception& e) {
|
||||||
TRI_V8_THROW_EXCEPTION(e.code());
|
TRI_V8_THROW_EXCEPTION(e.code());
|
||||||
|
@ -2354,26 +2165,15 @@ static void JS_QueryShortestPath(
|
||||||
TRI_V8_RETURN(scope.Escape<v8::Value>(v8::Null(isolate)));
|
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 {
|
try {
|
||||||
auto result =
|
auto result = PathIdsToV8(isolate, vocbase, trx.get(), *path, includeData);
|
||||||
PathIdsToV8(isolate, vocbase, resolver, *path, ditches, includeData);
|
|
||||||
TRI_V8_RETURN(result);
|
TRI_V8_RETURN(result);
|
||||||
} catch (Exception& e) {
|
} catch (Exception& e) {
|
||||||
TRI_V8_THROW_EXCEPTION(e.code());
|
TRI_V8_THROW_EXCEPTION(e.code());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
trx->finish(res);
|
||||||
TRI_V8_TRY_CATCH_END
|
TRI_V8_TRY_CATCH_END
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -2382,8 +2182,7 @@ static void JS_QueryShortestPath(
|
||||||
|
|
||||||
static v8::Handle<v8::Value> VertexIdsToV8(
|
static v8::Handle<v8::Value> VertexIdsToV8(
|
||||||
v8::Isolate* isolate, ExplicitTransaction* trx,
|
v8::Isolate* isolate, ExplicitTransaction* trx,
|
||||||
CollectionNameResolver const* resolver, std::unordered_set<std::string>& ids,
|
std::unordered_set<std::string>& ids,
|
||||||
std::unordered_map<TRI_voc_cid_t, CollectionDitchInfo>& ditches,
|
|
||||||
bool includeData = false) {
|
bool includeData = false) {
|
||||||
v8::EscapableHandleScope scope(isolate);
|
v8::EscapableHandleScope scope(isolate);
|
||||||
uint32_t const vn = static_cast<uint32_t>(ids.size());
|
uint32_t const vn = static_cast<uint32_t>(ids.size());
|
||||||
|
@ -2398,7 +2197,7 @@ static v8::Handle<v8::Value> VertexIdsToV8(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto& it : ids) {
|
for (auto& it : ids) {
|
||||||
vertices->Set(j, VertexIdToString(isolate, it));
|
vertices->Set(j, TRI_V8_STD_STRING(it));
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2519,43 +2318,37 @@ static void JS_QueryNeighbors(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TRI_voc_cid_t> readCollections;
|
std::vector<std::string> readCollections;
|
||||||
std::vector<TRI_voc_cid_t> writeCollections;
|
std::vector<std::string> writeCollections;
|
||||||
|
|
||||||
auto transactionContext = std::make_shared<V8TransactionContext>(vocbase, true);
|
auto transactionContext = std::make_shared<V8TransactionContext>(vocbase, true);
|
||||||
|
|
||||||
int res = TRI_ERROR_NO_ERROR;
|
int res = TRI_ERROR_NO_ERROR;
|
||||||
CollectionNameResolver const* resolver = transactionContext->getResolver();
|
|
||||||
|
|
||||||
for (auto const& it : edgeCollectionNames) {
|
for (auto const& it : edgeCollectionNames) {
|
||||||
readCollections.emplace_back(resolver->getCollectionIdLocal(it));
|
readCollections.emplace_back(it);
|
||||||
}
|
}
|
||||||
for (auto const& it : vertexCollectionNames) {
|
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;
|
std::unique_ptr<ExplicitTransaction> trx;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
trx.reset(BeginTransaction(transactionContext, readCollections, writeCollections,
|
trx.reset(BeginTransaction(transactionContext, readCollections,
|
||||||
resolver, ditches));
|
writeCollections));
|
||||||
} catch (Exception& e) {
|
} catch (Exception& e) {
|
||||||
TRI_V8_THROW_EXCEPTION(e.code());
|
TRI_V8_THROW_EXCEPTION(e.code());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<EdgeCollectionInfo*> edgeCollectionInfos;
|
std::vector<EdgeCollectionInfo*> edgeCollectionInfos;
|
||||||
std::vector<VertexCollectionInfo*> vertexCollectionInfos;
|
|
||||||
|
|
||||||
arangodb::basics::ScopeGuard guard{
|
arangodb::basics::ScopeGuard guard{
|
||||||
[]() -> void {},
|
[]() -> void {},
|
||||||
[&edgeCollectionInfos, &vertexCollectionInfos]() -> void {
|
[&edgeCollectionInfos]() -> void {
|
||||||
for (auto& p : edgeCollectionInfos) {
|
for (auto& p : edgeCollectionInfos) {
|
||||||
delete p;
|
delete p;
|
||||||
}
|
}
|
||||||
for (auto& p : vertexCollectionInfos) {
|
|
||||||
delete p;
|
|
||||||
}
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
for (auto const& it : edgeCollectionNames) {
|
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;
|
std::unordered_set<std::string> neighbors;
|
||||||
|
|
||||||
if (opts.useEdgeFilter) {
|
if (opts.useEdgeFilter) {
|
||||||
|
@ -2596,10 +2378,9 @@ static void JS_QueryNeighbors(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
|
|
||||||
if (opts.useVertexFilter) {
|
if (opts.useVertexFilter) {
|
||||||
std::string errorMessage;
|
std::string errorMessage;
|
||||||
for (auto const& it : vertexCollectionInfos) {
|
for (auto const& it : vertexCollectionNames) {
|
||||||
try {
|
try {
|
||||||
opts.addVertexFilter(isolate, vertexExample, trx.get(),
|
opts.addVertexFilter(isolate, vertexExample, trx.get(), it,
|
||||||
it->getCollection(), it->getShaper(), it->getCid(),
|
|
||||||
errorMessage);
|
errorMessage);
|
||||||
} catch (Exception& e) {
|
} catch (Exception& e) {
|
||||||
// ELEMENT not found is expected, if there is no shape of this type in
|
// 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,
|
auto result = VertexIdsToV8(isolate, trx.get(), neighbors, includeData);
|
||||||
includeData);
|
|
||||||
|
|
||||||
trx->finish(res);
|
trx->finish(res);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue