diff --git a/algo/src/main/java/org/neo4j/graphalgo/BalancedTriadsProc.java b/algo/src/main/java/org/neo4j/graphalgo/BalancedTriadsProc.java index ac046a40c..2fc29e15c 100644 --- a/algo/src/main/java/org/neo4j/graphalgo/BalancedTriadsProc.java +++ b/algo/src/main/java/org/neo4j/graphalgo/BalancedTriadsProc.java @@ -18,6 +18,8 @@ */ package org.neo4j.graphalgo; +import com.carrotsearch.hppc.LongLongMap; +import org.HdrHistogram.Histogram; import org.neo4j.graphalgo.api.HugeGraph; import org.neo4j.graphalgo.core.GraphLoader; import org.neo4j.graphalgo.core.ProcedureConfiguration; @@ -26,7 +28,7 @@ import org.neo4j.graphalgo.core.utils.paged.PagedAtomicIntegerArray; import org.neo4j.graphalgo.core.write.Exporter; import org.neo4j.graphalgo.impl.triangle.*; -import org.neo4j.graphalgo.results.AbstractResultBuilder; +import org.neo4j.graphalgo.results.AbstractCommunityResultBuilder; import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.internal.GraphDatabaseAPI; import org.neo4j.logging.Log; @@ -68,7 +70,7 @@ public Stream balancedTriadsStream( final HugeGraph graph = (HugeGraph) new GraphLoader(api, Pools.DEFAULT) .withOptionalLabel(configuration.getNodeLabelOrQuery()) .withOptionalRelationshipType(configuration.getRelationshipOrQuery()) - .withRelationshipWeightsFromProperty(configuration.getWeightProperty(), 0.0) + .withOptionalRelationshipWeightsFromProperty(configuration.getWeightProperty(), 0.0) .withoutNodeWeights() .withSort(true) .withLog(log) @@ -113,7 +115,7 @@ public Stream balancedTriads( graph = (HugeGraph) new GraphLoader(api, Pools.DEFAULT) .withOptionalLabel(configuration.getNodeLabelOrQuery()) .withOptionalRelationshipType(configuration.getRelationshipOrQuery()) - .withRelationshipWeightsFromProperty(configuration.getWeightProperty(), 0.0) + .withOptionalRelationshipWeightsFromProperty(configuration.getWeightProperty(), 0.0) .withoutNodeWeights() .withSort(true) .withLog(log) @@ -132,26 +134,33 @@ public Stream balancedTriads( // write if (configuration.isWriteFlag()) { + builder.withWrite(true); + + String balancedProperty = configuration.get("balancedProperty", DEFAULT_BALANCED_PROPERTY); + builder.withBalancedProperty(balancedProperty); + + String unbalancedProperty = configuration.get("unbalancedProperty", DEFAULT_UNBALANCED_PROPERTY); + builder.withUnbalancedProperty(unbalancedProperty); + try (ProgressTimer timer = builder.timeWrite()) { Exporter.of(api, graph) .withLog(log) .parallel(Pools.DEFAULT, configuration.getConcurrency(), terminationFlag) .build() .write( - configuration.get("balancedProperty", DEFAULT_BALANCED_PROPERTY), + balancedProperty, balancedTriads.getBalancedTriangles(), PagedAtomicIntegerArray.Translator.INSTANCE, - configuration.get("unbalancedProperty", DEFAULT_UNBALANCED_PROPERTY), + unbalancedProperty, balancedTriads.getUnbalancedTriangles(), PagedAtomicIntegerArray.Translator.INSTANCE); } } // result - return Stream.of(builder.withNodeCount(graph.nodeCount()) - .withBalancedTriadCount(balancedTriads.getBalancedTriangleCount()) - .withUnbalancedTriadCount(balancedTriads.getUnbalancedTriangleCount()) - .build()); + builder.withBalancedTriadCount(balancedTriads.getBalancedTriangleCount()) + .withUnbalancedTriadCount(balancedTriads.getUnbalancedTriangleCount()); + return Stream.of(builder.buildII(graph.nodeCount(), balancedTriads.getBalancedTriangles()::get)); } /** @@ -162,54 +171,105 @@ public static class Result { public final long loadMillis; public final long computeMillis; public final long writeMillis; + public final long postProcessingMillis; + public final long nodeCount; public final long balancedTriadCount; public final long unbalancedTriadCount; + public final long p1; + public final long p5; + public final long p10; + public final long p25; + public final long p50; + public final long p75; + public final long p90; + public final long p95; + public final long p99; + public final long p100; + + public final boolean write; + public final String balancedProperty; + public final String unbalancedProperty; + + public Result( long loadMillis, long computeMillis, long writeMillis, - long nodeCount, long balancedTriadCount, long unbalancedTriadCount) { + long postProcessingMillis, + long nodeCount, long balancedTriadCount, + long unbalancedTriadCount, + long p100, long p99, long p95, long p90, long p75, long p50, long p25, long p10, long p5, long p1, boolean write, String balancedProperty, String unbalancedProperty) { this.loadMillis = loadMillis; this.computeMillis = computeMillis; this.writeMillis = writeMillis; + this.postProcessingMillis = postProcessingMillis; this.nodeCount = nodeCount; this.balancedTriadCount = balancedTriadCount; this.unbalancedTriadCount = unbalancedTriadCount; + this.p100 = p100; + this.p99 = p99; + this.p95 = p95; + this.p90 = p90; + this.p75 = p75; + this.p50 = p50; + this.p25 = p25; + this.p10 = p10; + this.p5 = p5; + this.p1 = p1; + this.write = write; + this.balancedProperty = balancedProperty; + this.unbalancedProperty = unbalancedProperty; } } - public class BalancedTriadsResultBuilder extends AbstractResultBuilder { + public class BalancedTriadsResultBuilder extends AbstractCommunityResultBuilder { - private long nodeCount = 0; private long balancedTriadCount = 0; private long unbalancedTriadCount = 0; + private String balancedProperty; + private String unbalancedProperty; - public BalancedTriadsResultBuilder withNodeCount(long nodeCount) { - this.nodeCount = nodeCount; - return this; - } public BalancedTriadsResultBuilder withBalancedTriadCount(long balancedTriadCount) { this.balancedTriadCount = balancedTriadCount; return this; } + public BalancedTriadsResultBuilder withBalancedProperty(String property) { + this.balancedProperty = property; + return this; + } + + public BalancedTriadsResultBuilder withUnbalancedProperty(String property) { + this.unbalancedProperty = property; + return this; + } + public BalancedTriadsResultBuilder withUnbalancedTriadCount(long unbalancedTriadCount) { this.unbalancedTriadCount = unbalancedTriadCount; return this; } @Override - public Result build() { + protected Result build(long loadMillis, long computeMillis, long writeMillis, long postProcessingMillis, long nodeCount, long communityCount, LongLongMap communitySizeMap, Histogram communityHistogram, boolean write) { return new Result( - loadDuration, - evalDuration, - writeDuration, - nodeCount, - balancedTriadCount, - unbalancedTriadCount); + loadMillis, computeMillis, writeMillis, postProcessingMillis, nodeCount, balancedTriadCount, unbalancedTriadCount, + communityHistogram.getValueAtPercentile(100), + communityHistogram.getValueAtPercentile(99), + communityHistogram.getValueAtPercentile(95), + communityHistogram.getValueAtPercentile(90), + communityHistogram.getValueAtPercentile(75), + communityHistogram.getValueAtPercentile(50), + communityHistogram.getValueAtPercentile(25), + communityHistogram.getValueAtPercentile(10), + communityHistogram.getValueAtPercentile(5), + communityHistogram.getValueAtPercentile(1), + write, + balancedProperty, + unbalancedProperty + ); } } diff --git a/algo/src/main/java/org/neo4j/graphalgo/LabelPropagationProc.java b/algo/src/main/java/org/neo4j/graphalgo/LabelPropagationProc.java index c48b1e753..e686e513e 100644 --- a/algo/src/main/java/org/neo4j/graphalgo/LabelPropagationProc.java +++ b/algo/src/main/java/org/neo4j/graphalgo/LabelPropagationProc.java @@ -110,6 +110,7 @@ public Stream labelPropagation( final int[] labels = compute(direction, iterations, batchSize, concurrency, graph, stats); if (configuration.isWriteFlag(DEFAULT_WRITE) && partitionProperty != null) { + stats.withWrite(true); write(concurrency, partitionProperty, graph, labels, stats); } @@ -218,7 +219,6 @@ private void write( HeavyGraph graph, int[] labels, LabelPropagationStats.Builder stats) { - stats.write(true); try (ProgressTimer timer = stats.timeWrite()) { Exporter.of(dbAPI, graph) .withLog(log) diff --git a/algo/src/main/java/org/neo4j/graphalgo/LouvainProc.java b/algo/src/main/java/org/neo4j/graphalgo/LouvainProc.java index fd5399fc7..5c2c1b056 100644 --- a/algo/src/main/java/org/neo4j/graphalgo/LouvainProc.java +++ b/algo/src/main/java/org/neo4j/graphalgo/LouvainProc.java @@ -105,7 +105,18 @@ public Stream louvain( } if (configuration.isWriteFlag()) { - builder.timeWrite(() -> write(graph, louvain.getDendrogram(), louvain.getCommunityIds(), configuration)); + builder.timeWrite(() -> { + String writeProperty = configuration.getWriteProperty("community"); + boolean includeIntermediateCommunities = configuration.get(INCLUDE_INTERMEDIATE_COMMUNITIES, false); + String intermediateCommunitiesWriteProperty = configuration.get(INTERMEDIATE_COMMUNITIES_WRITE_PROPERTY, "communities"); + + builder.withWrite(true); + builder.withWriteProperty(writeProperty); + builder.withIntermediateCommunities(includeIntermediateCommunities); + builder.withIntermediateCommunitiesWriteProperty(intermediateCommunitiesWriteProperty); + + write(graph, louvain.getDendrogram(), louvain.getCommunityIds(), configuration, writeProperty, includeIntermediateCommunities, intermediateCommunitiesWriteProperty); + }); } builder.withIterations(louvain.getLevel()); @@ -170,9 +181,8 @@ public Graph graph(String label, String relationship, ProcedureConfiguration con .load(config.getGraphImpl()); } - private void write(Graph graph, int[][] allCommunities, int[] finalCommunities, ProcedureConfiguration configuration) { + private void write(Graph graph, int[][] allCommunities, int[] finalCommunities, ProcedureConfiguration configuration, String writeProperty, boolean includeIntermediateCommunities, String intermediateCommunitiesPropertyName) { log.debug("Writing results"); - boolean includeIntermediateCommunities = configuration.get(INCLUDE_INTERMEDIATE_COMMUNITIES, false); new LouvainCommunityExporter( api, @@ -180,8 +190,8 @@ private void write(Graph graph, int[][] allCommunities, int[] finalCommunities, configuration.getConcurrency(), graph, finalCommunities.length, - configuration.getWriteProperty("community"), - configuration.get(INTERMEDIATE_COMMUNITIES_WRITE_PROPERTY, "communities")) + writeProperty, + intermediateCommunitiesPropertyName) .export(allCommunities, finalCommunities, includeIntermediateCommunities); } @@ -205,29 +215,37 @@ public static class LouvainResult { -1, -1, 0, - new double[] {}, -1); + new double[] {}, -1, false, null, false, null); public final long loadMillis; public final long computeMillis; - public final long postProcessingMillis; public final long writeMillis; + public final long postProcessingMillis; public final long nodes; public final long communityCount; - public final long p100; - public final long p99; - public final long p95; - public final long p90; - public final long p75; - public final long p50; - public final long p25; - public final long p10; - public final long p05; - public final long p01; public final long iterations; public final List modularities; public final double modularity; - - public LouvainResult(long loadMillis, long computeMillis, long postProcessingMillis, long writeMillis, long nodes, long communityCount, long p100, long p99, long p95, long p90, long p75, long p50, long p25, long p10, long p05, long p01, long iterations, double[] modularities, double finalModularity) { + public final long p1; + public final long p5; + public final long p10; + public final long p25; + public final long p50; + public final long p75; + public final long p90; + public final long p95; + public final long p99; + public final long p100; + public final boolean write; + public final String writeProperty; + public final boolean includeIntermediateCommunities; + public final String intermediateCommunitiesWriteProperty; + + public LouvainResult(long loadMillis, long computeMillis, long postProcessingMillis, long writeMillis, long nodes, + long communityCount, long p100, long p99, long p95, long p90, long p75, long p50, long p25, long p10, long p5, long p1, + long iterations, double[] modularities, double finalModularity, + boolean write, String writeProperty, + boolean includeIntermediateCommunities, String intermediateCommunitiesWriteProperty) { this.loadMillis = loadMillis; this.computeMillis = computeMillis; this.postProcessingMillis = postProcessingMillis; @@ -242,12 +260,16 @@ public LouvainResult(long loadMillis, long computeMillis, long postProcessingMil this.p50 = p50; this.p25 = p25; this.p10 = p10; - this.p05 = p05; - this.p01 = p01; + this.p5 = p5; + this.p1 = p1; this.iterations = iterations; this.modularities = new ArrayList<>(modularities.length); + this.write = write; + this.includeIntermediateCommunities = includeIntermediateCommunities; for (double mod : modularities) this.modularities.add(mod); this.modularity = finalModularity; + this.writeProperty = writeProperty; + this.intermediateCommunitiesWriteProperty = intermediateCommunitiesWriteProperty; } } @@ -256,6 +278,14 @@ public static class Builder extends AbstractCommunityResultBuilder sccTarjan( final int[] connectedComponents = tarjan.getConnectedComponents(); if (configuration.isWriteFlag()) { + builder.withWrite(true); + String partitionProperty = configuration.get(CONFIG_WRITE_PROPERTY, CONFIG_CLUSTER); + builder.withPartitionProperty(partitionProperty); + builder.timeWrite(() -> { graph.release(); tarjan.release(); @@ -131,7 +135,7 @@ public Stream sccTarjan( .parallel(Pools.DEFAULT, configuration.getConcurrency(), terminationFlag) .build() .write( - configuration.get(CONFIG_WRITE_PROPERTY, CONFIG_CLUSTER), + partitionProperty, connectedComponents, Translators.OPTIONAL_INT_ARRAY_TRANSLATOR ); @@ -174,13 +178,17 @@ public Stream sccTunedTarjan( builder.timeEval(tarjan::compute); if (configuration.isWriteFlag()) { + builder.withWrite(true); + String partitionProperty = configuration.get(CONFIG_WRITE_PROPERTY, CONFIG_CLUSTER); + builder.withPartitionProperty(partitionProperty); + builder.timeWrite(() -> Exporter .of(api, graph) .withLog(log) .parallel(Pools.DEFAULT, configuration.getConcurrency(), terminationFlag) .build() .write( - configuration.get(CONFIG_WRITE_PROPERTY, CONFIG_CLUSTER), + partitionProperty, tarjan.getConnectedComponents(), Translators.OPTIONAL_INT_ARRAY_TRANSLATOR )); @@ -252,7 +260,11 @@ public Stream sccIterativeTarjan( builder.timeEval(tarjan::compute); if (configuration.isWriteFlag()) { - builder.timeWrite(() -> write(configuration, graph, terminationFlag, tarjan)); + builder.withWrite(true); + String partitionProperty = configuration.get(CONFIG_WRITE_PROPERTY, CONFIG_CLUSTER); + builder.withPartitionProperty(partitionProperty); + + builder.timeWrite(() -> write(configuration, graph, terminationFlag, tarjan, partitionProperty)); } if (graph instanceof HugeGraph) { @@ -264,7 +276,7 @@ public Stream sccIterativeTarjan( return Stream.of(builder.build(graph.nodeCount(), l -> (long) connectedComponents[((int) l)])); } - private void write(ProcedureConfiguration configuration, Graph graph, TerminationFlag terminationFlag, SCCAlgorithm tarjan) { + private void write(ProcedureConfiguration configuration, Graph graph, TerminationFlag terminationFlag, SCCAlgorithm tarjan, String partitionProperty) { if (graph instanceof HugeGraph) { final HugeLongArray connectedComponents = tarjan.getConnectedComponents(); @@ -275,7 +287,7 @@ private void write(ProcedureConfiguration configuration, Graph graph, Terminatio .parallel(Pools.DEFAULT, configuration.getConcurrency(), terminationFlag) .build() .write( - configuration.get(CONFIG_WRITE_PROPERTY, CONFIG_CLUSTER), + partitionProperty, connectedComponents, HugeLongArray.Translator.INSTANCE ); @@ -288,7 +300,7 @@ private void write(ProcedureConfiguration configuration, Graph graph, Terminatio .parallel(Pools.DEFAULT, configuration.getConcurrency(), terminationFlag) .build() .write( - configuration.get(CONFIG_WRITE_PROPERTY, CONFIG_CLUSTER), + partitionProperty, connectedComponents, Translators.OPTIONAL_INT_ARRAY_TRANSLATOR ); @@ -368,16 +380,22 @@ public Stream multistep( if (configuration.isWriteFlag()) { graph.release(); multistep.release(); - builder.timeWrite(() -> Exporter - .of(api, graph) - .withLog(log) - .parallel(Pools.DEFAULT, configuration.getConcurrency(), terminationFlag) - .build() - .write( - configuration.get(CONFIG_WRITE_PROPERTY, CONFIG_CLUSTER), - connectedComponents, - Translators.OPTIONAL_INT_ARRAY_TRANSLATOR - )); + builder.timeWrite(() -> { + builder.withWrite(true); + String partitionProperty = configuration.get(CONFIG_WRITE_PROPERTY, CONFIG_CLUSTER); + builder.withPartitionProperty(partitionProperty); + + Exporter + .of(api, graph) + .withLog(log) + .parallel(Pools.DEFAULT, configuration.getConcurrency(), terminationFlag) + .build() + .write( + partitionProperty, + connectedComponents, + Translators.OPTIONAL_INT_ARRAY_TRANSLATOR + ); + }); } return Stream.of(builder.build(graph.nodeCount(), l -> (long) connectedComponents[((int) l)])); diff --git a/algo/src/main/java/org/neo4j/graphalgo/TriangleProc.java b/algo/src/main/java/org/neo4j/graphalgo/TriangleProc.java index 1adb52aed..9e8381c86 100644 --- a/algo/src/main/java/org/neo4j/graphalgo/TriangleProc.java +++ b/algo/src/main/java/org/neo4j/graphalgo/TriangleProc.java @@ -218,8 +218,15 @@ public Stream triangleCountQueue( } if (configuration.isWriteFlag()) { + builder.withWrite(true); try (ProgressTimer timer = builder.timeWrite()) { - write(graph, triangleCount, configuration, terminationFlag); + String writeProperty = configuration.getWriteProperty(DEFAULT_WRITE_PROPERTY_VALUE); + Optional clusteringCoefficientProperty = configuration.getString(COEFFICIENT_WRITE_PROPERTY_VALUE); + + builder.withWriteProperty(writeProperty); + builder.withClusteringCoefficientProperty(clusteringCoefficientProperty); + + write(graph, triangleCount, configuration, terminationFlag, writeProperty, clusteringCoefficientProperty); } } @@ -248,10 +255,10 @@ private Stream buildResult(TriangleCountResultBuilder builder, Graph gra * @param algorithm Impl. of TriangleCountAlgorithm * @param configuration configuration wrapper * @param flag termination flag + * @param writeProperty + * @param coefficientProperty */ - private void write(Graph graph, TriangleCountAlgorithm algorithm, ProcedureConfiguration configuration, TerminationFlag flag) { - - final Optional coefficientProperty = configuration.getString(COEFFICIENT_WRITE_PROPERTY_VALUE); + private void write(Graph graph, TriangleCountAlgorithm algorithm, ProcedureConfiguration configuration, TerminationFlag flag, String writeProperty, Optional coefficientProperty) { final Exporter exporter = Exporter.of(api, graph) .withLog(log) @@ -264,7 +271,7 @@ private void write(Graph graph, TriangleCountAlgorithm algorithm, ProcedureConfi final DoubleArray coefficients = ((IntersectingTriangleCount) algorithm).getCoefficients(); final PagedAtomicIntegerArray triangles = ((IntersectingTriangleCount) algorithm).getTriangles(); exporter.write( - configuration.getWriteProperty(DEFAULT_WRITE_PROPERTY_VALUE), + writeProperty, triangles, PagedAtomicIntegerArray.Translator.INSTANCE, coefficientProperty.get(), @@ -275,7 +282,7 @@ private void write(Graph graph, TriangleCountAlgorithm algorithm, ProcedureConfi // huge without coefficients final PagedAtomicIntegerArray triangles = ((IntersectingTriangleCount) algorithm).getTriangles(); exporter.write( - configuration.getWriteProperty(DEFAULT_WRITE_PROPERTY_VALUE), + writeProperty, triangles, PagedAtomicIntegerArray.Translator.INSTANCE ); @@ -287,7 +294,7 @@ private void write(Graph graph, TriangleCountAlgorithm algorithm, ProcedureConfi final double[] coefficients = ((TriangleCountQueue) algorithm).getCoefficients(); final AtomicIntegerArray triangles = ((TriangleCountQueue) algorithm).getTriangles(); exporter.write( - configuration.getWriteProperty(DEFAULT_WRITE_PROPERTY_VALUE), + writeProperty, triangles, Translators.ATOMIC_INTEGER_ARRAY_TRANSLATOR, coefficientProperty.get(), @@ -298,7 +305,7 @@ private void write(Graph graph, TriangleCountAlgorithm algorithm, ProcedureConfi // nonhuge without coefficients final AtomicIntegerArray triangles = ((TriangleCountQueue) algorithm).getTriangles(); exporter.write( - configuration.getWriteProperty(DEFAULT_WRITE_PROPERTY_VALUE), + writeProperty, triangles, Translators.ATOMIC_INTEGER_ARRAY_TRANSLATOR ); @@ -409,27 +416,32 @@ public static class Result { -1, -1, -1, - .0); + .0, false, null, null); public final long loadMillis; public final long computeMillis; - public final long postProcessingMillis; public final long writeMillis; + public final long postProcessingMillis; public final long nodeCount; public final long triangleCount; - public final long p100; - public final long p99; - public final long p95; - public final long p90; - public final long p75; - public final long p50; - public final long p25; - public final long p10; - public final long p05; - public final long p01; public final double averageClusteringCoefficient; + public final long p1; + public final long p5; + public final long p10; + public final long p25; + public final long p50; + public final long p75; + public final long p90; + public final long p95; + public final long p99; + public final long p100; + public final boolean write; + public final String writeProperty; + public final String clusteringCoefficientProperty; - public Result(long loadMillis, long computeMillis, long postProcessingMillis, long writeMillis, long nodeCount, long triangleCount, long p100, long p99, long p95, long p90, long p75, long p50, long p25, long p10, long p05, long p01, double averageClusteringCoefficient) { + public Result(long loadMillis, long computeMillis, long postProcessingMillis, long writeMillis, long nodeCount, + long triangleCount, long p100, long p99, long p95, long p90, long p75, long p50, long p25, long p10, long p5, long p1, + double averageClusteringCoefficient, boolean write, String writeProperty, String clusteringCoefficientProperty) { this.loadMillis = loadMillis; this.computeMillis = computeMillis; this.postProcessingMillis = postProcessingMillis; @@ -445,8 +457,11 @@ public Result(long loadMillis, long computeMillis, long postProcessingMillis, lo this.p50 = p50; this.p25 = p25; this.p10 = p10; - this.p05 = p05; - this.p01 = p01; + this.p5 = p5; + this.p1 = p1; + this.write = write; + this.writeProperty = writeProperty; + this.clusteringCoefficientProperty= clusteringCoefficientProperty; } } @@ -454,6 +469,8 @@ public class TriangleCountResultBuilder extends AbstractCommunityResultBuilder clusteringCoefficientProperty) { + this.clusteringCoefficientProperty = clusteringCoefficientProperty.orElse(null); + return this; + } } } diff --git a/algo/src/main/java/org/neo4j/graphalgo/impl/UnionFindProcExec.java b/algo/src/main/java/org/neo4j/graphalgo/impl/UnionFindProcExec.java index 5fea95e09..c9c6360a3 100644 --- a/algo/src/main/java/org/neo4j/graphalgo/impl/UnionFindProcExec.java +++ b/algo/src/main/java/org/neo4j/graphalgo/impl/UnionFindProcExec.java @@ -86,7 +86,11 @@ public static Stream run( graph.release(); if (configuration.isWriteFlag()) { - uf.write(builder::timeWrite, graph, dssResult, configuration); + String writeProperty = configuration.get(CONFIG_CLUSTER_PROPERTY, DEFAULT_CLUSTER_PROPERTY); + builder.withWrite(true); + builder.withPartitionProperty(writeProperty); + + uf.write(builder::timeWrite, graph, dssResult, configuration, writeProperty); } if (dssResult.isHuge) { @@ -114,34 +118,37 @@ public static class UnionFindResult { -1, -1, -1, - -1 - ); + -1, + false, null); public final long loadMillis; public final long computeMillis; - public final long postProcessingMillis; public final long writeMillis; + public final long postProcessingMillis; public final long nodes; public final long communityCount; public final long setCount; - public final long p100; - public final long p99; - public final long p95; - public final long p90; - public final long p75; - public final long p50; - public final long p25; + public final long p1; + public final long p5; public final long p10; - public final long p05; - public final long p01; + public final long p25; + public final long p50; + public final long p75; + public final long p90; + public final long p95; + public final long p99; + public final long p100; + public final boolean write; + public final String partitionProperty; - public UnionFindResult(long loadMillis, long computeMillis, long postProcessingMillis, long writeMillis, long nodes, long communityCount, long p100, long p99, long p95, long p90, long p75, long p50, long p25, long p10, long p05, long p01) { + + public UnionFindResult(long loadMillis, long computeMillis, long postProcessingMillis, long writeMillis, long nodes, long communityCount, long p100, long p99, long p95, long p90, long p75, long p50, long p25, long p10, long p5, long p1, boolean write, String partitionProperty) { this.loadMillis = loadMillis; this.computeMillis = computeMillis; - this.postProcessingMillis = postProcessingMillis; this.writeMillis = writeMillis; + this.postProcessingMillis = postProcessingMillis; this.nodes = nodes; - this.communityCount = communityCount; + this.communityCount = this.setCount = communityCount; this.p100 = p100; this.p99 = p99; this.p95 = p95; @@ -150,15 +157,18 @@ public UnionFindResult(long loadMillis, long computeMillis, long postProcessingM this.p50 = p50; this.p25 = p25; this.p10 = p10; - this.p05 = p05; - this.p01 = p01; - this.setCount = communityCount; + this.p5 = p5; + this.p1 = p1; + this.write = write; + this.partitionProperty = partitionProperty; } } public static class Builder extends AbstractCommunityResultBuilder { + private String partitionProperty; + @Override - protected UnionFindResult build(long loadMillis, long computeMillis, long writeMillis, long postProcessingMillis, long nodeCount, long communityCount, LongLongMap communitySizeMap, Histogram communityHistogram) { + protected UnionFindResult build(long loadMillis, long computeMillis, long writeMillis, long postProcessingMillis, long nodeCount, long communityCount, LongLongMap communitySizeMap, Histogram communityHistogram, boolean write) { return new UnionFindResult( loadMillis, computeMillis, @@ -175,9 +185,16 @@ protected UnionFindResult build(long loadMillis, long computeMillis, long writeM communityHistogram.getValueAtPercentile(25), communityHistogram.getValueAtPercentile(10), communityHistogram.getValueAtPercentile(5), - communityHistogram.getValueAtPercentile(1) + communityHistogram.getValueAtPercentile(1), + write, + partitionProperty ); } + + public Builder withPartitionProperty(String partitionProperty) { + this.partitionProperty = partitionProperty; + return null; + } } public static Stream stream( @@ -272,16 +289,16 @@ private void write( Supplier timer, Graph graph, DSSResult struct, - ProcedureConfiguration configuration) { + ProcedureConfiguration configuration, String writeProperty) { try (ProgressTimer ignored = timer.get()) { - write(graph, struct, configuration); + write(graph, struct, configuration, writeProperty); } } private void write( Graph graph, DSSResult struct, - ProcedureConfiguration configuration) { + ProcedureConfiguration configuration, String writeProperty) { log.debug("Writing results"); Exporter exporter = Exporter.of(api, graph) .withLog(log) @@ -291,9 +308,9 @@ private void write( TerminationFlag.wrap(transaction)) .build(); if (struct.hugeStruct != null) { - write(exporter, struct.hugeStruct, configuration); + write(exporter, struct.hugeStruct, writeProperty); } else { - write(exporter, struct.struct, configuration); + write(exporter, struct.struct, writeProperty); } } @@ -305,24 +322,18 @@ public void accept(final String name, final Algorithm algorithm) { private void write( Exporter exporter, - DisjointSetStruct struct, - ProcedureConfiguration configuration) { + DisjointSetStruct struct, String writeProperty) { exporter.write( - configuration.get( - CONFIG_CLUSTER_PROPERTY, - DEFAULT_CLUSTER_PROPERTY), + writeProperty, struct, DisjointSetStruct.Translator.INSTANCE); } private void write( Exporter exporter, - PagedDisjointSetStruct struct, - ProcedureConfiguration configuration) { + PagedDisjointSetStruct struct, String writeProperty) { exporter.write( - configuration.get( - CONFIG_CLUSTER_PROPERTY, - DEFAULT_CLUSTER_PROPERTY), + writeProperty, struct, PagedDisjointSetStruct.Translator.INSTANCE); } diff --git a/algo/src/main/java/org/neo4j/graphalgo/results/AbstractCommunityResultBuilder.java b/algo/src/main/java/org/neo4j/graphalgo/results/AbstractCommunityResultBuilder.java index f7241eaac..d596ded4b 100644 --- a/algo/src/main/java/org/neo4j/graphalgo/results/AbstractCommunityResultBuilder.java +++ b/algo/src/main/java/org/neo4j/graphalgo/results/AbstractCommunityResultBuilder.java @@ -2,12 +2,9 @@ import com.carrotsearch.hppc.LongLongMap; import com.carrotsearch.hppc.LongLongScatterMap; -import com.carrotsearch.hppc.cursors.LongLongCursor; import org.HdrHistogram.Histogram; import org.neo4j.graphalgo.core.utils.ProgressTimer; -import java.util.Arrays; -import java.util.List; import java.util.function.IntFunction; import java.util.function.LongFunction; import java.util.function.LongToIntFunction; @@ -20,6 +17,7 @@ public abstract class AbstractCommunityResultBuilder { protected long loadDuration = -1; protected long evalDuration = -1; protected long writeDuration = -1; + protected boolean write = false; public AbstractCommunityResultBuilder withLoadDuration(long loadDuration) { this.loadDuration = loadDuration; @@ -38,6 +36,11 @@ public AbstractCommunityResultBuilder withWriteDuration(long writeDuration) { return this; } + public AbstractCommunityResultBuilder withWrite(boolean write) { + this.write = write; + return this; + } + /** * returns an AutoClosable which measures the time * until it gets closed. Saves the duration as loadMillis @@ -101,12 +104,53 @@ public void timeWrite(Runnable runnable) { } } - public T buildII(long nodes, IntFunction fun) { - return build(nodes, value -> (long) fun.apply((int) value)); + public T buildII(long nodeCount, IntFunction fun) { + final ProgressTimer timer = ProgressTimer.start(); + final Histogram histogram = new Histogram(2); + for (int nodeId = 0; nodeId < nodeCount; nodeId++) { + final long size = fun.apply(nodeId); + histogram.recordValue(size); + } + + timer.stop(); + + final LongLongMap communitySizeMap = new LongLongScatterMap(); + return build(loadDuration, + evalDuration, + writeDuration, + timer.getDuration(), + nodeCount, + communitySizeMap.size(), + communitySizeMap, + histogram, + write + ); + + } - public T buildLI(long nodes, LongToIntFunction fun) { - return build(nodes, value -> (long) fun.applyAsInt(value)); + public T buildLI(long nodeCount, LongToIntFunction fun) { + + final Histogram histogram = new Histogram(2); + final ProgressTimer timer = ProgressTimer.start(); + for (int nodeId = 0; nodeId < nodeCount; nodeId++) { + final long size = fun.applyAsInt(nodeId); + histogram.recordValue(size); + } + + timer.stop(); + + final LongLongMap communitySizeMap = new LongLongScatterMap(); + return build(loadDuration, + evalDuration, + writeDuration, + timer.getDuration(), + nodeCount, + communitySizeMap.size(), + communitySizeMap, + histogram, + write + ); } /** @@ -116,11 +160,9 @@ public T build(long nodeCount, LongFunction fun) { final LongLongMap communitySizeMap = new LongLongScatterMap(); final ProgressTimer timer = ProgressTimer.start(); - for (int i = 0; i < nodeCount; i++) { - // map to community id - final long cId = fun.apply(i); - // aggregate community size - communitySizeMap.addTo(cId, 1); + for (int nodeId = 0; nodeId < nodeCount; nodeId++) { + final long communityId = fun.apply(nodeId); + communitySizeMap.addTo(communityId, 1); } Histogram histogram = CommunityHistogram.buildFrom(communitySizeMap); @@ -134,7 +176,8 @@ public T build(long nodeCount, LongFunction fun) { nodeCount, communitySizeMap.size(), communitySizeMap, - histogram + histogram, + write ); } @@ -146,6 +189,7 @@ protected abstract T build( long nodeCount, long communityCount, LongLongMap communitySizeMap, - Histogram communityHistogram); + Histogram communityHistogram, + boolean write); } diff --git a/algo/src/main/java/org/neo4j/graphalgo/results/DefaultCommunityResult.java b/algo/src/main/java/org/neo4j/graphalgo/results/DefaultCommunityResult.java index 4eb0e8a17..d5aba4d21 100644 --- a/algo/src/main/java/org/neo4j/graphalgo/results/DefaultCommunityResult.java +++ b/algo/src/main/java/org/neo4j/graphalgo/results/DefaultCommunityResult.java @@ -3,9 +3,6 @@ import com.carrotsearch.hppc.LongLongMap; import org.HdrHistogram.Histogram; -import java.util.Collections; -import java.util.List; - /** * @author mknblch */ @@ -17,20 +14,20 @@ public class DefaultCommunityResult { public final long loadMillis; public final long computeMillis; - public final long postProcessingMillis; public final long writeMillis; + public final long postProcessingMillis; public final long nodes; public final long communityCount; - public final long p100; - public final long p99; - public final long p95; - public final long p90; - public final long p75; - public final long p50; - public final long p25; + public final long p1; + public final long p5; public final long p10; - public final long p05; - public final long p01; + public final long p25; + public final long p50; + public final long p75; + public final long p90; + public final long p95; + public final long p99; + public final long p100; public DefaultCommunityResult(long loadMillis, long computeMillis, @@ -46,8 +43,8 @@ public DefaultCommunityResult(long loadMillis, long p50, long p25, long p10, - long p05, - long p01) { + long p5, + long p1) { this.loadMillis = loadMillis; this.computeMillis = computeMillis; this.postProcessingMillis = postProcessingMillis; @@ -62,14 +59,14 @@ public DefaultCommunityResult(long loadMillis, this.p50 = p50; this.p25 = p25; this.p10 = p10; - this.p05 = p05; - this.p01 = p01; + this.p5 = p5; + this.p1 = p1; } public static class DefaultCommunityResultBuilder extends AbstractCommunityResultBuilder { @Override - protected DefaultCommunityResult build(long loadMillis, long computeMillis, long writeMillis, long postProcessingMillis, long nodeCount, long communityCount, LongLongMap communitySizeMap, Histogram communityHistogram) { + protected DefaultCommunityResult build(long loadMillis, long computeMillis, long writeMillis, long postProcessingMillis, long nodeCount, long communityCount, LongLongMap communitySizeMap, Histogram communityHistogram, boolean write) { return new DefaultCommunityResult( loadMillis, evalDuration, diff --git a/algo/src/main/java/org/neo4j/graphalgo/results/LabelPropagationStats.java b/algo/src/main/java/org/neo4j/graphalgo/results/LabelPropagationStats.java index 992378fb9..dda740616 100644 --- a/algo/src/main/java/org/neo4j/graphalgo/results/LabelPropagationStats.java +++ b/algo/src/main/java/org/neo4j/graphalgo/results/LabelPropagationStats.java @@ -21,8 +21,6 @@ import com.carrotsearch.hppc.LongLongMap; import org.HdrHistogram.Histogram; -import java.util.List; - public class LabelPropagationStats { public static final LabelPropagationStats EMPTY = new LabelPropagationStats( @@ -50,25 +48,32 @@ public class LabelPropagationStats { public final long loadMillis; public final long computeMillis; - public final long postProcessingMillis; public final long writeMillis; + public final long postProcessingMillis; + public final long nodes; public final long communityCount; - public final long p100; - public final long p99; - public final long p95; - public final long p90; - public final long p75; - public final long p50; - public final long p25; - public final long p10; - public final long p05; - public final long p01; public final long iterations; - public final boolean write, didConverge; - public final String weightProperty, partitionProperty; + public final boolean didConverge; - public LabelPropagationStats(long loadMillis, long computeMillis, long postProcessingMillis, long writeMillis, long nodes, long communityCount, long p100, long p99, long p95, long p90, long p75, long p50, long p25, long p10, long p05, long p01, long iterations, boolean write, boolean didConverge, String weightProperty, String partitionProperty) { + public final long p1; + public final long p5; + public final long p10; + public final long p25; + public final long p50; + public final long p75; + public final long p90; + public final long p95; + public final long p99; + public final long p100; + + public final String weightProperty; + public final boolean write; + public final String partitionProperty; + + public LabelPropagationStats(long loadMillis, long computeMillis, long postProcessingMillis, long writeMillis, long nodes, + long communityCount, long p100, long p99, long p95, long p90, long p75, long p50, long p25, long p10, long p5, long p1, long iterations, boolean write, boolean didConverge, + String weightProperty, String partitionProperty) { this.loadMillis = loadMillis; this.computeMillis = computeMillis; this.postProcessingMillis = postProcessingMillis; @@ -83,8 +88,8 @@ public LabelPropagationStats(long loadMillis, long computeMillis, long postProce this.p50 = p50; this.p25 = p25; this.p10 = p10; - this.p05 = p05; - this.p01 = p01; + this.p5 = p5; + this.p1 = p1; this.iterations = iterations; this.write = write; this.didConverge = didConverge; @@ -97,7 +102,6 @@ public static class Builder extends AbstractCommunityResultBuilder { - private int iterations = -1; + private String partitionProperty; @Override - protected SCCResult build(long loadMillis, long computeMillis, long writeMillis, long postProcessingMillis, long nodeCount, long communityCount, LongLongMap communitySizeMap, Histogram communityHistogram) { + protected SCCResult build(long loadMillis, long computeMillis, long writeMillis, long postProcessingMillis, long nodeCount, long communityCount, LongLongMap communitySizeMap, Histogram communityHistogram, boolean write) { return new SCCResult( loadMillis, computeMillis, @@ -99,11 +103,17 @@ protected SCCResult build(long loadMillis, long computeMillis, long writeMillis, communityHistogram.getValueAtPercentile(10), communityHistogram.getValueAtPercentile(5), communityHistogram.getValueAtPercentile(1), - iterations, communityHistogram.getMinNonZeroValue(), - communityHistogram.getMaxValue() + communityHistogram.getMaxValue(), + write, + partitionProperty ); } + + public Builder withPartitionProperty(String partitionProperty) { + this.partitionProperty = partitionProperty; + return this; + } } } diff --git a/doc/asciidoc/balanced-triads.adoc b/doc/asciidoc/balanced-triads.adoc index 112969190..983391a14 100644 --- a/doc/asciidoc/balanced-triads.adoc +++ b/doc/asciidoc/balanced-triads.adoc @@ -147,12 +147,29 @@ YIELD loadMillis, computeMillis, writeMillis, nodeCount, balancedTriadCount, unb [opts="header",cols="1,1,6"] |=== | Name | Type | Description -| nodeCount | int | The number of nodes considered -| loadMillis | int | Milliseconds for loading data -| evalMillis | int | Milliseconds for running the algorithm -| writeMillis | int | Milliseconds for writing result data back +| loadMillis | int | Milliseconds for loading data +| computeMillis | int | Milliseconds for running the algorithm +| writeMillis | int | Milliseconds for writing result data back +| postProcessingMillis | int | Milliseconds for computing percentiles and community count + +| nodeCount | int | The number of nodes considered | balancedTriadCount | int | The number of balanced triads in the given graph | unbalancedTriadCount | int | The number of unbalanced triads in the given graph + +| p1 | double | The 1 percentile of number of balanced triads. +| p5 | double | The 5 percentile of number of balanced triads. +| p10 | double | The 10 percentile of number of balanced triads. +| p25 | double | The 25 percentile of number of balanced triads. +| p50 | double | The 50 percentile of number of balanced triads. +| p75 | double | The 75 percentile of number of balanced triads. +| p90 | double | The 90 percentile of number of balanced triads. +| p95 | double | The 95 percentile of number of balanced triads. +| p99 | double | The 99 percentile of number of balanced triads. +| p100 | double | The 100 percentile of number of balanced triads. + +| write | boolean | Specifies if the result was written back as a node property +| balancedProperty | string | The property name the number of balanced triads is written to +| unbalancedProperty | string | The property name the number of unbalanced triads is written to |=== diff --git a/doc/asciidoc/connected-components.adoc b/doc/asciidoc/connected-components.adoc index e8696c4f1..7d42e0556 100644 --- a/doc/asciidoc/connected-components.adoc +++ b/doc/asciidoc/connected-components.adoc @@ -191,11 +191,27 @@ YIELD nodes, setCount, loadMillis, computeMillis, writeMillis [opts="header",cols="1,1,6"] |=== | Name | Type | Description -| nodes | int | The number of nodes considered -| setCount | int | The number of partitions found | loadMillis | int | Milliseconds for loading data | computeMillis | int | Milliseconds for running the algorithm | writeMillis | int | Milliseconds for writing result data back +| postProcessingMillis | int | Milliseconds for computing percentiles and community count + +| nodes | int | The number of nodes considered +| communityCount | int | The number of communities found + +| p1 | double | The 1 percentile of community size. +| p5 | double | The 5 percentile of community size. +| p10 | double | The 10 percentile of community size. +| p25 | double | The 25 percentile of community size. +| p50 | double | The 50 percentile of community size. +| p75 | double | The 75 percentile of community size. +| p90 | double | The 90 percentile of community size. +| p95 | double | The 95 percentile of community size. +| p99 | double | The 99 percentile of community size. +| p100 | double | The 100 percentile of community size. + +| write | boolean | Specifies if the result was written back as a node property +| partitionProperty | string | The property name written back to |=== diff --git a/doc/asciidoc/label-propagation.adoc b/doc/asciidoc/label-propagation.adoc index 16d505c5f..8b2653aff 100644 --- a/doc/asciidoc/label-propagation.adoc +++ b/doc/asciidoc/label-propagation.adoc @@ -158,15 +158,31 @@ YIELD nodes, iterations, didConverge, loadMillis, computeMillis, writeMillis, wr [opts="header",cols="1,1,6"] |=== | Name | Type | Description -| nodes | int | The number of nodes considered -| iterations | int | The number of iterations that were executed -| didConverge | boolean | True if the algorithm did converge to a stable labelling within the provided number of maximum iterations | loadMillis | int | Milliseconds for loading data | computeMillis | int | Milliseconds for running the algorithm | writeMillis | int | Milliseconds for writing result data back -| weightProperty | string | The property name that contains weight -| partitionProperty | string | The property name written back to +| postProcessingMillis | int | Milliseconds for computing percentiles and community count + +| nodes | int | The number of nodes considered +| communityCount | int | The number of communities found +| iterations | int | The number of iterations that were executed +| didConverge | boolean | True if the algorithm did converge to a stable labelling within the provided number of maximum iterations + +| p1 | double | The 1 percentile of community size. +| p5 | double | The 5 percentile of community size. +| p10 | double | The 10 percentile of community size. +| p25 | double | The 25 percentile of community size. +| p50 | double | The 50 percentile of community size. +| p75 | double | The 75 percentile of community size. +| p90 | double | The 90 percentile of community size. +| p95 | double | The 95 percentile of community size. +| p99 | double | The 99 percentile of community size. +| p100 | double | The 100 percentile of community size. + | write | boolean | Specifies if the result was written back as a node property +| partitionProperty | string | The property name written back to +| weightProperty | string | The property name that contains weight + |=== .The following will run the algorithm and stream back results: diff --git a/doc/asciidoc/louvain.adoc b/doc/asciidoc/louvain.adoc index 71d5c4b95..775b96036 100644 --- a/doc/asciidoc/louvain.adoc +++ b/doc/asciidoc/louvain.adoc @@ -254,12 +254,34 @@ YIELD nodes, communityCount, iterations, loadMillis, computeMillis, writeMillis [opts="header",cols="1,1,6"] |=== | Name | Type | Description -| nodes | int | The number of nodes considered -| communityCount | int | The number of communities found -| iterations | int | The number of iterations run | loadMillis | int | Milliseconds for loading data | computeMillis | int | Milliseconds for running the algorithm | writeMillis | int | Milliseconds for writing result data back +| postProcessingMillis | int | Milliseconds for computing percentiles and community count + +| nodes | int | The number of nodes considered +| communityCount | int | The number of communities found +| iterations | int | The number of iterations run +| modularities | list of double | List of modularities at each iteration +| modularity | double | Modularity after final iteration + +| p1 | double | The 1 percentile of community size. +| p5 | double | The 5 percentile of community size. +| p10 | double | The 10 percentile of community size. +| p25 | double | The 25 percentile of community size. +| p50 | double | The 50 percentile of community size. +| p75 | double | The 75 percentile of community size. +| p90 | double | The 90 percentile of community size. +| p95 | double | The 95 percentile of community size. +| p99 | double | The 99 percentile of community size. +| p100 | double | The 100 percentile of community size. + +| write | boolean | Specifies if the result was written back as a node property +| writeProperty | string | The property name written back to + +| includeIntermediateCommunities | boolean | Specifies if the intermediate communities were written back as a node property +| intermediateCommunitiesWriteProperty | string | The property name written back to for intermediate communities + |=== @@ -287,7 +309,8 @@ YIELD nodeId, community - yields a community to each node id |=== | Name | Type | Description | nodeId | int | Node ID -| community | int | Community ID +| community | int | Community ID after final iteration +| communities | list of int | Community IDs for each iteration |=== diff --git a/doc/asciidoc/strongly-connected-components.adoc b/doc/asciidoc/strongly-connected-components.adoc index 0907a6513..0d6e4d4dc 100644 --- a/doc/asciidoc/strongly-connected-components.adoc +++ b/doc/asciidoc/strongly-connected-components.adoc @@ -113,12 +113,28 @@ YIELD loadMillis, computeMillis, writeMillis, setCount, maxSetSize, minSetSize [opts="header",cols="1,1,6"] |=== | Name | Type | Description -| setCount | int | The number of partitions found -| maxSetSize | int | The number of members in biggest partition -| minSetSize | int | The number of members in smallest partition | loadMillis | int | Milliseconds for loading data | computeMillis | int | Milliseconds for running the algorithm | writeMillis | int | Milliseconds for writing result data back +| postProcessingMillis | int | Milliseconds for computing percentiles and community count + +| nodes | int | The number of nodes considered +| communityCount | int | The number of communities found + +| p1 | double | The 1 percentile of community size. +| p5 | double | The 5 percentile of community size. +| p10 | double | The 10 percentile of community size. +| p25 | double | The 25 percentile of community size. +| p50 | double | The 50 percentile of community size. +| p75 | double | The 75 percentile of community size. +| p90 | double | The 90 percentile of community size. +| p95 | double | The 95 percentile of community size. +| p99 | double | The 99 percentile of community size. +| p100 | double | The 100 percentile of community size. + +| write | boolean | Specifies if the result was written back as a node property +| partitionProperty | string | The property name written back to + |=== .The following will run the algorithm and stream results: diff --git a/doc/asciidoc/triangleCount.adoc b/doc/asciidoc/triangleCount.adoc index 3636a08e5..e31c21778 100644 --- a/doc/asciidoc/triangleCount.adoc +++ b/doc/asciidoc/triangleCount.adoc @@ -207,12 +207,30 @@ YIELD loadMillis, computeMillis, writeMillis, nodeCount, triangleCount, averageC [opts="header",cols="1,1,6"] |=== | Name | Type | Description -| nodeCount | int | The number of nodes considered -| loadMillis | int | Milliseconds for loading data -| evalMillis | int | Milliseconds for running the algorithm -| writeMillis | int | Milliseconds for writing result data back -| triangleCount | int | The number of triangles in the given graph -| averageClusteringCoefficient | float | The average clustering coefficient of the given graph +| loadMillis | int | Milliseconds for loading data +| computeMillis | int | Milliseconds for running the algorithm +| writeMillis | int | Milliseconds for writing result data back +| postProcessingMillis | int | Milliseconds for computing percentiles and community count + +| nodeCount | int | The number of nodes considered +| triangleCount | int | The number of triangles found +| averageClusteringCoefficient | float | The average clustering coefficient of the given graph + +| p1 | double | The 1 percentile of number of triangles. +| p5 | double | The 5 percentile of number of triangles. +| p10 | double | The 10 percentile of number of triangles. +| p25 | double | The 25 percentile of number of triangles. +| p50 | double | The 50 percentile of number of triangles. +| p75 | double | The 75 percentile of number of triangles. +| p90 | double | The 90 percentile of number of triangles. +| p95 | double | The 95 percentile of number of triangles. +| p99 | double | The 99 percentile of number of triangles. +| p100 | double | The 100 percentile of number of triangles. + +| write | boolean | Specifies if the result was written back as a node property +| writeProperty | string | The property name the number of triangles a node is member of is written to +| clusteringCoefficientProperty | string | The property name clustering coefficient of the node is written to + |=== diff --git a/tests/src/test/java/org/neo4j/graphalgo/algo/ClusteringCoefficientIntegrationTest.java b/tests/src/test/java/org/neo4j/graphalgo/algo/ClusteringCoefficientIntegrationTest.java index a443a6f01..2a8947ddd 100644 --- a/tests/src/test/java/org/neo4j/graphalgo/algo/ClusteringCoefficientIntegrationTest.java +++ b/tests/src/test/java/org/neo4j/graphalgo/algo/ClusteringCoefficientIntegrationTest.java @@ -95,8 +95,7 @@ public static void shutdownGraph() throws Exception { @Test public void testTriangleCountWriteCypher() throws Exception { - final String cypher = "CALL algo.triangleCount('Node', '', {concurrency:4, write:true, clusterCoefficientProperty:'c'}) " + - "YIELD loadMillis, computeMillis, writeMillis, nodeCount, triangleCount, averageClusteringCoefficient"; + final String cypher = "CALL algo.triangleCount('Node', '', {concurrency:4, write:true, clusterCoefficientProperty:'c'})"; api.execute(cypher).accept(row -> { final long loadMillis = row.getNumber("loadMillis").longValue(); final long computeMillis = row.getNumber("computeMillis").longValue(); @@ -104,6 +103,8 @@ public void testTriangleCountWriteCypher() throws Exception { final long nodeCount = row.getNumber("nodeCount").longValue(); final long triangles = row.getNumber("triangleCount").longValue(); final double coefficient = row.getNumber("averageClusteringCoefficient").doubleValue(); + final long p100 = row.getNumber("p100").longValue(); + assertNotEquals(-1, loadMillis); assertNotEquals(-1, computeMillis); assertNotEquals(-1, writeMillis); @@ -111,6 +112,7 @@ public void testTriangleCountWriteCypher() throws Exception { assertEquals(3, triangles); assertEquals(0.851, coefficient, 0.1); assertEquals(9, nodeCount); + assertEquals(1, p100); return true; });