mirror of https://gitee.com/bigwinds/arangodb
Working single DBServer solution SSSP
This commit is contained in:
parent
a6774ae269
commit
c7379f6a06
|
@ -137,8 +137,8 @@ void Conductor::finishedGlobalStep(VPackSlice &data) {
|
|||
_globalSuperstep++;
|
||||
|
||||
std::string baseUrl = Utils::baseUrl(_vocbaseGuard.vocbase()->name());
|
||||
if (_doneCount == _dbServerCount || _globalSuperstep >= 25) {
|
||||
LOG(INFO) << "Done. We did " << _globalSuperstep << " rounds";
|
||||
if (_doneCount == _dbServerCount || _globalSuperstep == 101) {
|
||||
LOG(INFO) << "Done. We did " << _globalSuperstep-1 << " rounds";
|
||||
VPackBuilder b;
|
||||
b.openObject();
|
||||
b.add(Utils::executionNumberKey, VPackValue(_executionNumber));
|
||||
|
|
|
@ -48,7 +48,7 @@ void InMessageCache::clear() {
|
|||
|
||||
void InMessageCache::addMessages(VPackArrayIterator incomingMessages) {
|
||||
MUTEX_LOCKER(locker, writeMutex);
|
||||
LOG(INFO) << "Adding messages to in queue\n";
|
||||
LOG(INFO) << "Adding messages to in queue";
|
||||
|
||||
//unordered_map<string, vector<VPackSlice>> messageBucket;
|
||||
//VPackSlice messages = data.get(Utils::messagesKey);
|
||||
|
@ -89,7 +89,7 @@ void InMessageCache::addMessages(VPackArrayIterator incomingMessages) {
|
|||
}
|
||||
|
||||
VPackSlice InMessageCache::getMessages(std::string const& vertexId) {
|
||||
LOG(INFO) << "Querying messages from in queue\n";
|
||||
LOG(INFO) << "Querying messages from for " << vertexId;
|
||||
auto vmsg = _messages.find(vertexId);
|
||||
if (vmsg != _messages.end()) {
|
||||
return vmsg->second->slice();
|
||||
|
|
|
@ -66,8 +66,8 @@ void OutMessageCache::clear() {
|
|||
_map.clear();
|
||||
}
|
||||
|
||||
void OutMessageCache::addMessage(std::string key, VPackSlice slice) {
|
||||
LOG(INFO) << "Adding messages to out queue\n";
|
||||
void OutMessageCache::addMessage(std::string key, VPackSlice mData) {
|
||||
LOG(INFO) << "Adding outgoing messages " << mData.toJson();
|
||||
|
||||
ShardID responsibleShard;
|
||||
bool usesDefaultShardingAttributes;
|
||||
|
@ -89,15 +89,15 @@ void OutMessageCache::addMessage(std::string key, VPackSlice slice) {
|
|||
|
||||
// hardcoded combiner
|
||||
int64_t oldValue = b->slice().get("value").getInt();
|
||||
int64_t newValue = slice.get("value").getInt();
|
||||
int64_t newValue = mData.get("value").getInt();
|
||||
if (newValue < oldValue) {
|
||||
b->clear();
|
||||
b->add(slice);
|
||||
b->add(mData);
|
||||
}
|
||||
|
||||
} else {// first message for this vertex
|
||||
std::unique_ptr<VPackBuilder> b(new VPackBuilder());
|
||||
b->add(slice);
|
||||
b->add(mData);
|
||||
_map[responsibleShard][key] = b.get();
|
||||
b.release();
|
||||
}
|
||||
|
|
|
@ -34,7 +34,12 @@ using namespace arangodb::pregel;
|
|||
|
||||
Message::Message(VPackSlice slice) {
|
||||
VPackSlice s = slice.get("value");
|
||||
_value = s.getSmallInt() || s.getInt() ? s.getInt() : -1;
|
||||
_value = s.getInt();
|
||||
}
|
||||
|
||||
Edge::Edge(VPackSlice data) : _data(data) {
|
||||
VPackSlice v = data.get("value");
|
||||
_value = v.isInteger() ? v.getInt() : 1;
|
||||
}
|
||||
|
||||
Vertex::Vertex(VPackSlice document) : _data(document) {
|
||||
|
@ -51,20 +56,26 @@ Vertex::~Vertex() {
|
|||
}
|
||||
|
||||
void Vertex::compute(int gss, MessageIterator const &messages, OutMessageCache* const cache) {
|
||||
int current = _vertexState;
|
||||
int64_t current = _vertexState;
|
||||
for (auto const &msg : messages) {
|
||||
if (msg._value < current) current = msg._value;
|
||||
if (current < 0 || msg._value < current) {
|
||||
current = msg._value;
|
||||
};
|
||||
}
|
||||
if (current >= 0 && (gss == 0 || current != _vertexState)) {
|
||||
LOG(INFO) << "Recomputing value for vertex " << _data.toJson();
|
||||
|
||||
_vertexState = current;
|
||||
for (auto const &edge : _edges) {
|
||||
int64_t val = edge._value + current;
|
||||
VPackSlice toID = edge._data.get(StaticStrings::ToString);
|
||||
VPackBuilder b;
|
||||
b.openObject();
|
||||
b.add(StaticStrings::ToString, toID);
|
||||
b.add("value", VPackValue(edge._value + current));
|
||||
b.add("value", VPackValue(val));
|
||||
b.close();
|
||||
cache->addMessage(toID.copyString(), b.slice());
|
||||
}
|
||||
} else voteHalt();
|
||||
}
|
||||
voteHalt();
|
||||
}
|
||||
|
|
|
@ -40,13 +40,13 @@ namespace pregel {
|
|||
struct Message {
|
||||
Message(VPackSlice slice);
|
||||
|
||||
int _value; // demo
|
||||
int64_t _value; // demo
|
||||
};
|
||||
|
||||
//template <typename T>
|
||||
class MessageIterator {
|
||||
public:
|
||||
MessageIterator() = delete;
|
||||
MessageIterator() : _size(0) {}
|
||||
|
||||
typedef MessageIterator iterator;
|
||||
typedef const MessageIterator const_iterator;
|
||||
|
@ -109,12 +109,12 @@ namespace pregel {
|
|||
};
|
||||
|
||||
struct Edge {
|
||||
Edge(VPackSlice data) : _data(data) {}
|
||||
Edge(VPackSlice data);
|
||||
VPackSlice _data;
|
||||
|
||||
//protected: virtual void loadData() = 0;
|
||||
|
||||
int _value;// demo
|
||||
int64_t _value;// demo
|
||||
};
|
||||
|
||||
class Vertex {
|
||||
|
@ -132,11 +132,11 @@ namespace pregel {
|
|||
|
||||
protected:
|
||||
void voteHalt() {_activationState = VertexActivationState::STOPPED;}
|
||||
int _vertexState;// demo
|
||||
int64_t _vertexState;// demo
|
||||
VPackSlice _data;
|
||||
|
||||
private:
|
||||
VertexActivationState _activationState;
|
||||
VertexActivationState _activationState = VertexActivationState::ACTIVE;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ using namespace arangodb::pregel;
|
|||
|
||||
Worker::Worker(unsigned int executionNumber,
|
||||
TRI_vocbase_t *vocbase,
|
||||
VPackSlice s) : _vocbase(vocbase), _ctx(new WorkerContext) {
|
||||
VPackSlice s) : _vocbase(vocbase), _ctx(new WorkerContext(executionNumber)) {
|
||||
|
||||
//VPackSlice algo = s.get("algo");
|
||||
|
||||
|
@ -65,7 +65,6 @@ Worker::Worker(unsigned int executionNumber,
|
|||
if (!(coordID.isString() && vertexShardIDs.length() == 1 && edgeShardIDs.length() == 1)) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, "Only one shard per collection supported");
|
||||
}
|
||||
_ctx->_executionNumber = executionNumber;
|
||||
_ctx->_coordinatorId = coordID.copyString();
|
||||
_ctx->_database = vocbase->name();
|
||||
_ctx->_vertexCollectionName = s.get(Utils::vertexCollectionKey).copyString();// readable name of collection
|
||||
|
@ -147,9 +146,7 @@ Worker::Worker(unsigned int executionNumber,
|
|||
}
|
||||
LOG(INFO) << s.toJson();
|
||||
|
||||
VPackSlice i = s.get("value");
|
||||
v->_edges.emplace_back(s);
|
||||
v->_edges.end()->_value = i.isInteger() ? i.getInt() : 1;
|
||||
edgeCount++;
|
||||
|
||||
}
|
||||
|
@ -190,17 +187,21 @@ void Worker::nextGlobalStep(VPackSlice data) {
|
|||
"Invalid gss in %s:%d", __FILE__, __LINE__);
|
||||
}
|
||||
unsigned int gss = (unsigned int) gssSlice.getUInt();
|
||||
unsigned int expected = _ctx->_globalSuperstep + 1;
|
||||
if (gss != 0 && expected != gss) {
|
||||
if (_ctx->_expectedGSS != gss) {
|
||||
THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_BAD_PARAMETER, "Seems like this worker missed a gss, expected %u. Data = %s ",
|
||||
expected, data.toJson().c_str());
|
||||
_ctx->_expectedGSS, data.toJson().c_str());
|
||||
}
|
||||
|
||||
_ctx->_globalSuperstep = gss;
|
||||
_ctx->_expectedGSS = gss + 1;
|
||||
_ctx->readableIncomingCache()->clear();
|
||||
_ctx->swapIncomingCaches();// write cache becomes the readable cache
|
||||
|
||||
std::unique_ptr<rest::Job> job(new WorkerJob(this, _ctx));
|
||||
DispatcherFeature::DISPATCHER->addJob(job, false);
|
||||
int res = DispatcherFeature::DISPATCHER->addJob(job, true);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG(ERR) << "Could not start worker job";
|
||||
}
|
||||
LOG(INFO) << "Worker started new gss: " << gss;
|
||||
}
|
||||
|
||||
|
@ -222,7 +223,7 @@ void Worker::receivedMessages(VPackSlice data) {
|
|||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, "Superstep out of sync");
|
||||
}
|
||||
|
||||
LOG(INFO) << "Worker received messages\n";
|
||||
LOG(INFO) << "Worker received messages";
|
||||
}
|
||||
|
||||
void Worker::writeResults() {
|
||||
|
@ -247,7 +248,7 @@ void Worker::writeResults() {
|
|||
b.add(StaticStrings::KeyString, pair.second->_data.get(StaticStrings::KeyString));
|
||||
b.add("value", VPackValue(pair.second->_vertexState));
|
||||
b.close();
|
||||
LOG(INFO) << b.toString();
|
||||
LOG(INFO) << b.toJson();
|
||||
/*result = trx.update(_vertexCollection, b->slice(), options);
|
||||
if (!result.successful()) {
|
||||
THROW_ARANGO_EXCEPTION_FORMAT(result.code, "while looking up graph '%s'",
|
||||
|
@ -266,14 +267,16 @@ void Worker::writeResults() {
|
|||
|
||||
// ========== WorkerJob ==========
|
||||
|
||||
WorkerJob::WorkerJob(Worker *worker, std::shared_ptr<WorkerContext> ctx) : Job("Pregel Job"), _worker(worker), _ctx(ctx) {
|
||||
WorkerJob::WorkerJob(Worker *worker,
|
||||
std::shared_ptr<WorkerContext> ctx) : Job("Pregel Job"), _canceled(false), _worker(worker), _ctx(ctx) {
|
||||
}
|
||||
|
||||
void WorkerJob::work() {
|
||||
LOG(INFO) << "Worker job started";
|
||||
if (_canceled) {
|
||||
LOG(INFO) << "Job was canceled before work started";
|
||||
return;
|
||||
}
|
||||
LOG(INFO) << "Worker job started\n";
|
||||
// TODO cache this
|
||||
OutMessageCache outCache(_ctx);
|
||||
|
||||
|
@ -285,24 +288,29 @@ void WorkerJob::work() {
|
|||
|
||||
for (auto const &it : _worker->_vertices) {
|
||||
Vertex *v = it.second;
|
||||
std::string key = v->_data.get(StaticStrings::KeyString).copyString();
|
||||
|
||||
VPackSlice messages = _ctx->readableIncomingCache()->getMessages(key);
|
||||
v->compute(gss, MessageIterator(messages), &outCache);
|
||||
//std::string key = v->_data.get(StaticStrings::KeyString).copyString();
|
||||
//VPackSlice messages = _ctx->readableIncomingCache()->getMessages(key);
|
||||
v->compute(gss, MessageIterator(), &outCache);
|
||||
bool active = v->state() == VertexActivationState::ACTIVE;
|
||||
if (!active) LOG(INFO) << "vertex has halted";
|
||||
_worker->_activationMap[it.first] = active;
|
||||
}
|
||||
} else {
|
||||
for (auto &it : _worker->_activationMap) {
|
||||
VPackSlice messages = _ctx->readableIncomingCache()->getMessages(it.first);
|
||||
|
||||
std::string key = _ctx->vertexCollectionName() + "/" + it.first;
|
||||
VPackSlice messages = _ctx->readableIncomingCache()->getMessages(key);
|
||||
|
||||
MessageIterator iterator(messages);
|
||||
if (iterator.size() > 0 || it.second) {
|
||||
isDone = false;
|
||||
LOG(INFO) << "Processing messages: " << messages.toString();
|
||||
|
||||
Vertex *v = _worker->_vertices[it.first];
|
||||
v->compute(gss, iterator, &outCache);
|
||||
it.second = v->state() == VertexActivationState::ACTIVE;
|
||||
bool active = v->state() == VertexActivationState::ACTIVE;
|
||||
it.second = active;
|
||||
if (!active) LOG(INFO) << "vertex has halted";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +325,7 @@ void WorkerJob::work() {
|
|||
if (!isDone) {
|
||||
outCache.sendMessages();
|
||||
} else {
|
||||
LOG(INFO) << "Worker job has nothing more to process\n";
|
||||
LOG(INFO) << "Worker job has nothing more to process";
|
||||
}
|
||||
|
||||
// notify the conductor that we are done.
|
||||
|
@ -326,7 +334,7 @@ void WorkerJob::work() {
|
|||
package.add(Utils::senderKey, VPackValue(ServerState::instance()->getId()));
|
||||
package.add(Utils::executionNumberKey, VPackValue(_ctx->executionNumber()));
|
||||
package.add(Utils::globalSuperstepKey, VPackValue(gss));
|
||||
if (!isDone) package.add(Utils::doneKey, VPackValue(isDone));
|
||||
package.add(Utils::doneKey, VPackValue(isDone));
|
||||
package.close();
|
||||
|
||||
LOG(INFO) << "Sending finishedGSS to coordinator: " << _ctx->coordinatorId();
|
||||
|
@ -348,6 +356,7 @@ void WorkerJob::work() {
|
|||
}
|
||||
|
||||
bool WorkerJob::cancel() {
|
||||
LOG(INFO) << "Canceling worker job";
|
||||
_canceled = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
using namespace arangodb;
|
||||
using namespace arangodb::pregel;
|
||||
|
||||
WorkerContext::WorkerContext() {
|
||||
WorkerContext::WorkerContext(unsigned int en) : _executionNumber(en) {
|
||||
_readCache = new InMessageCache();
|
||||
_writeCache = new InMessageCache();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace pregel {
|
|||
class WorkerContext {
|
||||
friend class Worker;
|
||||
public:
|
||||
WorkerContext();
|
||||
WorkerContext(unsigned int exeNum);
|
||||
~WorkerContext();
|
||||
|
||||
inline unsigned int executionNumber() {
|
||||
|
@ -83,8 +83,9 @@ namespace pregel {
|
|||
|
||||
private:
|
||||
/// @brief guard to make sure the database is not dropped while used by us
|
||||
unsigned int _executionNumber;
|
||||
unsigned int _globalSuperstep;
|
||||
const unsigned int _executionNumber;
|
||||
unsigned int _globalSuperstep = 0;
|
||||
unsigned int _expectedGSS = 0;
|
||||
std::string _coordinatorId;
|
||||
std::string _database;
|
||||
std::string _vertexCollectionName, _vertexCollectionPlanId;
|
||||
|
|
Loading…
Reference in New Issue