@Override public Edge<T, LongValue> map(Edge<T, Tuple2<ET, Degrees>> edge) throws Exception { output.f0 = edge.f0; output.f1 = edge.f1; output.f2 = edge.f2.f1.getOutDegree(); return output; } }
@Override public void writeRecord(Vertex<T, Degrees> record) throws IOException { long degree = record.f1.getDegree().getValue(); long outDegree = record.f1.getOutDegree().getValue(); long inDegree = record.f1.getInDegree().getValue(); long unidirectionalEdgesAsSource = degree - inDegree; long unidirectionalEdgesAsTarget = degree - outDegree; long bidirectionalEdges = inDegree + outDegree - degree; vertexCount++; unidirectionalEdgeCount += unidirectionalEdgesAsSource + unidirectionalEdgesAsTarget; bidirectionalEdgeCount += bidirectionalEdges; triplet021dCount += unidirectionalEdgesAsSource * (unidirectionalEdgesAsSource - 1) / 2; triplet021uCount += unidirectionalEdgesAsTarget * (unidirectionalEdgesAsTarget - 1) / 2; triplet021cCount += unidirectionalEdgesAsSource * unidirectionalEdgesAsTarget; triplet111dCount += unidirectionalEdgesAsTarget * bidirectionalEdges; triplet111uCount += unidirectionalEdgesAsSource * bidirectionalEdges; triplet201Count += bidirectionalEdges * (bidirectionalEdges - 1) / 2; }
@Override public Tuple3<T, T, ByteValue> map(Edge<T, Tuple3<ET, Degrees, Degrees>> value) throws Exception { Tuple3<ET, Degrees, Degrees> degrees = value.f2; long sourceDegree = degrees.f1.getDegree().getValue(); long targetDegree = degrees.f2.getDegree().getValue(); if (sourceDegree < targetDegree || (sourceDegree == targetDegree && value.f0.compareTo(value.f1) < 0)) { output.f0 = value.f0; output.f1 = value.f1; output.f2 = forward; } else { output.f0 = value.f1; output.f1 = value.f0; output.f2 = reverse; } return output; } }
@Override public DataSet<Edge<K, Tuple3<EV, Degrees, Degrees>>> runInternal(Graph<K, VV, EV> input) throws Exception { // s, t, d(s) DataSet<Edge<K, Tuple2<EV, Degrees>>> edgeSourceDegrees = input .run(new EdgeSourceDegrees<K, VV, EV>() .setParallelism(parallelism)); // t, d(t) DataSet<Vertex<K, Degrees>> vertexDegrees = input .run(new VertexDegrees<K, VV, EV>() .setParallelism(parallelism)); // s, t, (d(s), d(t)) return edgeSourceDegrees .join(vertexDegrees, JoinHint.REPARTITION_HASH_SECOND) .where(1) .equalTo(0) .with(new JoinEdgeDegreeWithVertexDegree<>()) .setParallelism(parallelism) .name("Edge target degree"); } }
@Override public VertexMetrics<K, VV, EV> run(Graph<K, VV, EV> input) throws Exception { super.run(input); DataSet<Vertex<K, Degrees>> vertexDegree = input .run(new VertexDegrees<K, VV, EV>() .setIncludeZeroDegreeVertices(includeZeroDegreeVertices) .setParallelism(parallelism)); vertexMetricsHelper = new VertexMetricsHelper<>(); vertexDegree .output(vertexMetricsHelper) .name("Vertex metrics"); return this; }
@Override public DataSet<Vertex<K, Degrees>> runInternal(Graph<K, VV, EV> input) throws Exception { // s, t, bitmask DataSet<Tuple2<K, ByteValue>> vertexWithEdgeOrder = input.getEdges() .flatMap(new EmitAndFlipEdge<>()) .setParallelism(parallelism) .name("Emit and flip edge") .groupBy(0, 1) .reduceGroup(new ReduceBitmask<>()) .setParallelism(parallelism) .name("Reduce bitmask"); // s, d(s) DataSet<Vertex<K, Degrees>> vertexDegrees = vertexWithEdgeOrder .groupBy(0) .reduceGroup(new DegreeCount<>()) .setParallelism(parallelism) .name("Degree count"); if (includeZeroDegreeVertices.get()) { vertexDegrees = input.getVertices() .leftOuterJoin(vertexDegrees) .where(0) .equalTo(0) .with(new JoinVertexWithVertexDegrees<>()) .setParallelism(parallelism) .name("Zero degree vertices"); } return vertexDegrees; }
@Override public DataSet<Edge<K, Tuple2<EV, Degrees>>> runInternal(Graph<K, VV, EV> input) throws Exception { // t, d(t) DataSet<Vertex<K, Degrees>> vertexDegrees = input .run(new VertexDegrees<K, VV, EV>() .setParallelism(parallelism)); // s, t, d(t) return input.getEdges() .join(vertexDegrees, JoinHint.REPARTITION_HASH_SECOND) .where(1) .equalTo(0) .with(new JoinEdgeWithVertexDegree<>()) .setParallelism(parallelism) .name("Edge target degrees"); } }
@Override public EdgeMetrics<K, VV, EV> run(Graph<K, VV, EV> input) throws Exception { super.run(input); // s, t, (d(s), d(t)) DataSet<Edge<K, Tuple3<EV, Degrees, Degrees>>> edgeDegreesPair = input .run(new EdgeDegreesPair<K, VV, EV>() .setParallelism(parallelism)); // s, d(s), count of (u, v) where deg(u) < deg(v) or (deg(u) == deg(v) and u < v) DataSet<Tuple3<K, Degrees, LongValue>> edgeStats = edgeDegreesPair .flatMap(new EdgeStats<>()) .setParallelism(parallelism) .name("Edge stats") .groupBy(0, 1) .reduceGroup(new ReduceEdgeStats<>()) .setParallelism(parallelism) .name("Reduce edge stats") .groupBy(0) .reduce(new SumEdgeStats<>()) .setCombineHint(CombineHint.HASH) .setParallelism(parallelism) .name("Sum edge stats"); edgeMetricsHelper = new EdgeMetricsHelper<>(); edgeStats .output(edgeMetricsHelper) .setParallelism(parallelism) .name("Edge metrics"); return this; }
@Override public void flatMap(Vertex<T, Degrees> vertex, Collector<Tuple2<T, DoubleValue>> out) throws Exception { if (vertex.f1.getInDegree().getValue() == 0) { output.f0 = vertex.f0; out.collect(output); } } }
.run(new VertexDegrees<K, VV, EV>() .setIncludeZeroDegreeVertices(includeZeroDegreeVertices) .setParallelism(parallelism)); .run(new EdgeSourceDegrees<K, VV, EV>() .setParallelism(parallelism)) .map(new ExtractSourceDegree<>()) .setParallelism(parallelism)
@Override public void writeRecord(Vertex<T, Degrees> record) throws IOException { long degree = record.f1.getDegree().getValue(); long outDegree = record.f1.getOutDegree().getValue(); long inDegree = record.f1.getInDegree().getValue(); long bidirectionalEdges = outDegree + inDegree - degree; long triplets = degree * (degree - 1) / 2; vertexCount++; unidirectionalEdgeCount += degree - bidirectionalEdges; bidirectionalEdgeCount += bidirectionalEdges; tripletCount += triplets; maximumDegree = Math.max(maximumDegree, degree); maximumOutDegree = Math.max(maximumOutDegree, outDegree); maximumInDegree = Math.max(maximumInDegree, inDegree); maximumTriplets = Math.max(maximumTriplets, triplets); }
.run(new VertexDegrees<K, VV, EV>() .setIncludeZeroDegreeVertices(includeZeroDegreeVertices.get()) .setParallelism(parallelism));
@Override public DataSet<Edge<K, Tuple2<EV, Degrees>>> runInternal(Graph<K, VV, EV> input) throws Exception { // s, d(s) DataSet<Vertex<K, Degrees>> vertexDegrees = input .run(new VertexDegrees<K, VV, EV>() .setParallelism(parallelism)); // s, t, d(s) return input.getEdges() .join(vertexDegrees, JoinHint.REPARTITION_HASH_SECOND) .where(0) .equalTo(0) .with(new JoinEdgeWithVertexDegree<>()) .setParallelism(parallelism) .name("Edge source degrees"); } }
.run(new EdgeDegreesPair<K, VV, EV>() .setParallelism(parallelism));
@Override public Edge<T, LongValue> map(Edge<T, Tuple2<ET, Degrees>> edge) throws Exception { output.f0 = edge.f0; output.f1 = edge.f1; output.f2 = edge.f2.f1.getOutDegree(); return output; } }
@Override public void writeRecord(Tuple3<T, Degrees, LongValue> record) throws IOException { Degrees degrees = record.f1; long degree = degrees.getDegree().getValue(); long lowDegree = record.f2.getValue(); long highDegree = degree - lowDegree; long triangleTriplets = lowDegree * (lowDegree - 1) / 2; long rectangleTriplets = triangleTriplets + lowDegree * highDegree; triangleTripletCount += triangleTriplets; rectangleTripletCount += rectangleTriplets; maximumTriangleTriplets = Math.max(maximumTriangleTriplets, triangleTriplets); maximumRectangleTriplets = Math.max(maximumRectangleTriplets, rectangleTriplets); }
@Override public void reduce(Iterable<Tuple2<T, ByteValue>> values, Collector<Vertex<T, Degrees>> out) throws Exception { long degree = 0; long outDegree = 0; long inDegree = 0; for (Tuple2<T, ByteValue> edge : values) { output.f0 = edge.f0; byte bitmask = edge.f1.getValue(); degree++; if (bitmask == EdgeOrder.FORWARD.getBitmask()) { outDegree++; } else if (bitmask == EdgeOrder.REVERSE.getBitmask()) { inDegree++; } else { outDegree++; inDegree++; } } output.f1.getDegree().setValue(degree); output.f1.getOutDegree().setValue(outDegree); output.f1.getInDegree().setValue(inDegree); out.collect(output); } }
@Override public TriadicCensus<K, VV, EV> run(Graph<K, VV, EV> input) throws Exception { super.run(input); triangleListingHelper = new TriangleListingHelper<>(); input .run(new TriangleListing<K, VV, EV>() .setParallelism(parallelism)) .output(triangleListingHelper) .name("Triangle counts"); vertexDegreesHelper = new VertexDegreesHelper<>(); input .run(new VertexDegrees<K, VV, EV>() .setParallelism(parallelism)) .output(vertexDegreesHelper) .name("Edge and triplet counts"); return this; }
@Override public Edge<T, LongValue> map(Edge<T, Tuple2<ET, Degrees>> edge) throws Exception { output.f0 = edge.f0; output.f1 = edge.f1; output.f2 = edge.f2.f1.getOutDegree(); return output; } }
@Override public void flatMap(Edge<T, Tuple3<ET, Degrees, Degrees>> edge, Collector<Tuple4<T, T, Degrees, LongValue>> out) throws Exception { Tuple3<ET, Degrees, Degrees> degrees = edge.f2; long sourceDegree = degrees.f1.getDegree().getValue(); long targetDegree = degrees.f2.getDegree().getValue(); boolean ordered = (sourceDegree < targetDegree || (sourceDegree == targetDegree && edge.f0.compareTo(edge.f1) < 0)); output.f0 = edge.f0; output.f1 = edge.f1; output.f2 = edge.f2.f1; output.f3 = ordered ? one : zero; out.collect(output); output.f0 = edge.f1; output.f1 = edge.f0; output.f2 = edge.f2.f2; output.f3 = ordered ? zero : one; out.collect(output); } }