mirror of https://gitee.com/bigwinds/arangodb
Multiple edge collections
This commit is contained in:
parent
9b1a11e68f
commit
6c6c2a092d
|
@ -58,14 +58,14 @@ static IAggregatorCreator* resolveAlgorithm(std::string name,
|
||||||
Conductor::Conductor(
|
Conductor::Conductor(
|
||||||
uint64_t executionNumber, TRI_vocbase_t* vocbase,
|
uint64_t executionNumber, TRI_vocbase_t* vocbase,
|
||||||
std::vector<std::shared_ptr<LogicalCollection>> const& vertexCollections,
|
std::vector<std::shared_ptr<LogicalCollection>> const& vertexCollections,
|
||||||
std::shared_ptr<LogicalCollection> edgeCollection,
|
std::vector<std::shared_ptr<LogicalCollection>> const& edgeCollections,
|
||||||
std::string const& algorithm)
|
std::string const& algorithm)
|
||||||
: _vocbaseGuard(vocbase),
|
: _vocbaseGuard(vocbase),
|
||||||
_executionNumber(executionNumber),
|
_executionNumber(executionNumber),
|
||||||
_algorithm(algorithm),
|
_algorithm(algorithm),
|
||||||
_state(ExecutionState::DEFAULT),
|
_state(ExecutionState::DEFAULT),
|
||||||
_vertexCollections(vertexCollections),
|
_vertexCollections(vertexCollections),
|
||||||
_edgeCollection(edgeCollection) {
|
_edgeCollections(edgeCollections) {
|
||||||
bool isCoordinator = ServerState::instance()->isCoordinator();
|
bool isCoordinator = ServerState::instance()->isCoordinator();
|
||||||
TRI_ASSERT(isCoordinator);
|
TRI_ASSERT(isCoordinator);
|
||||||
LOG(INFO) << "constructed conductor";
|
LOG(INFO) << "constructed conductor";
|
||||||
|
@ -88,7 +88,9 @@ static void printResults(std::vector<ClusterCommRequest> const& requests) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resolveShards(LogicalCollection const* collection,
|
static void resolveShards(LogicalCollection const* collection,
|
||||||
std::map<ServerID, std::vector<ShardID>>& serverMap) {
|
std::map<ServerID, std::map<CollectionID,
|
||||||
|
std::vector<ShardID>>> &serverMap) {
|
||||||
|
|
||||||
ClusterInfo* ci = ClusterInfo::instance();
|
ClusterInfo* ci = ClusterInfo::instance();
|
||||||
std::shared_ptr<std::vector<ShardID>> shardIDs =
|
std::shared_ptr<std::vector<ShardID>> shardIDs =
|
||||||
ci->getShardList(collection->cid_as_string());
|
ci->getShardList(collection->cid_as_string());
|
||||||
|
@ -97,7 +99,7 @@ static void resolveShards(LogicalCollection const* collection,
|
||||||
std::shared_ptr<std::vector<ServerID>> servers =
|
std::shared_ptr<std::vector<ServerID>> servers =
|
||||||
ci->getResponsibleServer(shard);
|
ci->getResponsibleServer(shard);
|
||||||
if (servers->size() > 0) {
|
if (servers->size() > 0) {
|
||||||
serverMap[(*servers)[0]].push_back(shard);
|
serverMap[(*servers)[0]][collection->name()].push_back(shard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,34 +117,38 @@ void Conductor::start(VPackSlice userConfig) {
|
||||||
_aggregatorUsage.reset(new AggregatorUsage(_agregatorCreator.get()));
|
_aggregatorUsage.reset(new AggregatorUsage(_agregatorCreator.get()));
|
||||||
int64_t vertexCount = 0, edgeCount = 0;
|
int64_t vertexCount = 0, edgeCount = 0;
|
||||||
std::map<CollectionID, std::string> collectionPlanIdMap;
|
std::map<CollectionID, std::string> collectionPlanIdMap;
|
||||||
std::map<ServerID, std::vector<ShardID>> edgeServerMap;
|
std::map<ServerID, std::map<CollectionID, std::vector<ShardID>>> vertexMap, edgeMap;
|
||||||
|
|
||||||
|
// resolve plan id's and shards on the servers
|
||||||
for (auto &collection : _vertexCollections) {
|
for (auto &collection : _vertexCollections) {
|
||||||
collectionPlanIdMap[collection->name()] = collection->planId_as_string();
|
collectionPlanIdMap.emplace(collection->name(), collection->planId_as_string());
|
||||||
int64_t cc =
|
int64_t cc =
|
||||||
Utils::countDocuments(_vocbaseGuard.vocbase(), collection->name());
|
Utils::countDocuments(_vocbaseGuard.vocbase(), collection->name());
|
||||||
if (cc > 0) {
|
if (cc > 0) {
|
||||||
vertexCount += cc;
|
vertexCount += cc;
|
||||||
resolveShards(collection.get(), _vertexServerMap);
|
resolveShards(collection.get(), vertexMap);
|
||||||
} else {
|
|
||||||
LOG(WARN) << "Collection does not contain vertices";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
edgeCount =
|
for (auto &collection : _edgeCollections) {
|
||||||
Utils::countDocuments(_vocbaseGuard.vocbase(), _edgeCollection->name());
|
collectionPlanIdMap.emplace(collection->name(), collection->planId_as_string());
|
||||||
if (edgeCount > 0) {
|
int64_t cc =
|
||||||
resolveShards(_edgeCollection.get(), edgeServerMap);
|
Utils::countDocuments(_vocbaseGuard.vocbase(), collection->name());
|
||||||
} else {
|
if (cc > 0) {
|
||||||
LOG(WARN) << "Collection does not contain edges";
|
edgeCount += cc;
|
||||||
|
resolveShards(collection.get(), edgeMap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
for (auto const& pair : vertexMap) {
|
||||||
|
_dbServers.push_back(pair.first);
|
||||||
|
}
|
||||||
|
|
||||||
std::string const baseUrl = Utils::baseUrl(_vocbaseGuard.vocbase()->name());
|
std::string const baseUrl = Utils::baseUrl(_vocbaseGuard.vocbase()->name());
|
||||||
_globalSuperstep = 0;
|
_globalSuperstep = 0;
|
||||||
_state = ExecutionState::RUNNING;
|
_state = ExecutionState::RUNNING;
|
||||||
_dbServerCount = _vertexServerMap.size();
|
_dbServerCount = _dbServers.size();
|
||||||
_responseCount = 0;
|
_responseCount = 0;
|
||||||
_doneCount = 0;
|
_doneCount = 0;
|
||||||
if (_vertexServerMap.size() != edgeServerMap.size()) {
|
if (vertexMap.size() != edgeMap.size()) {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||||
TRI_ERROR_BAD_PARAMETER,
|
TRI_ERROR_BAD_PARAMETER,
|
||||||
"Vertex and edge collections are not sharded correctly");
|
"Vertex and edge collections are not sharded correctly");
|
||||||
|
@ -151,7 +157,11 @@ void Conductor::start(VPackSlice userConfig) {
|
||||||
std::string coordinatorId = ServerState::instance()->getId();
|
std::string coordinatorId = ServerState::instance()->getId();
|
||||||
LOG(INFO) << "My id: " << coordinatorId;
|
LOG(INFO) << "My id: " << coordinatorId;
|
||||||
std::vector<ClusterCommRequest> requests;
|
std::vector<ClusterCommRequest> requests;
|
||||||
for (auto const& it : _vertexServerMap) {
|
for (auto const& it : vertexMap) {
|
||||||
|
ServerID const& server = it.first;
|
||||||
|
std::map<CollectionID, std::vector<ShardID>> const& vertexShardMap = it.second;
|
||||||
|
std::map<CollectionID, std::vector<ShardID>> const& edgeShardMap = edgeMap[it.first];
|
||||||
|
|
||||||
VPackBuilder b;
|
VPackBuilder b;
|
||||||
b.openObject();
|
b.openObject();
|
||||||
b.add(Utils::executionNumberKey, VPackValue(_executionNumber));
|
b.add(Utils::executionNumberKey, VPackValue(_executionNumber));
|
||||||
|
@ -161,18 +171,24 @@ void Conductor::start(VPackSlice userConfig) {
|
||||||
b.add(Utils::coordinatorIdKey, VPackValue(coordinatorId));
|
b.add(Utils::coordinatorIdKey, VPackValue(coordinatorId));
|
||||||
b.add(Utils::totalVertexCount, VPackValue(vertexCount));
|
b.add(Utils::totalVertexCount, VPackValue(vertexCount));
|
||||||
b.add(Utils::totalEdgeCount, VPackValue(edgeCount));
|
b.add(Utils::totalEdgeCount, VPackValue(edgeCount));
|
||||||
b.add(Utils::vertexShardsListKey, VPackValue(VPackValueType::Array));
|
b.add(Utils::vertexShardsKey, VPackValue(VPackValueType::Object));
|
||||||
for (ShardID const& vit : it.second) {
|
for (auto const& pair : vertexShardMap) {
|
||||||
b.add(VPackValue(vit));
|
b.add(pair.first, VPackValue(VPackValueType::Array));
|
||||||
|
for (ShardID const& shard : pair.second) {
|
||||||
|
b.add(VPackValue(shard));
|
||||||
|
}
|
||||||
|
b.close();
|
||||||
}
|
}
|
||||||
b.close();
|
b.close();
|
||||||
b.add(Utils::edgeShardsListKey, VPackValue(VPackValueType::Array));
|
b.add(Utils::edgeShardsKey, VPackValue(VPackValueType::Object));
|
||||||
for (ShardID const& eit : edgeServerMap[it.first]) {
|
for (auto const& pair : edgeShardMap) {
|
||||||
b.add(VPackValue(eit));
|
b.add(pair.first, VPackValue(VPackValueType::Array));
|
||||||
|
for (ShardID const& shard : pair.second) {
|
||||||
|
b.add(VPackValue(shard));
|
||||||
|
}
|
||||||
|
b.close();
|
||||||
}
|
}
|
||||||
b.close();
|
b.close();
|
||||||
b.add(Utils::edgeCollectionPlanIdKey,
|
|
||||||
VPackValue(_edgeCollection->planId_as_string()));
|
|
||||||
b.add(Utils::collectionPlanIdMapKey, VPackValue(VPackValueType::Object));
|
b.add(Utils::collectionPlanIdMapKey, VPackValue(VPackValueType::Object));
|
||||||
for (auto const& pair : collectionPlanIdMap) {
|
for (auto const& pair : collectionPlanIdMap) {
|
||||||
b.add(pair.first, VPackValue(pair.second));
|
b.add(pair.first, VPackValue(pair.second));
|
||||||
|
@ -181,7 +197,7 @@ void Conductor::start(VPackSlice userConfig) {
|
||||||
b.close();
|
b.close();
|
||||||
|
|
||||||
auto body = std::make_shared<std::string const>(b.toJson());
|
auto body = std::make_shared<std::string const>(b.toJson());
|
||||||
requests.emplace_back("server:" + it.first, rest::RequestType::POST,
|
requests.emplace_back("server:" + server, rest::RequestType::POST,
|
||||||
baseUrl + Utils::startExecutionPath, body);
|
baseUrl + Utils::startExecutionPath, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +309,7 @@ void Conductor::cancel() { _state = ExecutionState::CANCELED; }
|
||||||
|
|
||||||
int Conductor::sendToAllDBServers(std::string path, VPackSlice const& config) {
|
int Conductor::sendToAllDBServers(std::string path, VPackSlice const& config) {
|
||||||
ClusterComm* cc = ClusterComm::instance();
|
ClusterComm* cc = ClusterComm::instance();
|
||||||
_dbServerCount = _vertexServerMap.size();
|
_dbServerCount = _dbServers.size();
|
||||||
_responseCount = 0;
|
_responseCount = 0;
|
||||||
_doneCount = 0;
|
_doneCount = 0;
|
||||||
|
|
||||||
|
@ -304,8 +320,8 @@ int Conductor::sendToAllDBServers(std::string path, VPackSlice const& config) {
|
||||||
|
|
||||||
auto body = std::make_shared<std::string const>(config.toJson());
|
auto body = std::make_shared<std::string const>(config.toJson());
|
||||||
std::vector<ClusterCommRequest> requests;
|
std::vector<ClusterCommRequest> requests;
|
||||||
for (auto const& it : _vertexServerMap) {
|
for (auto const& server : _dbServers) {
|
||||||
requests.emplace_back("server:" + it.first, rest::RequestType::POST, path,
|
requests.emplace_back("server:" + server, rest::RequestType::POST, path,
|
||||||
body);
|
body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,12 @@ class Conductor {
|
||||||
const std::string _algorithm;
|
const std::string _algorithm;
|
||||||
ExecutionState _state;
|
ExecutionState _state;
|
||||||
std::vector<std::shared_ptr<LogicalCollection>> _vertexCollections;
|
std::vector<std::shared_ptr<LogicalCollection>> _vertexCollections;
|
||||||
std::shared_ptr<LogicalCollection> _edgeCollection;
|
std::vector<std::shared_ptr<LogicalCollection>> _edgeCollections;
|
||||||
|
std::vector<ServerID> _dbServers;
|
||||||
|
|
||||||
// initialized on startup
|
// initialized on startup
|
||||||
std::unique_ptr<IAggregatorCreator> _agregatorCreator;
|
std::unique_ptr<IAggregatorCreator> _agregatorCreator;
|
||||||
std::unique_ptr<AggregatorUsage> _aggregatorUsage;
|
std::unique_ptr<AggregatorUsage> _aggregatorUsage;
|
||||||
std::map<ServerID, std::vector<ShardID>> _vertexServerMap;
|
|
||||||
|
|
||||||
uint64_t _globalSuperstep = 0;
|
uint64_t _globalSuperstep = 0;
|
||||||
int32_t _dbServerCount = 0;
|
int32_t _dbServerCount = 0;
|
||||||
|
@ -69,7 +69,7 @@ class Conductor {
|
||||||
public:
|
public:
|
||||||
Conductor(uint64_t executionNumber, TRI_vocbase_t* vocbase,
|
Conductor(uint64_t executionNumber, TRI_vocbase_t* vocbase,
|
||||||
std::vector<std::shared_ptr<LogicalCollection>> const& vertexCollections,
|
std::vector<std::shared_ptr<LogicalCollection>> const& vertexCollections,
|
||||||
std::shared_ptr<LogicalCollection> edgeCollection,
|
std::vector<std::shared_ptr<LogicalCollection>> const& edgeCollections,
|
||||||
std::string const& algorithm);
|
std::string const& algorithm);
|
||||||
~Conductor();
|
~Conductor();
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "Indexes/Index.h"
|
#include "Indexes/Index.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Utils/OperationCursor.h"
|
#include "Utils/OperationCursor.h"
|
||||||
#include "Utils/SingleCollectionTransaction.h"
|
#include "Utils/ExplicitTransaction.h"
|
||||||
#include "Utils/StandaloneTransactionContext.h"
|
#include "Utils/StandaloneTransactionContext.h"
|
||||||
#include "Utils/Transaction.h"
|
#include "Utils/Transaction.h"
|
||||||
#include "VocBase/EdgeCollectionInfo.h"
|
#include "VocBase/EdgeCollectionInfo.h"
|
||||||
|
@ -41,16 +41,49 @@ using namespace arangodb;
|
||||||
using namespace arangodb::pregel;
|
using namespace arangodb::pregel;
|
||||||
|
|
||||||
template <typename V, typename E>
|
template <typename V, typename E>
|
||||||
GraphStore<V, E>::GraphStore(TRI_vocbase_t* vocbase, const WorkerState* state,
|
GraphStore<V, E>::GraphStore(TRI_vocbase_t* vb, const WorkerState* state,
|
||||||
GraphFormat<V, E>* graphFormat)
|
GraphFormat<V, E>* graphFormat)
|
||||||
: _vocbaseGuard(vocbase), _workerState(state), _graphFormat(graphFormat) {
|
: _vocbaseGuard(vb), _workerState(state), _graphFormat(graphFormat) {
|
||||||
_edgeCollection = ClusterInfo::instance()->getCollection(
|
// _edgeCollection = ClusterInfo::instance()->getCollection(
|
||||||
vocbase->name(), state->edgeCollectionPlanId());
|
// vb->name(), state->edgeCollectionPlanId());
|
||||||
|
std::vector<std::string> readColls, writeColls;
|
||||||
|
for (auto const& pair : state->vertexCollectionShards()) {
|
||||||
|
for (auto const& shard : pair.second) {
|
||||||
|
readColls.push_back(shard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto const& pair : state->edgeCollectionShards()) {
|
||||||
|
for (auto const& shard : pair.second) {
|
||||||
|
readColls.push_back(shard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double lockTimeout =
|
||||||
|
(double)(TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
|
||||||
|
_transaction = new ExplicitTransaction(StandaloneTransactionContext::Create(_vocbaseGuard.vocbase()),
|
||||||
|
readColls, writeColls,
|
||||||
|
lockTimeout, false, false);
|
||||||
|
int res = _transaction->begin();
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
THROW_ARANGO_EXCEPTION(res);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& shard : state->localVertexShardIDs()) {
|
std::map<CollectionID, std::vector<ShardID>> const& vertexMap = state->vertexCollectionShards();
|
||||||
loadVertices(shard);
|
std::map<CollectionID, std::vector<ShardID>> const& edgeMap = state->edgeCollectionShards();
|
||||||
|
for (auto const& pair : vertexMap) {
|
||||||
|
std::vector<ShardID> const& vertexShards = pair.second;
|
||||||
|
for (size_t i = 0; i < vertexShards.size(); i++) {
|
||||||
|
// distributeshardslike should cause the edges for a vertex to be
|
||||||
|
// in the same shard index. x in vertexShard2 => E(x) in edgeShard2
|
||||||
|
for (auto const& pair2 : edgeMap) {
|
||||||
|
std::vector<ShardID> const& edgeShards = pair2.second;
|
||||||
|
TRI_ASSERT(vertexShards.size() == edgeShards.size());
|
||||||
|
loadVertices(vertexShards[i], edgeShards[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cleanupTransactions();
|
cleanupTransactions();
|
||||||
|
|
||||||
|
LOG(INFO) << "Loaded " << _index.size() << "vertices and " << _edges.size() << " edges";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename V, typename E>
|
template <typename V, typename E>
|
||||||
|
@ -88,7 +121,7 @@ RangeIterator<EdgeEntry<E>> GraphStore<V, E>::edgeIterator(VertexEntry const* en
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
template <typename V, typename E>
|
template <typename V, typename E>
|
||||||
SingleCollectionTransaction* GraphStore<V, E>::readTransaction(ShardID const& shard) {
|
SingleCollectionTransaction* GraphStore<V, E>::readTransaction(ShardID const& shard) {
|
||||||
auto it = _transactions.find(shard);
|
auto it = _transactions.find(shard);
|
||||||
|
@ -106,11 +139,11 @@ SingleCollectionTransaction* GraphStore<V, E>::readTransaction(ShardID const& sh
|
||||||
_transactions[shard] = trx.get();
|
_transactions[shard] = trx.get();
|
||||||
return trx.release();
|
return trx.release();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
template <typename V, typename E>
|
template <typename V, typename E>
|
||||||
void GraphStore<V, E>::cleanupTransactions() {
|
void GraphStore<V, E>::cleanupTransactions() {
|
||||||
for (auto const& it : _transactions) { // clean transactions
|
/*for (auto const& it : _transactions) { // clean transactions
|
||||||
if (it.second->getStatus() == TRI_TRANSACTION_RUNNING) {
|
if (it.second->getStatus() == TRI_TRANSACTION_RUNNING) {
|
||||||
if (it.second->commit() != TRI_ERROR_NO_ERROR) {
|
if (it.second->commit() != TRI_ERROR_NO_ERROR) {
|
||||||
LOG(WARN) << "Pregel worker: Failed to commit on a read transaction";
|
LOG(WARN) << "Pregel worker: Failed to commit on a read transaction";
|
||||||
|
@ -118,36 +151,35 @@ void GraphStore<V, E>::cleanupTransactions() {
|
||||||
}
|
}
|
||||||
delete (it.second);
|
delete (it.second);
|
||||||
}
|
}
|
||||||
_transactions.clear();
|
_transactions.clear();*/
|
||||||
|
if (_transaction) {
|
||||||
|
if (_transaction->getStatus() == TRI_TRANSACTION_RUNNING) {
|
||||||
|
if (_transaction->commit() != TRI_ERROR_NO_ERROR) {
|
||||||
|
LOG(WARN) << "Pregel worker: Failed to commit on a read transaction";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete _transaction;
|
||||||
|
_transaction = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename V, typename E>
|
template <typename V, typename E>
|
||||||
void GraphStore<V, E>::loadVertices(ShardID const& vertexShard) {
|
void GraphStore<V, E>::loadVertices(ShardID const& vertexShard, ShardID const& edgeShard) {
|
||||||
//_graphFormat->willUseCollection(vocbase, vertexShard, false);
|
//_graphFormat->willUseCollection(vocbase, vertexShard, false);
|
||||||
bool storeData = _graphFormat->storesVertexData();
|
bool storeData = _graphFormat->storesVertexData();
|
||||||
|
|
||||||
SingleCollectionTransaction trx(
|
TRI_voc_cid_t cid = _transaction->addCollectionAtRuntime(vertexShard);
|
||||||
StandaloneTransactionContext::Create(_vocbaseGuard.vocbase()),
|
_transaction->orderDitch(cid); // will throw when it fails
|
||||||
vertexShard, TRI_TRANSACTION_READ);
|
|
||||||
|
|
||||||
int res = trx.begin();
|
/*int res = _transaction->lockRead();
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
THROW_ARANGO_EXCEPTION_FORMAT(res, "while looking up vertices '%s'",
|
THROW_ARANGO_EXCEPTION_FORMAT(res, "while looking up vertices '%s'",
|
||||||
vertexShard.c_str());
|
vertexShard.c_str());
|
||||||
}
|
}*/
|
||||||
|
|
||||||
TRI_voc_cid_t cid = trx.addCollectionAtRuntime(vertexShard);
|
ManagedDocumentResult mmdr(_transaction);
|
||||||
trx.orderDitch(cid); // will throw when it fails
|
std::unique_ptr<OperationCursor> cursor = _transaction->indexScan(
|
||||||
|
|
||||||
res = trx.lockRead();
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
|
||||||
THROW_ARANGO_EXCEPTION_FORMAT(res, "while looking up vertices '%s'",
|
|
||||||
vertexShard.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
ManagedDocumentResult mmdr(&trx);
|
|
||||||
std::unique_ptr<OperationCursor> cursor = trx.indexScan(
|
|
||||||
vertexShard, Transaction::CursorType::ALL, Transaction::IndexHandle(), {},
|
vertexShard, Transaction::CursorType::ALL, Transaction::IndexHandle(), {},
|
||||||
&mmdr, 0, UINT64_MAX, 1000, false);
|
&mmdr, 0, UINT64_MAX, 1000, false);
|
||||||
|
|
||||||
|
@ -164,7 +196,7 @@ void GraphStore<V, E>::loadVertices(ShardID const& vertexShard) {
|
||||||
cursor->getMoreMptr(result, 1000);
|
cursor->getMoreMptr(result, 1000);
|
||||||
for (auto const& element : result) {
|
for (auto const& element : result) {
|
||||||
TRI_voc_rid_t revisionId = element.revisionId();
|
TRI_voc_rid_t revisionId = element.revisionId();
|
||||||
if (collection->readRevision(&trx, mmdr, revisionId)) {
|
if (collection->readRevision(_transaction, mmdr, revisionId)) {
|
||||||
VPackSlice document(mmdr.vpack());
|
VPackSlice document(mmdr.vpack());
|
||||||
if (document.isExternal()) {
|
if (document.isExternal()) {
|
||||||
document = document.resolveExternal();
|
document = document.resolveExternal();
|
||||||
|
@ -172,7 +204,7 @@ void GraphStore<V, E>::loadVertices(ShardID const& vertexShard) {
|
||||||
|
|
||||||
LOG(INFO) << "Loaded Vertex: " << document.toJson();
|
LOG(INFO) << "Loaded Vertex: " << document.toJson();
|
||||||
|
|
||||||
std::string vertexId = trx.extractIdString(document);
|
std::string vertexId = _transaction->extractIdString(document);
|
||||||
VertexEntry entry(vertexId);
|
VertexEntry entry(vertexId);
|
||||||
if (storeData) {
|
if (storeData) {
|
||||||
V vertexData;
|
V vertexData;
|
||||||
|
@ -185,42 +217,44 @@ void GraphStore<V, E>::loadVertices(ShardID const& vertexShard) {
|
||||||
LOG(ERR) << "Could not load vertex " << document.toJson();
|
LOG(ERR) << "Could not load vertex " << document.toJson();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadEdges(entry);
|
|
||||||
|
loadEdges(edgeShard, entry);
|
||||||
_index.push_back(entry);
|
_index.push_back(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = trx.unlockRead();
|
/*res = trx.unlockRead();
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
THROW_ARANGO_EXCEPTION_FORMAT(res, "while looking up shard '%s'",
|
THROW_ARANGO_EXCEPTION_FORMAT(res, "while looking up shard '%s'",
|
||||||
vertexShard.c_str());
|
vertexShard.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
//_shardsPlanIdMap[vertexShard] =
|
|
||||||
// trx.documentCollection()->planId_as_string();
|
|
||||||
res = trx.finish(res);
|
res = trx.finish(res);
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
THROW_ARANGO_EXCEPTION_FORMAT(res, "while looking up vertices '%s'",
|
THROW_ARANGO_EXCEPTION_FORMAT(res, "while looking up vertices '%s'",
|
||||||
vertexShard.c_str());
|
vertexShard.c_str());
|
||||||
}
|
}//*/
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename V, typename E>
|
template <typename V, typename E>
|
||||||
void GraphStore<V, E>::loadEdges(VertexEntry& vertexEntry) {
|
void GraphStore<V, E>::loadEdges(ShardID const& shard, VertexEntry& vertexEntry) {
|
||||||
//_graphFormat->willUseCollection(vocbase, edgeShard, true);
|
//_graphFormat->willUseCollection(vocbase, edgeShard, true);
|
||||||
const bool storeData = _graphFormat->storesEdgeData();
|
const bool storeData = _graphFormat->storesEdgeData();
|
||||||
std::string const& _from = vertexEntry.vertexID();
|
std::string const& _from = vertexEntry.vertexID();
|
||||||
const std::string _key = Utils::vertexKeyFromToValue(_from);
|
const std::string _key = Utils::vertexKeyFromToValue(_from);
|
||||||
ShardID shard;
|
|
||||||
Utils::resolveShard(_edgeCollection.get(), Utils::edgeShardingKey, _key,
|
|
||||||
shard);
|
|
||||||
|
|
||||||
SingleCollectionTransaction* trx = readTransaction(shard);
|
/*ShardID shard;
|
||||||
traverser::EdgeCollectionInfo info(trx, shard, TRI_EDGE_OUT,
|
Utils::resolveShard(_edgeCollection.get(), Utils::edgeShardingKey,
|
||||||
|
_key, shard);*/
|
||||||
|
|
||||||
|
//Transaction* trx = readTransaction(shard);
|
||||||
|
traverser::EdgeCollectionInfo info(_transaction, shard, TRI_EDGE_OUT,
|
||||||
StaticStrings::FromString, 0);
|
StaticStrings::FromString, 0);
|
||||||
|
|
||||||
ManagedDocumentResult mmdr(trx);
|
ManagedDocumentResult mmdr(_transaction);
|
||||||
auto cursor = info.getEdges(_from, &mmdr);
|
auto cursor = info.getEdges(_from, &mmdr);
|
||||||
if (cursor->failed()) {
|
if (cursor->failed()) {
|
||||||
THROW_ARANGO_EXCEPTION_FORMAT(cursor->code,
|
THROW_ARANGO_EXCEPTION_FORMAT(cursor->code,
|
||||||
|
@ -240,7 +274,7 @@ void GraphStore<V, E>::loadEdges(VertexEntry& vertexEntry) {
|
||||||
cursor->getMoreMptr(result, 1000);
|
cursor->getMoreMptr(result, 1000);
|
||||||
for (auto const& element : result) {
|
for (auto const& element : result) {
|
||||||
TRI_voc_rid_t revisionId = element.revisionId();
|
TRI_voc_rid_t revisionId = element.revisionId();
|
||||||
if (collection->readRevision(trx, mmdr, revisionId)) {
|
if (collection->readRevision(_transaction, mmdr, revisionId)) {
|
||||||
VPackSlice document(mmdr.vpack());
|
VPackSlice document(mmdr.vpack());
|
||||||
if (document.isExternal()) {
|
if (document.isExternal()) {
|
||||||
document = document.resolveExternal();
|
document = document.resolveExternal();
|
||||||
|
@ -276,7 +310,7 @@ void GraphStore<V, E>::loadEdges(VertexEntry& vertexEntry) {
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename V, typename E>
|
/*template <typename V, typename E>
|
||||||
SingleCollectionTransaction* GraphStore<V, E>::writeTransaction(ShardID const& shard) {
|
SingleCollectionTransaction* GraphStore<V, E>::writeTransaction(ShardID const& shard) {
|
||||||
|
|
||||||
auto it = _transactions.find(shard);
|
auto it = _transactions.find(shard);
|
||||||
|
@ -295,11 +329,28 @@ SingleCollectionTransaction* GraphStore<V, E>::writeTransaction(ShardID const& s
|
||||||
_transactions[shard] = trx.get();
|
_transactions[shard] = trx.get();
|
||||||
return trx.release();
|
return trx.release();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
template <typename V, typename E>
|
template <typename V, typename E>
|
||||||
void GraphStore<V,E>::storeResults() {
|
void GraphStore<V,E>::storeResults() {
|
||||||
|
|
||||||
|
std::vector<std::string> readColls, writeColls;
|
||||||
|
for (auto shard : _workerState->localVertexShardIDs() ) {
|
||||||
|
writeColls.push_back(shard);
|
||||||
|
}
|
||||||
|
//for (auto shard : _workerState->localEdgeShardIDs() ) {
|
||||||
|
// writeColls(shard);
|
||||||
|
//}
|
||||||
|
double lockTimeout =
|
||||||
|
(double)(TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
|
||||||
|
_transaction = new ExplicitTransaction(StandaloneTransactionContext::Create(_vocbaseGuard.vocbase()),
|
||||||
|
readColls, writeColls,
|
||||||
|
lockTimeout, false, false);
|
||||||
|
int res = _transaction->begin();
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
THROW_ARANGO_EXCEPTION(res);
|
||||||
|
}
|
||||||
|
|
||||||
OperationOptions options;
|
OperationOptions options;
|
||||||
for (auto& vertexEntry : _index) {
|
for (auto& vertexEntry : _index) {
|
||||||
|
|
||||||
|
@ -316,7 +367,6 @@ void GraphStore<V,E>::storeResults() {
|
||||||
|
|
||||||
std::string shard;
|
std::string shard;
|
||||||
Utils::resolveShard(collInfo.get(), StaticStrings::KeyString, _key, shard);
|
Utils::resolveShard(collInfo.get(), StaticStrings::KeyString, _key, shard);
|
||||||
SingleCollectionTransaction* trx = writeTransaction(shard);
|
|
||||||
|
|
||||||
void* data = mutableVertexData(&vertexEntry);
|
void* data = mutableVertexData(&vertexEntry);
|
||||||
VPackBuilder b;
|
VPackBuilder b;
|
||||||
|
@ -325,7 +375,7 @@ void GraphStore<V,E>::storeResults() {
|
||||||
_graphFormat->buildVertexDocument(b, data, sizeof(V));
|
_graphFormat->buildVertexDocument(b, data, sizeof(V));
|
||||||
b.close();
|
b.close();
|
||||||
|
|
||||||
OperationResult result = trx->update(shard, b.slice(), options);
|
OperationResult result = _transaction->update(shard, b.slice(), options);
|
||||||
if (result.code != TRI_ERROR_NO_ERROR) {
|
if (result.code != TRI_ERROR_NO_ERROR) {
|
||||||
THROW_ARANGO_EXCEPTION(result.code);
|
THROW_ARANGO_EXCEPTION(result.code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,13 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "Cluster/ClusterInfo.h"
|
#include "Cluster/ClusterInfo.h"
|
||||||
|
#include "VocBase/voc-types.h"
|
||||||
#include "GraphFormat.h"
|
#include "GraphFormat.h"
|
||||||
|
|
||||||
struct TRI_vocbase_t;
|
struct TRI_vocbase_t;
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
class SingleCollectionTransaction;
|
class Transaction;
|
||||||
class LogicalCollection;
|
class LogicalCollection;
|
||||||
namespace pregel {
|
namespace pregel {
|
||||||
|
|
||||||
|
@ -43,6 +44,8 @@ struct EdgeEntry {
|
||||||
// size_t _nextEntryOffset;
|
// size_t _nextEntryOffset;
|
||||||
// size_t _dataSize;
|
// size_t _dataSize;
|
||||||
std::string _toVertexID;
|
std::string _toVertexID;
|
||||||
|
TRI_voc_cid_t sourceShardID;
|
||||||
|
TRI_voc_cid_t targetShardID;
|
||||||
E _data;
|
E _data;
|
||||||
// size_t _vertexIDSize;
|
// size_t _vertexIDSize;
|
||||||
// char _vertexID[1];
|
// char _vertexID[1];
|
||||||
|
@ -246,15 +249,14 @@ class GraphStore {
|
||||||
VocbaseGuard _vocbaseGuard;
|
VocbaseGuard _vocbaseGuard;
|
||||||
const WorkerState* _workerState;
|
const WorkerState* _workerState;
|
||||||
const std::unique_ptr<GraphFormat<V, E>> _graphFormat;
|
const std::unique_ptr<GraphFormat<V, E>> _graphFormat;
|
||||||
std::unordered_map<std::string, SingleCollectionTransaction*> _transactions;
|
|
||||||
std::shared_ptr<LogicalCollection> _edgeCollection;
|
|
||||||
|
|
||||||
SingleCollectionTransaction* readTransaction(ShardID const& shard);
|
Transaction *_transaction;
|
||||||
SingleCollectionTransaction* writeTransaction(ShardID const& shard);
|
//SingleCollectionTransaction* readTransaction(ShardID const& shard);
|
||||||
|
//SingleCollectionTransaction* writeTransaction(ShardID const& shard);
|
||||||
void cleanupTransactions();
|
void cleanupTransactions();
|
||||||
|
|
||||||
void loadVertices(ShardID const& vertexShard);
|
void loadVertices(ShardID const& vertexShard, ShardID const& edgeShard);
|
||||||
void loadEdges(VertexEntry& entry);
|
void loadEdges(ShardID const& edgeShard, VertexEntry& entry);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GraphStore(TRI_vocbase_t* vocbase, const WorkerState* state,
|
GraphStore(TRI_vocbase_t* vocbase, const WorkerState* state,
|
||||||
|
|
|
@ -44,7 +44,7 @@ template <typename M>
|
||||||
class IncomingCache {
|
class IncomingCache {
|
||||||
public:
|
public:
|
||||||
IncomingCache(MessageFormat<M> const* format, MessageCombiner<M> const* combiner)
|
IncomingCache(MessageFormat<M> const* format, MessageCombiner<M> const* combiner)
|
||||||
: _format(format), _combiner(combiner), _receivedMessageCount(0) {}
|
: _receivedMessageCount(0), _format(format), _combiner(combiner) {}
|
||||||
~IncomingCache();
|
~IncomingCache();
|
||||||
|
|
||||||
void parseMessages(VPackSlice messages);
|
void parseMessages(VPackSlice messages);
|
||||||
|
|
|
@ -27,10 +27,7 @@ In arangosh:
|
||||||
|
|
||||||
db._create('vertices', {numberOfShards: 2});
|
db._create('vertices', {numberOfShards: 2});
|
||||||
db._createEdgeCollection('alt_edges');
|
db._createEdgeCollection('alt_edges');
|
||||||
db._createEdgeCollection('edges', {numberOfShards: 2,
|
db._createEdgeCollection('edges', {numberOfShards: 2, shardKeys:["_vertex"], distributeShardsLike:'vertices'});
|
||||||
shardKeys:["_vertex"],
|
|
||||||
distributeShardsLike:'vertices'
|
|
||||||
});
|
|
||||||
|
|
||||||
arangoimp --file generated_vertices.csv --type csv --collection vertices --overwrite true --server.endpoint http+tcp://127.0.0.1:8530
|
arangoimp --file generated_vertices.csv --type csv --collection vertices --overwrite true --server.endpoint http+tcp://127.0.0.1:8530
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,8 @@ std::string const Utils::finalizeExecutionPath = "finalizeExecution";
|
||||||
|
|
||||||
std::string const Utils::executionNumberKey = "exn";
|
std::string const Utils::executionNumberKey = "exn";
|
||||||
std::string const Utils::collectionPlanIdMapKey = "collectionPlanIdMap";
|
std::string const Utils::collectionPlanIdMapKey = "collectionPlanIdMap";
|
||||||
std::string const Utils::edgeCollectionPlanIdKey = "edgePlanId";
|
std::string const Utils::vertexShardsKey = "vertexShards";
|
||||||
std::string const Utils::vertexShardsListKey = "vertexShards";
|
std::string const Utils::edgeShardsKey = "edgeShards";
|
||||||
std::string const Utils::edgeShardsListKey = "edgeShards";
|
|
||||||
|
|
||||||
std::string const Utils::coordinatorIdKey = "coordinatorId";
|
std::string const Utils::coordinatorIdKey = "coordinatorId";
|
||||||
std::string const Utils::algorithmKey = "algorithm";
|
std::string const Utils::algorithmKey = "algorithm";
|
||||||
|
|
|
@ -51,9 +51,8 @@ class Utils {
|
||||||
static std::string const algorithmKey;
|
static std::string const algorithmKey;
|
||||||
static std::string const coordinatorIdKey;
|
static std::string const coordinatorIdKey;
|
||||||
static std::string const collectionPlanIdMapKey;
|
static std::string const collectionPlanIdMapKey;
|
||||||
static std::string const edgeCollectionPlanIdKey;
|
static std::string const vertexShardsKey;
|
||||||
static std::string const vertexShardsListKey;
|
static std::string const edgeShardsKey;
|
||||||
static std::string const edgeShardsListKey;
|
|
||||||
|
|
||||||
static std::string const globalSuperstepKey;
|
static std::string const globalSuperstepKey;
|
||||||
static std::string const messagesKey;
|
static std::string const messagesKey;
|
||||||
|
|
|
@ -31,14 +31,13 @@ using namespace arangodb::pregel;
|
||||||
WorkerState::WorkerState(DatabaseID dbname, VPackSlice params)
|
WorkerState::WorkerState(DatabaseID dbname, VPackSlice params)
|
||||||
: _database(dbname) {
|
: _database(dbname) {
|
||||||
VPackSlice coordID = params.get(Utils::coordinatorIdKey);
|
VPackSlice coordID = params.get(Utils::coordinatorIdKey);
|
||||||
VPackSlice vertexShardIDs = params.get(Utils::vertexShardsListKey);
|
VPackSlice vertexShardMap = params.get(Utils::vertexShardsKey);
|
||||||
VPackSlice edgeShardIDs = params.get(Utils::edgeShardsListKey);
|
VPackSlice edgeShardMap = params.get(Utils::edgeShardsKey);
|
||||||
VPackSlice execNum = params.get(Utils::executionNumberKey);
|
VPackSlice execNum = params.get(Utils::executionNumberKey);
|
||||||
VPackSlice collectionPlanIdMap = params.get(Utils::collectionPlanIdMapKey);
|
VPackSlice collectionPlanIdMap = params.get(Utils::collectionPlanIdMapKey);
|
||||||
VPackSlice edgePlanID = params.get(Utils::edgeCollectionPlanIdKey);
|
if (!coordID.isString() || !edgeShardMap.isObject() ||
|
||||||
if (!coordID.isString() || !vertexShardIDs.isArray() ||
|
!vertexShardMap.isObject() || !execNum.isInteger() ||
|
||||||
!edgeShardIDs.isArray() || !execNum.isInteger() ||
|
!collectionPlanIdMap.isObject()) {
|
||||||
!collectionPlanIdMap.isObject() || !edgePlanID.isString()) {
|
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
||||||
"Supplied bad parameters to worker");
|
"Supplied bad parameters to worker");
|
||||||
}
|
}
|
||||||
|
@ -47,22 +46,25 @@ WorkerState::WorkerState(DatabaseID dbname, VPackSlice params)
|
||||||
//_vertexCollectionName = vertexCollName.copyString();
|
//_vertexCollectionName = vertexCollName.copyString();
|
||||||
//_vertexCollectionPlanId = vertexCollPlanId.copyString();
|
//_vertexCollectionPlanId = vertexCollPlanId.copyString();
|
||||||
|
|
||||||
LOG(INFO) << "Local Shards:";
|
for (auto const& pair : VPackObjectIterator(vertexShardMap)) {
|
||||||
VPackArrayIterator vertices(vertexShardIDs);
|
std::vector<ShardID> shards;
|
||||||
for (VPackSlice shardSlice : vertices) {
|
for (VPackSlice shardSlice : VPackArrayIterator(pair.value)) {
|
||||||
ShardID name = shardSlice.copyString();
|
ShardID shard = shardSlice.copyString();
|
||||||
_localVertexShardIDs.push_back(name);
|
shards.push_back(shard);
|
||||||
LOG(INFO) << name;
|
_localVertexShardIDs.push_back(shard);
|
||||||
|
}
|
||||||
|
_vertexCollectionShards.emplace(pair.key.copyString(), shards);
|
||||||
}
|
}
|
||||||
VPackArrayIterator edges(edgeShardIDs);
|
|
||||||
for (VPackSlice shardSlice : edges) {
|
for (auto const& pair : VPackObjectIterator(edgeShardMap)) {
|
||||||
ShardID name = shardSlice.copyString();
|
std::vector<ShardID> shards;
|
||||||
_localEdgeShardIDs.push_back(name);
|
for (VPackSlice shardSlice : VPackArrayIterator(pair.value)) {
|
||||||
LOG(INFO) << name;
|
shards.push_back(shardSlice.copyString());
|
||||||
|
}
|
||||||
|
_edgeCollectionShards.emplace(pair.key.copyString(), shards);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& it : VPackObjectIterator(collectionPlanIdMap)) {
|
for (auto const& it : VPackObjectIterator(collectionPlanIdMap)) {
|
||||||
_collectionPlanIdMap.emplace(it.key.copyString(), it.value.copyString());
|
_collectionPlanIdMap.emplace(it.key.copyString(), it.value.copyString());
|
||||||
}
|
}
|
||||||
_edgeCollectionPlanId = edgePlanID.copyString();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,21 +52,21 @@ class WorkerState {
|
||||||
|
|
||||||
inline std::string const& database() const { return _database; }
|
inline std::string const& database() const { return _database; }
|
||||||
|
|
||||||
inline std::vector<ShardID> const& localVertexShardIDs() const {
|
inline std::map<CollectionID, std::vector<ShardID>> const& vertexCollectionShards() const {
|
||||||
return _localVertexShardIDs;
|
return _vertexCollectionShards;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::vector<ShardID> const& localEdgeShardIDs() const {
|
inline std::map<CollectionID, std::vector<ShardID>> const& edgeCollectionShards() const {
|
||||||
return _localEdgeShardIDs;
|
return _edgeCollectionShards;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<CollectionID, std::string> const& collectionPlanIdMap() const {
|
inline std::map<CollectionID, std::string> const& collectionPlanIdMap() const {
|
||||||
return _collectionPlanIdMap;
|
return _collectionPlanIdMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string const& edgeCollectionPlanId() const {
|
inline std::vector<ShardID> const& localVertexShardIDs() const {
|
||||||
return _edgeCollectionPlanId;
|
return _localVertexShardIDs;
|
||||||
}
|
};
|
||||||
|
|
||||||
// inline uint64_t numWorkerThreads() {
|
// inline uint64_t numWorkerThreads() {
|
||||||
// return _numWorkerThreads;
|
// return _numWorkerThreads;
|
||||||
|
@ -79,9 +79,10 @@ class WorkerState {
|
||||||
|
|
||||||
std::string _coordinatorId;
|
std::string _coordinatorId;
|
||||||
const std::string _database;
|
const std::string _database;
|
||||||
std::vector<ShardID> _localVertexShardIDs, _localEdgeShardIDs;
|
std::vector<ShardID> _localVertexShardIDs;
|
||||||
|
std::map<CollectionID, std::vector<ShardID>> _vertexCollectionShards, _edgeCollectionShards;
|
||||||
|
|
||||||
std::map<std::string, std::string> _collectionPlanIdMap;
|
std::map<std::string, std::string> _collectionPlanIdMap;
|
||||||
std::string _edgeCollectionPlanId;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
|
|
||||||
#include "Utils/Transaction.h"
|
#include "Utils/Transaction.h"
|
||||||
#include "Utils/V8TransactionContext.h"
|
#include "Utils/TransactionContext.h"
|
||||||
#include "VocBase/ticks.h"
|
#include "VocBase/ticks.h"
|
||||||
#include "VocBase/transaction.h"
|
#include "VocBase/transaction.h"
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ class ExplicitTransaction : public Transaction {
|
||||||
/// @brief create the transaction
|
/// @brief create the transaction
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExplicitTransaction(std::shared_ptr<V8TransactionContext> transactionContext,
|
ExplicitTransaction(std::shared_ptr<TransactionContext> transactionContext,
|
||||||
std::vector<std::string> const& readCollections,
|
std::vector<std::string> const& readCollections,
|
||||||
std::vector<std::string> const& writeCollections,
|
std::vector<std::string> const& writeCollections,
|
||||||
double lockTimeout, bool waitForSync,
|
double lockTimeout, bool waitForSync,
|
||||||
|
|
|
@ -1848,16 +1848,20 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
"_pregelStart(<vertexCollection>, <edgeCollection>, <algorithm>[, "
|
"_pregelStart(<vertexCollection>, <edgeCollection>, <algorithm>[, "
|
||||||
"{steps:100, ...}]");
|
"{steps:100, ...}]");
|
||||||
}
|
}
|
||||||
std::vector<std::string> vertices;
|
auto parse = [](v8::Local<v8::Value> const& value, std::vector<std::string> &out) {
|
||||||
if (args[0]->IsArray()) {
|
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
|
||||||
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(args[0]);
|
|
||||||
uint32_t const n = array->Length();
|
uint32_t const n = array->Length();
|
||||||
for (uint32_t i = 0; i < n; ++i) {
|
for (uint32_t i = 0; i < n; ++i) {
|
||||||
v8::Handle<v8::Value> obj = array->Get(i);
|
v8::Handle<v8::Value> obj = array->Get(i);
|
||||||
if (obj->IsString()) {
|
if (obj->IsString()) {
|
||||||
vertices.push_back(TRI_ObjectToString(obj));
|
out.push_back(TRI_ObjectToString(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> vertices, edges;
|
||||||
|
if (args[0]->IsArray()) {
|
||||||
|
parse(args[0], vertices);
|
||||||
} else if (args[0]->IsString()) {
|
} else if (args[0]->IsString()) {
|
||||||
vertices.push_back(TRI_ObjectToString(args[0]));
|
vertices.push_back(TRI_ObjectToString(args[0]));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1866,10 +1870,16 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
if (vertices.size() == 0) {
|
if (vertices.size() == 0) {
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE("Specify at least one vertex collection");
|
TRI_V8_THROW_EXCEPTION_USAGE("Specify at least one vertex collection");
|
||||||
}
|
}
|
||||||
if (!args[1]->IsString()) {
|
if (args[1]->IsArray()) {
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE("Specify an edge collection to use");
|
parse(args[1], edges);
|
||||||
|
} else if (args[1]->IsString()) {
|
||||||
|
edges.push_back(TRI_ObjectToString(args[1]));
|
||||||
|
} else {
|
||||||
|
TRI_V8_THROW_EXCEPTION_USAGE("Specify an array of edge collections (or a string)");
|
||||||
|
}
|
||||||
|
if (edges.size() == 0) {
|
||||||
|
TRI_V8_THROW_EXCEPTION_USAGE("Specify at least one edge collection");
|
||||||
}
|
}
|
||||||
std::string edgeCName(TRI_ObjectToString(args[1]));
|
|
||||||
std::string algorithm = TRI_ObjectToString(args[2]);
|
std::string algorithm = TRI_ObjectToString(args[2]);
|
||||||
VPackBuilder paramBuilder;
|
VPackBuilder paramBuilder;
|
||||||
if (argLength >= 4 && args[3]->IsObject()) {
|
if (argLength >= 4 && args[3]->IsObject()) {
|
||||||
|
@ -1879,14 +1889,11 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Called _pregelStart(" << vertices[0] << "," << edgeCName << ")";
|
|
||||||
|
|
||||||
if (ServerState::instance()->isCoordinator()) {
|
if (ServerState::instance()->isCoordinator()) {
|
||||||
LOG(INFO) << "Called as a controller";
|
LOG(INFO) << "Called as a controller";
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase = GetContextVocBase(isolate);
|
TRI_vocbase_t* vocbase = GetContextVocBase(isolate);
|
||||||
std::vector<std::shared_ptr<LogicalCollection>> vColls;
|
std::vector<std::shared_ptr<LogicalCollection>> vColls, eColls;
|
||||||
std::shared_ptr<LogicalCollection> edgeCollection;
|
|
||||||
try {
|
try {
|
||||||
for (std::string const& name : vertices) {
|
for (std::string const& name : vertices) {
|
||||||
auto coll =
|
auto coll =
|
||||||
|
@ -1901,17 +1908,20 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
}
|
}
|
||||||
vColls.push_back(coll);
|
vColls.push_back(coll);
|
||||||
}
|
}
|
||||||
edgeCollection =
|
for (std::string const& name : edges) {
|
||||||
ClusterInfo::instance()->getCollection(vocbase->name(), edgeCName);
|
auto coll =
|
||||||
if (edgeCollection->isSystem()) {
|
ClusterInfo::instance()->getCollection(vocbase->name(), name);
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE(
|
if (coll->isSystem()) {
|
||||||
"Cannot use pregel on system collection");
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
||||||
}
|
"Cannot use pregel on system collection");
|
||||||
std::vector<std::string> eKeys = edgeCollection->shardKeys();
|
}
|
||||||
if (eKeys.size() != 1 || eKeys[0] != "_vertex") {
|
std::vector<std::string> eKeys = coll->shardKeys();
|
||||||
|
if (eKeys.size() != 1 || eKeys[0] != "_vertex") {
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE(
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
||||||
"Edge collection needs to be sharded after '_vertex', or use "
|
"Edge collection needs to be sharded after '_vertex', or use "
|
||||||
"smart graphs");
|
"smart graphs");
|
||||||
|
}
|
||||||
|
eColls.push_back(coll);
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE("Collections do not exist");
|
TRI_V8_THROW_EXCEPTION_USAGE("Collections do not exist");
|
||||||
|
@ -1921,7 +1931,7 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
pregel::Conductor* c = new pregel::Conductor(en,
|
pregel::Conductor* c = new pregel::Conductor(en,
|
||||||
vocbase,
|
vocbase,
|
||||||
vColls,
|
vColls,
|
||||||
edgeCollection,
|
eColls,
|
||||||
algorithm);
|
algorithm);
|
||||||
pregel::PregelFeature::instance()->addExecution(c, en);
|
pregel::PregelFeature::instance()->addExecution(c, en);
|
||||||
c->start(paramBuilder.slice());
|
c->start(paramBuilder.slice());
|
||||||
|
|
Loading…
Reference in New Issue