mirror of https://gitee.com/bigwinds/arangodb
Fixed DMID
This commit is contained in:
parent
2e912a1743
commit
41bc0da58e
|
@ -373,7 +373,7 @@ SET(ARANGOD_SOURCES
|
||||||
Pregel/Algos/SCC.cpp
|
Pregel/Algos/SCC.cpp
|
||||||
Pregel/Algos/AsyncSCC.cpp
|
Pregel/Algos/AsyncSCC.cpp
|
||||||
Pregel/Algos/HITS.cpp
|
Pregel/Algos/HITS.cpp
|
||||||
# Pregel/Algos/DMID/DMID.cpp
|
Pregel/Algos/DMID/DMID.cpp
|
||||||
Pregel/Algos/EffectiveCloseness/EffectiveCloseness.cpp
|
Pregel/Algos/EffectiveCloseness/EffectiveCloseness.cpp
|
||||||
Pregel/Algos/EffectiveCloseness/HLLCounter.cpp
|
Pregel/Algos/EffectiveCloseness/HLLCounter.cpp
|
||||||
Pregel/Conductor.cpp
|
Pregel/Conductor.cpp
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "Pregel/Algos/SSSP.h"
|
#include "Pregel/Algos/SSSP.h"
|
||||||
#include "Pregel/Algos/ShortestPath.h"
|
#include "Pregel/Algos/ShortestPath.h"
|
||||||
#include "Pregel/Algos/HITS.h"
|
#include "Pregel/Algos/HITS.h"
|
||||||
|
#include "Pregel/Algos/DMID/DMID.h"
|
||||||
#include "Pregel/Utils.h"
|
#include "Pregel/Utils.h"
|
||||||
|
|
||||||
using namespace arangodb;
|
using namespace arangodb;
|
||||||
|
@ -58,6 +59,8 @@ IAlgorithm* AlgoRegistry::createAlgorithm(std::string const& algorithm,
|
||||||
return new algos::AsyncSCC(userParams);
|
return new algos::AsyncSCC(userParams);
|
||||||
} else if (algorithm == "hits") {
|
} else if (algorithm == "hits") {
|
||||||
return new algos::HITS(userParams);
|
return new algos::HITS(userParams);
|
||||||
|
} else if (algorithm == "dmid") {
|
||||||
|
return new algos::DMID(userParams);
|
||||||
} else {
|
} else {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
||||||
"Unsupported Algorithm");
|
"Unsupported Algorithm");
|
||||||
|
@ -107,6 +110,8 @@ IWorker* AlgoRegistry::createWorker(TRI_vocbase_t* vocbase, VPackSlice body) {
|
||||||
return createWorker(vocbase, new algos::AsyncSCC(userParams), body);
|
return createWorker(vocbase, new algos::AsyncSCC(userParams), body);
|
||||||
} else if (algorithm == "hits") {
|
} else if (algorithm == "hits") {
|
||||||
return createWorker(vocbase, new algos::HITS(userParams), body);
|
return createWorker(vocbase, new algos::HITS(userParams), body);
|
||||||
|
} else if (algorithm == "dmid") {
|
||||||
|
return createWorker(vocbase, new algos::DMID(userParams), body);
|
||||||
} else {
|
} else {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
||||||
"Unsupported Algorithm");
|
"Unsupported Algorithm");
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#include "Pregel/MasterContext.h"
|
#include "Pregel/MasterContext.h"
|
||||||
#include "Pregel/VertexComputation.h"
|
#include "Pregel/VertexComputation.h"
|
||||||
#include "Pregel/Algos/DMID/VertexSumAggregator.h"
|
#include "Pregel/Algos/DMID/VertexSumAggregator.h"
|
||||||
|
#include "Pregel/Algos/DMID/DMIDMessageFormat.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
using namespace arangodb;
|
using namespace arangodb;
|
||||||
using namespace arangodb::pregel;
|
using namespace arangodb::pregel;
|
||||||
|
@ -79,9 +81,14 @@ static std::string const ITERATION_AGG = "aggIT";
|
||||||
*/
|
*/
|
||||||
static std::string const PROFITABILITY_AGG = "aggProfit";
|
static std::string const PROFITABILITY_AGG = "aggProfit";
|
||||||
|
|
||||||
/** Maximum steps for the random walk, corresponds to t*. Default = 1000 */
|
static std::string const RESTART_COUNTER_AGG = "aggRestart";
|
||||||
static uint64_t const long RW_ITERATIONBOUND = 10;
|
|
||||||
|
|
||||||
|
/** Maximum steps for the random walk, corresponds to t*. Default = 1000 */
|
||||||
|
static uint64_t const RW_ITERATIONBOUND = 10;
|
||||||
|
|
||||||
|
static const double PROFTIABILITY_DELTA = 0.3;
|
||||||
|
|
||||||
|
static const bool LOG_AGGS = false;
|
||||||
|
|
||||||
struct DMIDComputation
|
struct DMIDComputation
|
||||||
: public VertexComputation<DMIDValue, float, DMIDMessage> {
|
: public VertexComputation<DMIDValue, float, DMIDMessage> {
|
||||||
|
@ -111,9 +118,9 @@ struct DMIDComputation
|
||||||
superstepRW(messages);
|
superstepRW(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
long rwFinished = RW_ITERATIONBOUND + 4;
|
uint64_t rwFinished = RW_ITERATIONBOUND + 4;
|
||||||
if (globalSuperstep() == rwFinished) {
|
if (globalSuperstep() == rwFinished) {
|
||||||
superstep4(vertex, messages);
|
superstep4(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalSuperstep() == rwFinished +1) {
|
if (globalSuperstep() == rwFinished +1) {
|
||||||
|
@ -133,18 +140,18 @@ struct DMIDComputation
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t iterationCounter = getAggregatedValue<int64_t>(ITERATION_AGG);
|
int64_t const* iterationCounter = getAggregatedValue<int64_t>(ITERATION_AGG);
|
||||||
|
|
||||||
if (globalSuperstep() >= rwFinished +4
|
if (globalSuperstep() >= rwFinished +4
|
||||||
&& (iterationCounter % 3 == 1 )) {
|
&& (*iterationCounter % 3 == 1 )) {
|
||||||
superstep8(messages);
|
superstep8(messages);
|
||||||
}
|
}
|
||||||
if (globalSuperstep() >= rwFinished +5
|
if (globalSuperstep() >= rwFinished +5
|
||||||
&& (iterationCounter % 3 == 2 )) {
|
&& (*iterationCounter % 3 == 2 )) {
|
||||||
superstep9(messages);
|
superstep9(messages);
|
||||||
}
|
}
|
||||||
if (globalSuperstep() >= rwFinished +6
|
if (globalSuperstep() >= rwFinished +6
|
||||||
&& (iterationCounter % 3 == 0 )) {
|
&& (*iterationCounter % 3 == 0 )) {
|
||||||
superstep10(messages);
|
superstep10(messages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,11 +160,11 @@ struct DMIDComputation
|
||||||
* SUPERSTEP 0: send a message along all outgoing edges. Message contains
|
* SUPERSTEP 0: send a message along all outgoing edges. Message contains
|
||||||
* own VertexID and the edge weight.
|
* own VertexID and the edge weight.
|
||||||
*/
|
*/
|
||||||
void superstep0(MessageIterator<DMIDMessage> const& messages messages) {
|
void superstep0(MessageIterator<DMIDMessage> const& messages) {
|
||||||
DMIDMessage message(pregelId(), 0);
|
DMIDMessage message(pregelId(), 0);
|
||||||
RangeIterator<Edge<int64_t>> edges = getEdges();
|
RangeIterator<Edge<float>> edges = getEdges();
|
||||||
for (Edge<int64_t>* edge : edges) {
|
for (Edge<float> *edge : edges) {
|
||||||
message.value = *edge->data(); // edge weight
|
message.weight = *edge->data(); // edge weight
|
||||||
sendMessage(edge, message);
|
sendMessage(edge, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +178,7 @@ struct DMIDComputation
|
||||||
|
|
||||||
float weightedInDegree = 0.0;
|
float weightedInDegree = 0.0;
|
||||||
/** vertices that need a reply containing this vertexs weighted indegree */
|
/** vertices that need a reply containing this vertexs weighted indegree */
|
||||||
std::set<PregelId> predecessors);
|
std::set<PregelID> predecessors;
|
||||||
|
|
||||||
for (DMIDMessage const* message : messages) {
|
for (DMIDMessage const* message : messages) {
|
||||||
/**
|
/**
|
||||||
|
@ -180,15 +187,15 @@ struct DMIDComputation
|
||||||
* was send by msg.getSourceVertexId()
|
* was send by msg.getSourceVertexId()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
predecessors.push(message->senderId);
|
predecessors.insert(message->senderId);
|
||||||
weightedInDegree += message->value;
|
weightedInDegree += message->weight;
|
||||||
}
|
}
|
||||||
/** update new weightedInDegree */
|
/** update new weightedInDegree */
|
||||||
mutableVertexValue()->weightedInDegree = weightedInDegree;
|
mutableVertexData()->weightedInDegree = weightedInDegree;
|
||||||
|
|
||||||
// send to all predecessors
|
// send to all predecessors
|
||||||
DMIDMessage message(pregelId(), weightedInDegree);
|
DMIDMessage message(pregelId(), weightedInDegree);
|
||||||
for (PregelId const& pid : predecessors) {
|
for (PregelID const& pid : predecessors) {
|
||||||
sendMessage(pid, message);
|
sendMessage(pid, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,11 +218,11 @@ struct DMIDComputation
|
||||||
for (DMIDMessage const* message : messages) {
|
for (DMIDMessage const* message : messages) {
|
||||||
|
|
||||||
/** Weight= weightedInDegree */
|
/** Weight= weightedInDegree */
|
||||||
float senderWeight = msg.getValue();
|
float senderWeight = message->weight;
|
||||||
float disValue = fabs(ownWeight - senderWeight);
|
float disValue = fabs(ownWeight - senderWeight);
|
||||||
disSum += disValue;
|
disSum += disValue;
|
||||||
/** disValue = disassortativity value of senderID and ownID */
|
/** disValue = disassortativity value of senderID and ownID */
|
||||||
vertexState->disCol[msg->pregelId] = disValue;
|
vertexState->disCol[message->senderId] = disValue;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Normalize the new disCol (Note: a new Vector is automatically
|
* Normalize the new disCol (Note: a new Vector is automatically
|
||||||
|
@ -233,7 +240,7 @@ struct DMIDComputation
|
||||||
* */
|
* */
|
||||||
|
|
||||||
VertexSumAggregator *agg = (VertexSumAggregator*)getAggregator(DA_AGG);
|
VertexSumAggregator *agg = (VertexSumAggregator*)getAggregator(DA_AGG);
|
||||||
agg->aggregate(this->shard(), this->key(), 1.0 / context->vertexCount());
|
agg->aggregate(this->shard(), this->key(), 1.0 / context()->vertexCount());
|
||||||
//DoubleDenseVector init = new DoubleDenseVector(
|
//DoubleDenseVector init = new DoubleDenseVector(
|
||||||
// (int) getTotalNumVertices());
|
// (int) getTotalNumVertices());
|
||||||
//init.set((int) vertex.getId().get(), (double) 1.0
|
//init.set((int) vertex.getId().get(), (double) 1.0
|
||||||
|
@ -263,14 +270,14 @@ struct DMIDComputation
|
||||||
curDA->forEach([&](PregelID const& _id, double entry) {
|
curDA->forEach([&](PregelID const& _id, double entry) {
|
||||||
newEntryDA += entry * vertexState->disCol[_id];
|
newEntryDA += entry * vertexState->disCol[_id];
|
||||||
});
|
});
|
||||||
curDA->aggregateValue(this->shard(), this->key(), newEntryDA);
|
curDA->aggregate(this->shard(), this->key(), newEntryDA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SUPERSTEP RW_ITERATIONBOUND+4: Calculate entry LS_ownID using DA^t* and
|
* SUPERSTEP RW_ITERATIONBOUND+4: Calculate entry LS_ownID using DA^t* and
|
||||||
* weightedInDegree. Save entry in the LS aggregator.
|
* weightedInDegree. Save entry in the LS aggregator.
|
||||||
*/
|
*/
|
||||||
private void superstep4(MessageIterator<DMIDMessage> const& messages) {
|
void superstep4(MessageIterator<DMIDMessage> const& messages) {
|
||||||
DMIDValue* vertexState = mutableVertexData();
|
DMIDValue* vertexState = mutableVertexData();
|
||||||
VertexSumAggregator *finalDA = (VertexSumAggregator*)getAggregator(DA_AGG);
|
VertexSumAggregator *finalDA = (VertexSumAggregator*)getAggregator(DA_AGG);
|
||||||
|
|
||||||
|
@ -296,16 +303,16 @@ struct DMIDComputation
|
||||||
* value on the sender. The influence v-i has on v-j is (LS-i * w-ji) where
|
* value on the sender. The influence v-i has on v-j is (LS-i * w-ji) where
|
||||||
* w-ji is the weight of the edge from v-j to v-i.
|
* w-ji is the weight of the edge from v-j to v-i.
|
||||||
* */
|
* */
|
||||||
private void superstep6(MessageIterator<DMIDMessage> const& messages) {
|
void superstep6(MessageIterator<DMIDMessage> const& messages) {
|
||||||
|
|
||||||
//DoubleDenseVector vecLS = getAggregatedValue(LS_AGG);
|
//DoubleDenseVector vecLS = getAggregatedValue(LS_AGG);
|
||||||
VertexSumAggregator *vecLS = (VertexSumAggregator*)getAggregator(LS_AGG);
|
VertexSumAggregator *vecLS = (VertexSumAggregator*)getAggregator(LS_AGG);
|
||||||
for (DMIDMessage const* message : messages) {
|
for (DMIDMessage const* message : messages) {
|
||||||
|
|
||||||
PregelID senderID = message->senderId();
|
PregelID senderID = message->senderId;
|
||||||
/** Weight= weightedInDegree */
|
/** Weight= weightedInDegree */
|
||||||
|
|
||||||
float senderWeight = message->value();
|
float senderWeight = message->weight;
|
||||||
|
|
||||||
float myInfluence = senderWeight * vecLS->getAggregatedValue(this->shard(), this->key());
|
float myInfluence = senderWeight * vecLS->getAggregatedValue(this->shard(), this->key());
|
||||||
|
|
||||||
|
@ -314,7 +321,7 @@ struct DMIDComputation
|
||||||
*/
|
*/
|
||||||
bool hasEdgeToSender = false;
|
bool hasEdgeToSender = false;
|
||||||
for (Edge<float> *edge : getEdges()) {
|
for (Edge<float> *edge : getEdges()) {
|
||||||
if (edge->targetShard() == senderID.shard && edge->key() == senderID.key) {
|
if (edge->targetShard() == senderID.shard && edge->toKey() == senderID.key) {
|
||||||
|
|
||||||
hasEdgeToSender = true;
|
hasEdgeToSender = true;
|
||||||
/**
|
/**
|
||||||
|
@ -345,7 +352,7 @@ struct DMIDComputation
|
||||||
* There may be more then one local leader. Add 1/k to the FollowerDegree
|
* There may be more then one local leader. Add 1/k to the FollowerDegree
|
||||||
* (aggregator) of the k local leaders found.
|
* (aggregator) of the k local leaders found.
|
||||||
**/
|
**/
|
||||||
private void superstep7(MessageIterator<DMIDMessage> const& messages) {
|
void superstep7(MessageIterator<DMIDMessage> const& messages) {
|
||||||
|
|
||||||
/** maximum influence on this vertex */
|
/** maximum influence on this vertex */
|
||||||
float maxInfValue = 0;
|
float maxInfValue = 0;
|
||||||
|
@ -356,8 +363,8 @@ struct DMIDComputation
|
||||||
/** Find possible local leader */
|
/** Find possible local leader */
|
||||||
for (DMIDMessage const* message : messages) {
|
for (DMIDMessage const* message : messages) {
|
||||||
|
|
||||||
if (message->value >= maxInfValue) {
|
if (message->weight >= maxInfValue) {
|
||||||
if (message->value > maxInfValue) {
|
if (message->weight > maxInfValue) {
|
||||||
/** new distinct leader found. Clear set */
|
/** new distinct leader found. Clear set */
|
||||||
leaderSet.clear();
|
leaderSet.clear();
|
||||||
}
|
}
|
||||||
|
@ -412,9 +419,9 @@ struct DMIDComputation
|
||||||
* specific communities.
|
* specific communities.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
it = vertexState->membershipDegree.find(this->pregelId());
|
auto const& it2 = vertexState->membershipDegree.find(this->pregelId());
|
||||||
/** In case of first init test again if vertex is leader */
|
/** In case of first init test again if vertex is leader */
|
||||||
if (it == vertexState->membershipDegree.end()) {
|
if (it2 == vertexState->membershipDegree.end()) {
|
||||||
|
|
||||||
for (auto const& pair : vertexState->membershipDegree) {
|
for (auto const& pair : vertexState->membershipDegree) {
|
||||||
/**
|
/**
|
||||||
|
@ -427,16 +434,16 @@ struct DMIDComputation
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
voteToHalt();
|
voteHalt();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/** All vertices are assigned to at least one community */
|
/** All vertices are assigned to at least one community */
|
||||||
/** TERMINATION */
|
/** TERMINATION */
|
||||||
voteToHalt();
|
voteHalt();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
voteToHalt();
|
voteHalt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +451,7 @@ struct DMIDComputation
|
||||||
* SUPERSTEP RW_IT+9: Second iteration point of the cascading behavior
|
* SUPERSTEP RW_IT+9: Second iteration point of the cascading behavior
|
||||||
* phase.
|
* phase.
|
||||||
**/
|
**/
|
||||||
private void superstep9(MessageIterator<DMIDMessage> const& messages) {
|
void superstep9(MessageIterator<DMIDMessage> const& messages) {
|
||||||
DMIDValue* vertexState = mutableVertexData();
|
DMIDValue* vertexState = mutableVertexData();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -459,8 +466,8 @@ struct DMIDComputation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (vertexState->membershipDegree[leaderID] != 0.0) {
|
if (vertexState->membershipDegree[leaderID] != 0.0) {
|
||||||
DMIDMessage message(pregelId(), leaderID);
|
DMIDMessage data(pregelId(), leaderID);
|
||||||
sendMessage(message->senderId, leaderID);
|
sendMessage(message->senderId, data);
|
||||||
|
|
||||||
//LongDoubleMessage answerMsg = new LongDoubleMessage(vertex
|
//LongDoubleMessage answerMsg = new LongDoubleMessage(vertex
|
||||||
// .getId().get(), leaderID);
|
// .getId().get(), leaderID);
|
||||||
|
@ -474,12 +481,72 @@ struct DMIDComputation
|
||||||
* SUPERSTEP RW_IT+10: Third iteration point of the cascading behavior
|
* SUPERSTEP RW_IT+10: Third iteration point of the cascading behavior
|
||||||
* phase.
|
* phase.
|
||||||
**/
|
**/
|
||||||
abstract void superstep10(MessageIterator<DMIDMessage> const& messages);
|
void superstep10(MessageIterator<DMIDMessage> const& messages) {
|
||||||
|
|
||||||
|
//long vertexID = vertex.getId().get();
|
||||||
|
DMIDValue* vertexState = mutableVertexData();
|
||||||
|
auto const& it = vertexState->membershipDegree.find(this->pregelId());
|
||||||
|
|
||||||
|
/** Is this vertex a global leader? */
|
||||||
|
if (it == vertexState->membershipDegree.end()) {//!vertex.getValue().getMembershipDegree().containsKey(vertexID)
|
||||||
|
/** counts per communities the number of successors which are member */
|
||||||
|
std::map<PregelID, float> membershipCounter;
|
||||||
|
//double previousCount = 0.0;
|
||||||
|
|
||||||
|
for (DMIDMessage const* message : messages) {
|
||||||
|
/**
|
||||||
|
* the msg value is the index of the community the sender is a
|
||||||
|
* member of
|
||||||
|
*/
|
||||||
|
//Long leaderID = ((long) msg.getValue());
|
||||||
|
PregelID const& leaderID = message->leaderId;
|
||||||
|
// .containsKey(leaderID)
|
||||||
|
if (membershipCounter.find(leaderID) != membershipCounter.end()) {
|
||||||
|
/** increase count by 1 */
|
||||||
|
membershipCounter[leaderID] += 1;//.get(leaderID);
|
||||||
|
//membershipCounter.put(leaderID, previousCount + 1);
|
||||||
|
} else {
|
||||||
|
membershipCounter[leaderID] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** profitability threshold */
|
||||||
|
float const* threshold = getAggregatedValue<float>(PROFITABILITY_AGG);
|
||||||
|
|
||||||
|
int64_t const* iterationCounter = getAggregatedValue<int64_t>(ITERATION_AGG);
|
||||||
|
|
||||||
|
// Map.Entry<Long, Double> entry : membershipCounter.entrySet()
|
||||||
|
for (std::pair<PregelID, float> const& pair : membershipCounter) {
|
||||||
|
|
||||||
|
if ((pair.second / getEdges().size()) > *threshold) {
|
||||||
|
/** its profitable to become a member, set value */
|
||||||
|
vertexState->membershipDegree[pair.first] = 1.0 / std::pow(*iterationCounter / 3, 2);
|
||||||
|
aggregate<bool>(NEW_MEMBER_AGG, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* vertex.getValue().setBestValidMemDeg(vertex.getValue()
|
||||||
|
.getMembershipDegree());
|
||||||
|
*/
|
||||||
|
bool isPartOfAnyCommunity = false;
|
||||||
|
// Map.Entry<Long, Double> entry : vertex.getValue().getMembershipDegree().entrySet()
|
||||||
|
for (auto const& pair : vertexState->membershipDegree) {
|
||||||
|
if (pair.second != 0.0) {
|
||||||
|
isPartOfAnyCommunity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isPartOfAnyCommunity) {
|
||||||
|
|
||||||
|
aggregate<bool>(NOT_ALL_ASSIGNED_AGG, true);
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
voteHalt();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the MembershipDegree vector.
|
* Initialize the MembershipDegree vector.
|
||||||
**/
|
**/
|
||||||
private void initilaizeMemDeg() {
|
void initilaizeMemDeg() {
|
||||||
DMIDValue* vertexState = mutableVertexData();
|
DMIDValue* vertexState = mutableVertexData();
|
||||||
|
|
||||||
VertexSumAggregator *vecGL = (VertexSumAggregator*)getAggregator(GL_AGG);
|
VertexSumAggregator *vecGL = (VertexSumAggregator*)getAggregator(GL_AGG);
|
||||||
|
@ -506,19 +573,18 @@ struct DMIDComputation
|
||||||
// vertexState->membershipDegree[this->pregelId] = 1.0;
|
// vertexState->membershipDegree[this->pregelId] = 1.0;
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VertexComputation<DMIDValue, int32_t, int64_t>*
|
VertexComputation<DMIDValue, float, DMIDMessage>*
|
||||||
DMID::createComputation(WorkerConfig const* config) const {
|
DMID::createComputation(WorkerConfig const* config) const {
|
||||||
return new DMIDComputation();
|
return new DMIDComputation();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SCCGraphFormat : public GraphFormat<DMIDValue, int32_t> {
|
struct DMIDGraphFormat : public GraphFormat<DMIDValue, float> {
|
||||||
const std::string _resultField;
|
const std::string _resultField;
|
||||||
uint64_t vertexIdRange = 0;
|
uint64_t vertexIdRange = 0;
|
||||||
|
|
||||||
SCCGraphFormat(std::string const& result) : _resultField(result) {}
|
DMIDGraphFormat(std::string const& result) : _resultField(result) {}
|
||||||
|
|
||||||
void willLoadVertices(uint64_t count) override {
|
void willLoadVertices(uint64_t count) override {
|
||||||
// if we aren't running in a cluster it doesn't matter
|
// if we aren't running in a cluster it doesn't matter
|
||||||
|
@ -530,40 +596,44 @@ struct SCCGraphFormat : public GraphFormat<DMIDValue, int32_t> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t estimatedEdgeSize() const override { return 0; };
|
|
||||||
|
|
||||||
size_t copyVertexData(std::string const& documentId,
|
size_t copyVertexData(std::string const& documentId,
|
||||||
arangodb::velocypack::Slice document,
|
arangodb::velocypack::Slice document,
|
||||||
SCCValue* targetPtr, size_t maxSize) override {
|
DMIDValue* value, size_t maxSize) override {
|
||||||
SCCValue* senders = (SCCValue*)targetPtr;
|
//SCCValue* senders = (SCCValue*)targetPtr;
|
||||||
senders->vertexID = vertexIdRange++;
|
//senders->vertexID = vertexIdRange++;
|
||||||
return sizeof(SCCValue);
|
return sizeof(SCCValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t copyEdgeData(arangodb::velocypack::Slice document, int32_t* targetPtr,
|
size_t copyEdgeData(arangodb::velocypack::Slice document, float* targetPtr,
|
||||||
size_t maxSize) override {
|
size_t maxSize) override {
|
||||||
return 0;
|
*targetPtr = 1.0f;
|
||||||
|
return sizeof(float);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool buildVertexDocument(arangodb::velocypack::Builder& b,
|
bool buildVertexDocument(arangodb::velocypack::Builder& b,
|
||||||
const SCCValue* ptr, size_t size) const override {
|
const DMIDValue* ptr, size_t size) const override {
|
||||||
SCCValue* senders = (SCCValue*)ptr;
|
if (ptr->membershipDegree.size() > 0) {
|
||||||
b.add(_resultField, VPackValue(senders->color));
|
b.add(_resultField, VPackValue(VPackValueType::Array));
|
||||||
|
for (auto const& pair : ptr->membershipDegree) {
|
||||||
|
b.add(pair.first.key, VPackValue(pair.second));
|
||||||
|
}
|
||||||
|
b.close();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool buildEdgeDocument(arangodb::velocypack::Builder& b, const int32_t* ptr,
|
bool buildEdgeDocument(arangodb::velocypack::Builder& b, const float* ptr,
|
||||||
size_t size) const override {
|
size_t size) const override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
GraphFormat<SCCValue, int32_t>* SCC::inputFormat() const {
|
GraphFormat<DMIDValue, float>* DMID::inputFormat() const {
|
||||||
return new DMIDValueGraphFormat(_resultField);
|
return new DMIDGraphFormat(_resultField);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DMIDValueMasterContext : public MasterContext {
|
struct DMIDMasterContext : public MasterContext {
|
||||||
DMIDValueMasterContext() {} // TODO use _threashold
|
DMIDMasterContext() {} // TODO use _threashold
|
||||||
void preGlobalSuperstep() override {
|
void preGlobalSuperstep() override {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -573,38 +643,38 @@ struct DMIDValueMasterContext : public MasterContext {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int64_t* iterCount = getAggregatedValue<int64_t>(ITERATION_AGG);
|
int64_t const* iterCount = getAggregatedValue<int64_t>(ITERATION_AGG);
|
||||||
int64_t newIterCount = *iterCount + 1;
|
int64_t newIterCount = *iterCount + 1;
|
||||||
bool hasCascadingStarted = false;
|
bool hasCascadingStarted = false;
|
||||||
if (*iterCount != 0) {
|
if (*iterCount != 0) {
|
||||||
/** Cascading behavior started increment the iteration count */
|
/** Cascading behavior started increment the iteration count */
|
||||||
aggregateValue<int64_t>(ITERATION_AGG, newIterCount);
|
aggregate<int64_t>(ITERATION_AGG, newIterCount);
|
||||||
hasCascadingStarted = true;
|
hasCascadingStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getSuperstep() == RW_ITERATIONBOUND+ 8) {
|
if (globalSuperstep() == RW_ITERATIONBOUND+ 8) {
|
||||||
aggregateValue<bool>(NEW_MEMBER_AGG, false);
|
aggregate<bool>(NEW_MEMBER_AGG, false);
|
||||||
aggregateValue<bool>(NOT_ALL_ASSIGNED_AGG, true);
|
aggregate<bool>(NOT_ALL_ASSIGNED_AGG, true);
|
||||||
aggregateValue<int64_t>(ITERATION_AGG, 1);
|
aggregate<int64_t>(ITERATION_AGG, 1);
|
||||||
hasCascadingStarted = true;
|
hasCascadingStarted = true;
|
||||||
initializeGL();
|
initializeGL();
|
||||||
}
|
}
|
||||||
if (hasCascadingStarted && (newIterCount % 3 == 1)) {
|
if (hasCascadingStarted && (newIterCount % 3 == 1)) {
|
||||||
/** first step of one iteration */
|
/** first step of one iteration */
|
||||||
int64_t* restartCountWritable = getAggregatedValue<int64_t>(RESTART_COUNTER_AGG);
|
int64_t const* restartCountWritable = getAggregatedValue<int64_t>(RESTART_COUNTER_AGG);
|
||||||
Long restartCount = restartCountWritable.get();
|
int64_t restartCount = *restartCountWritable;
|
||||||
BooleanWritable newMember = getAggregatedValue(DMIDComputation.NEW_MEMBER_AGG);
|
bool const* newMember = getAggregatedValue<bool>(NEW_MEMBER_AGG);
|
||||||
BooleanWritable notAllAssigned = getAggregatedValue(DMIDComputation.NOT_ALL_ASSIGNED_AGG);
|
bool const* notAllAssigned = getAggregatedValue<bool>(NOT_ALL_ASSIGNED_AGG);
|
||||||
|
|
||||||
if ((notAllAssigned.get() == true) && (newMember.get() == false)) {
|
if ((*notAllAssigned == true) && (*newMember == false)) {
|
||||||
/**
|
/**
|
||||||
* RESTART Cascading Behavior with lower profitability threshold
|
* RESTART Cascading Behavior with lower profitability threshold
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float newThreshold = 1 - (PROFTIABILITY_DELTA * (restartCount + 1));
|
float newThreshold = 1 - (PROFTIABILITY_DELTA * (restartCount + 1));
|
||||||
setAggregatedValue<int64_t>(RESTART_COUNTER_AGG, restartCount + 1);
|
aggregate<int64_t>(RESTART_COUNTER_AGG, restartCount + 1);
|
||||||
setAggregatedValue<float>(PROFITABILITY_AGG, newThreshold);
|
aggregate<float>(PROFITABILITY_AGG, newThreshold);
|
||||||
setAggregatedValue<int64_t>(ITERATION_AGG, 1);
|
aggregate<int64_t>(ITERATION_AGG, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -616,36 +686,24 @@ struct DMIDValueMasterContext : public MasterContext {
|
||||||
* initial value
|
* initial value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setAggregatedValue<bool>(NEW_MEMBER_AGG, false);
|
aggregate<bool>(NEW_MEMBER_AGG, false);
|
||||||
setAggregatedValue<bool>(NOT_ALL_ASSIGNED_AGG, false);
|
aggregate<bool>(NOT_ALL_ASSIGNED_AGG, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LOG_AGGS) {
|
if (LOG_AGGS) {
|
||||||
if (getSuperstep() <= DMIDComputation.RW_ITERATIONBOUND + 4) {
|
if (globalSuperstep() <= RW_ITERATIONBOUND + 4) {
|
||||||
DoubleDenseVector convergedDA = getAggregatedValue(DMIDComputation.DA_AGG);
|
VertexSumAggregator *convergedDA = (VertexSumAggregator*)getAggregator(DA_AGG);
|
||||||
System.out.print("Aggregator DA at step: "+getSuperstep()+" \nsize="
|
|
||||||
+ getTotalNumVertices() + "\n{ ");
|
LOG_TOPIC(INFO, Logger::PREGEL) << "Aggregator DA at step: " << globalSuperstep();
|
||||||
for (int i = 0; i < getTotalNumVertices(); ++i) {
|
convergedDA->forEach([&](PregelID const& _id, double entry) {
|
||||||
System.out.print(convergedDA.get(i));
|
LOG_TOPIC(INFO, Logger::PREGEL) << _id.key;
|
||||||
if (i != getTotalNumVertices() - 1) {
|
});
|
||||||
System.out.print(" , ");
|
|
||||||
} else {
|
|
||||||
System.out.println(" }\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (getSuperstep() == DMIDComputation.RW_ITERATIONBOUND +6) {
|
|
||||||
DoubleDenseVector leadershipVector = getAggregatedValue(DMIDComputation.LS_AGG);
|
|
||||||
System.out.print("Aggregator LS: \nsize="
|
|
||||||
+ getTotalNumVertices() + "\n{ ");
|
|
||||||
for (int i = 0; i < getTotalNumVertices(); ++i) {
|
|
||||||
System.out.print(leadershipVector.get(i));
|
|
||||||
if (i != getTotalNumVertices() - 1) {
|
|
||||||
System.out.print(" , ");
|
|
||||||
} else {
|
|
||||||
System.out.println(" }\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (globalSuperstep() == RW_ITERATIONBOUND +6) {
|
||||||
|
VertexSumAggregator *leadershipVector = (VertexSumAggregator*)getAggregator(LS_AGG);
|
||||||
|
leadershipVector->forEach([&](PregelID const& _id, double entry) {
|
||||||
|
LOG_TOPIC(INFO, Logger::PREGEL) << "Aggregator LS:" << _id.key;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,54 +713,46 @@ struct DMIDValueMasterContext : public MasterContext {
|
||||||
* higher number of followers than the average.
|
* higher number of followers than the average.
|
||||||
*/
|
*/
|
||||||
void initializeGL() {
|
void initializeGL() {
|
||||||
DoubleSparseVector initGL = new DoubleSparseVector(
|
/** set Global Leader aggregator */
|
||||||
(int) getTotalNumVertices());
|
VertexSumAggregator *initGL = (VertexSumAggregator*)getAggregator(GL_AGG);
|
||||||
VertexSumAggregator *vecFD = (VertexSumAggregator*)getAggregator(FD_AGG);
|
VertexSumAggregator *vecFD = (VertexSumAggregator*)getAggregator(FD_AGG);
|
||||||
|
|
||||||
double averageFD = 0.0;
|
double averageFD = 0.0;
|
||||||
int numLocalLeader = 0;
|
int numLocalLeader = 0;
|
||||||
/** get averageFollower degree */
|
/** get averageFollower degree */
|
||||||
f
|
vecFD->forEach([&](PregelID const& _id, double entry) {
|
||||||
for (int i = 0; i < getTotalNumVertices(); ++i) {
|
averageFD += entry;
|
||||||
averageFD += vecFD.get(i);
|
if (entry != 0) {
|
||||||
if (vecFD.get(i) != 0) {
|
|
||||||
numLocalLeader++;
|
numLocalLeader++;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (numLocalLeader != 0) {
|
if (numLocalLeader != 0) {
|
||||||
averageFD = (double) averageFD / numLocalLeader;
|
averageFD = (double) averageFD / numLocalLeader;
|
||||||
}
|
}
|
||||||
/** set flag for globalLeader */
|
/** set flag for globalLeader */
|
||||||
if (LOG_AGGS) {
|
//if (LOG_AGGS) {
|
||||||
System.out.print("Global Leader:");
|
// System.out.print("Global Leader:");
|
||||||
|
//}
|
||||||
|
vecFD->forEach([&](PregelID const& _id, double entry) {
|
||||||
|
if (entry > averageFD) {
|
||||||
|
initGL->aggregate(_id.shard, _id.key, 1.0);
|
||||||
|
LOG_TOPIC(INFO, Logger::PREGEL) << "Leader " << _id.key;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < vertexCount(); ++i) {
|
});
|
||||||
if (vecFD.get(i) > averageFD) {
|
//setAggregatedValue(DMIDComputation.GL_AGG, initGL);
|
||||||
initGL.set(i, 1.0);
|
|
||||||
if (LOG_AGGS) {
|
|
||||||
System.out.print(" " + i + " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (LOG_AGGS) {
|
|
||||||
System.out.println("\n");
|
|
||||||
}
|
|
||||||
/** set Global Leader aggregator */
|
|
||||||
setAggregatedValue(DMIDComputation.GL_AGG, initGL);
|
|
||||||
|
|
||||||
/** set not all vertices assigned aggregator to true */
|
/** set not all vertices assigned aggregator to true */
|
||||||
setAggregatedValue(DMIDComputation.NOT_ALL_ASSIGNED_AGG,
|
aggregate<bool>(NOT_ALL_ASSIGNED_AGG, true);
|
||||||
new BooleanWritable(true));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MasterContext* SCC::masterContext(VPackSlice userParams) const {
|
MasterContext* DMID::masterContext(VPackSlice userParams) const {
|
||||||
return new SCCMasterContext();
|
return new DMIDMasterContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
IAggregator* SCC::aggregator(std::string const& name) const {
|
IAggregator* DMID::aggregator(std::string const& name) const {
|
||||||
if (name == DA_AGG) { // permanent value
|
if (name == DA_AGG) { // permanent value
|
||||||
return new VertexSumAggregator(false);// non perm
|
return new VertexSumAggregator(false);// non perm
|
||||||
} else if (name == LS_AGG) {
|
} else if (name == LS_AGG) {
|
||||||
|
@ -712,9 +762,9 @@ IAggregator* SCC::aggregator(std::string const& name) const {
|
||||||
} else if (name == GL_AGG) {
|
} else if (name == GL_AGG) {
|
||||||
return new VertexSumAggregator(true);// perm
|
return new VertexSumAggregator(true);// perm
|
||||||
} else if (name == NEW_MEMBER_AGG) {
|
} else if (name == NEW_MEMBER_AGG) {
|
||||||
return new BooleanOrAggregator(false); // non perm
|
return new BoolOrAggregator(false); // non perm
|
||||||
} else if (name == NOT_ALL_ASSIGNED_AGG) {
|
} else if (name == NOT_ALL_ASSIGNED_AGG) {
|
||||||
return new BooleanOrAggregator(false); // non perm
|
return new BoolOrAggregator(false); // non perm
|
||||||
} else if (name == ITERATION_AGG) {
|
} else if (name == ITERATION_AGG) {
|
||||||
return new MaxAggregator<int64_t>(0, true); // perm
|
return new MaxAggregator<int64_t>(0, true); // perm
|
||||||
} else if (name == PROFITABILITY_AGG) {
|
} else if (name == PROFITABILITY_AGG) {
|
||||||
|
@ -725,3 +775,7 @@ IAggregator* SCC::aggregator(std::string const& name) const {
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageFormat<DMIDMessage>* DMID::messageFormat() const {
|
||||||
|
return new DMIDMessageFormat();
|
||||||
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
/// @author Simon Grätzer
|
/// @author Simon Grätzer
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef ARANGODB_PREGEL_ALGOS_SCC_H
|
#ifndef ARANGODB_PREGEL_ALGOS_DMID_H
|
||||||
#define ARANGODB_PREGEL_ALGOS_SCC_H 1
|
#define ARANGODB_PREGEL_ALGOS_DMID_H 1
|
||||||
|
|
||||||
#include "Pregel/Algorithm.h"
|
#include "Pregel/Algorithm.h"
|
||||||
#include "Pregel/CommonFormats.h"
|
#include "Pregel/CommonFormats.h"
|
||||||
|
|
|
@ -35,7 +35,6 @@ namespace arangodb {
|
||||||
namespace pregel {
|
namespace pregel {
|
||||||
|
|
||||||
struct DMIDMessageFormat : public MessageFormat<DMIDMessage> {
|
struct DMIDMessageFormat : public MessageFormat<DMIDMessage> {
|
||||||
static_assert(std::is_arithmetic<T>::value, "Message type must be numeric");
|
|
||||||
DMIDMessageFormat() {}
|
DMIDMessageFormat() {}
|
||||||
void unwrapValue(VPackSlice s, DMIDMessage& message) const override {
|
void unwrapValue(VPackSlice s, DMIDMessage& message) const override {
|
||||||
VPackArrayIterator array(s);
|
VPackArrayIterator array(s);
|
||||||
|
@ -43,7 +42,7 @@ struct DMIDMessageFormat : public MessageFormat<DMIDMessage> {
|
||||||
message.senderId.key = (*(++array)).copyString();
|
message.senderId.key = (*(++array)).copyString();
|
||||||
message.leaderId.shard = (*array).getUInt();
|
message.leaderId.shard = (*array).getUInt();
|
||||||
message.leaderId.key = (*(++array)).copyString();
|
message.leaderId.key = (*(++array)).copyString();
|
||||||
message.value = (*(++array)).getNumber<float>();
|
message.weight = (*(++array)).getNumber<float>();
|
||||||
}
|
}
|
||||||
void addValue(VPackBuilder& arrayBuilder,
|
void addValue(VPackBuilder& arrayBuilder,
|
||||||
DMIDMessage const& message) const override {
|
DMIDMessage const& message) const override {
|
||||||
|
@ -52,7 +51,7 @@ struct DMIDMessageFormat : public MessageFormat<DMIDMessage> {
|
||||||
arrayBuilder.add(VPackValue(message.senderId.key));
|
arrayBuilder.add(VPackValue(message.senderId.key));
|
||||||
arrayBuilder.add(VPackValue(message.leaderId.shard));
|
arrayBuilder.add(VPackValue(message.leaderId.shard));
|
||||||
arrayBuilder.add(VPackValue(message.leaderId.key));
|
arrayBuilder.add(VPackValue(message.leaderId.key));
|
||||||
arrayBuilder.add(VPackValue(message.value));
|
arrayBuilder.add(VPackValue(message.weight));
|
||||||
arrayBuilder.close();
|
arrayBuilder.close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,9 +22,10 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <velocypack/Builder.h>
|
#include <velocypack/Builder.h>
|
||||||
#include <velocypack/Iterators.h>
|
#include <velocypack/Iterator.h>
|
||||||
#include <velocypack/Slice.h>
|
#include <velocypack/Slice.h>
|
||||||
#include <velocypack/velocypack-aliases.h>
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
#include <string>
|
||||||
#include "Pregel/Graph.h"
|
#include "Pregel/Graph.h"
|
||||||
|
|
||||||
#ifndef ARANGODB_PREGEL_AGG_DENSE_VECTOR_H
|
#ifndef ARANGODB_PREGEL_AGG_DENSE_VECTOR_H
|
||||||
|
@ -34,17 +35,17 @@ namespace arangodb {
|
||||||
namespace pregel {
|
namespace pregel {
|
||||||
|
|
||||||
struct VertexSumAggregator : public IAggregator {
|
struct VertexSumAggregator : public IAggregator {
|
||||||
static_assert(std::is_arithmetic<T>::value, "Type must be numeric");
|
|
||||||
typedef std::map<prgl_shard_t, std::unordered_map<std::string, double>> VertexMap;
|
typedef std::map<prgl_shard_t, std::unordered_map<std::string, double>> VertexMap;
|
||||||
|
typedef std::pair<prgl_shard_t, std::unordered_map<std::string, double>> MyPair;
|
||||||
|
|
||||||
VertexSumAggregator(bool perm = false)
|
VertexSumAggregator(bool perm = false)
|
||||||
: _empty(empty), _permanent(perm) {}
|
: _permanent(perm) {}
|
||||||
|
|
||||||
// if you use this from a vertex I will end you
|
// if you use this from a vertex I will end you
|
||||||
void aggregate(void const* valuePtr) {
|
void aggregate(void const* valuePtr) override {
|
||||||
VertexMap const* map = (VertexMap const*)valuePtr;
|
VertexMap const* map = (VertexMap const*)valuePtr;
|
||||||
for (auto pair1 const& : map) {
|
for (MyPair const& pair1 : *map) {
|
||||||
for (auto pair2 const& : it.second) {
|
for (auto const& pair2 : pair1.second) {
|
||||||
_entries[pair1.first][pair2.first] += pair2.second;
|
_entries[pair1.first][pair2.first] += pair2.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,14 +53,14 @@ struct VertexSumAggregator : public IAggregator {
|
||||||
|
|
||||||
void parseAggregate(VPackSlice const& slice) override {
|
void parseAggregate(VPackSlice const& slice) override {
|
||||||
for (auto const& pair: VPackObjectIterator(slice)) {
|
for (auto const& pair: VPackObjectIterator(slice)) {
|
||||||
prgl_shard_t shard = it.key.getUInt();
|
prgl_shard_t shard = std::stoi(pair.key.copyString());
|
||||||
std::string key;
|
std::string key;
|
||||||
VPackLength i = 0;
|
VPackValueLength i = 0;
|
||||||
for (VPackSlice const& val : VPackArrayIterator(pair.value)) {
|
for (VPackSlice const& val : VPackArrayIterator(pair.value)) {
|
||||||
if (i % 2 == 0) {
|
if (i % 2 == 0) {
|
||||||
key = val.copyString();
|
key = val.copyString();
|
||||||
} else {
|
} else {
|
||||||
entries[shard][key] += val.getNumber<double>();
|
_entries[shard][key] += val.getNumber<double>();
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -68,16 +69,16 @@ struct VertexSumAggregator : public IAggregator {
|
||||||
|
|
||||||
void const* getAggregatedValue() const override { return &_entries; };
|
void const* getAggregatedValue() const override { return &_entries; };
|
||||||
|
|
||||||
void setAggregatedValue(VPackSlice slice) override {
|
void setAggregatedValue(VPackSlice const& slice) override {
|
||||||
for (auto const& pair : VPackObjectIterator(slice)) {
|
for (auto const& pair : VPackObjectIterator(slice)) {
|
||||||
prgl_shard_t shard = it.key.getUInt();
|
prgl_shard_t shard = std::stoi(pair.key.copyString());
|
||||||
std::string key;
|
std::string key;
|
||||||
VPackLength i = 0;
|
VPackValueLength i = 0;
|
||||||
for (VPackSlice const& val : VPackArrayIterator(pair.value)) {
|
for (VPackSlice const& val : VPackArrayIterator(pair.value)) {
|
||||||
if (i % 2 == 0) {
|
if (i % 2 == 0) {
|
||||||
key = val.copyString();
|
key = val.copyString();
|
||||||
} else {
|
} else {
|
||||||
entries[shard][key] = val.getNumber<double>();
|
_entries[shard][key] = val.getNumber<double>();
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -85,9 +86,14 @@ struct VertexSumAggregator : public IAggregator {
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(std::string const& key, VPackBuilder &builder) const override {
|
void serialize(std::string const& key, VPackBuilder &builder) const override {
|
||||||
builder.add(key, VPackValueType::Array);
|
builder.add(key, VPackValue(VPackValueType::Object));
|
||||||
for (T const& e : _entries) {
|
for (auto const& pair1 : _entries) {
|
||||||
builder.add(VPackValue(e));
|
builder.add(std::to_string(pair1.first), VPackValue(VPackValueType::Array));
|
||||||
|
for (auto const& pair2 : pair1.second) {
|
||||||
|
builder.add(VPackValue(pair2.first));
|
||||||
|
builder.add(VPackValue(pair2.second));
|
||||||
|
}
|
||||||
|
builder.close();
|
||||||
}
|
}
|
||||||
builder.close();
|
builder.close();
|
||||||
};
|
};
|
||||||
|
@ -101,12 +107,12 @@ struct VertexSumAggregator : public IAggregator {
|
||||||
double getAggregatedValue(prgl_shard_t shard, std::string const& key) {
|
double getAggregatedValue(prgl_shard_t shard, std::string const& key) {
|
||||||
auto const& it1 = _entries.find(shard);
|
auto const& it1 = _entries.find(shard);
|
||||||
if (it1 != _entries.end()) {
|
if (it1 != _entries.end()) {
|
||||||
auto const& it2 = it1.second.find(key);
|
auto const& it2 = it1->second.find(key);
|
||||||
if (it2 != it1.second.end()) {
|
if (it2 != it1->second.end()) {
|
||||||
return it2.second;
|
return it2->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _empty;
|
return _default;
|
||||||
}
|
}
|
||||||
|
|
||||||
//void setValue(prgl_shard_t shard, std::string const& key, double val) {
|
//void setValue(prgl_shard_t shard, std::string const& key, double val) {
|
||||||
|
@ -139,4 +145,5 @@ struct VertexSumAggregator : public IAggregator {
|
||||||
bool _permanent;
|
bool _permanent;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,10 +39,14 @@ struct PregelID {
|
||||||
PregelID() : shard(0), key("") {}
|
PregelID() : shard(0), key("") {}
|
||||||
PregelID(prgl_shard_t s, std::string const& k) : shard(s), key(k) {}
|
PregelID(prgl_shard_t s, std::string const& k) : shard(s), key(k) {}
|
||||||
|
|
||||||
inline bool operator==(const PregelID& rhs) {
|
inline bool operator==(const PregelID& rhs) const {
|
||||||
return shard == rhs.shard && key == rhs.key;
|
return shard == rhs.shard && key == rhs.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator<(const PregelID& rhs) const {
|
||||||
|
return shard < rhs.shard || (shard == rhs.shard && key < rhs.key);
|
||||||
|
}
|
||||||
|
|
||||||
bool inline isValid() const {
|
bool inline isValid() const {
|
||||||
return shard != invalid_prgl_shard && !key.empty();
|
return shard != invalid_prgl_shard && !key.empty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ class MessageIterator {
|
||||||
|
|
||||||
// postfix ++
|
// postfix ++
|
||||||
MessageIterator operator++(int) {
|
MessageIterator operator++(int) {
|
||||||
MessageIterator result(_data, _size);
|
MessageIterator result(*this);
|
||||||
++(*this);
|
++(*this);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,10 @@ class MasterContext {
|
||||||
return (const T*)_aggregators->getAggregatedValue(name);
|
return (const T*)_aggregators->getAggregatedValue(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline IAggregator* getAggregator(std::string const& name) {
|
||||||
|
return _aggregators->getAggregator(name);
|
||||||
|
}
|
||||||
|
|
||||||
inline void enterNextGlobalSuperstep() { _enterNextGSS = true; }
|
inline void enterNextGlobalSuperstep() { _enterNextGSS = true; }
|
||||||
|
|
||||||
virtual void preApplication(){};
|
virtual void preApplication(){};
|
||||||
|
|
Loading…
Reference in New Issue