2323import org .neo4j .graphalgo .AlgoBaseProc ;
2424import org .neo4j .graphalgo .AlgorithmFactory ;
2525import org .neo4j .graphalgo .api .Graph ;
26- import org .neo4j .graphalgo .compat .MapUtil ;
2726import org .neo4j .graphalgo .core .CypherMapWrapper ;
28- import org .neo4j .graphalgo .core .utils .ProgressTimer ;
29- import org .neo4j .graphalgo .core .write .RelationshipExporter ;
3027import org .neo4j .graphalgo .newapi .GraphCreateConfig ;
31- import org .neo4j .graphalgo .result .AbstractResultBuilder ;
3228
33- import java .util .Collections ;
34- import java .util .Map ;
3529import java .util .Optional ;
36- import java .util .stream .Stream ;
3730
3831public abstract class NodeSimilarityBaseProc <CONFIG extends NodeSimilarityBaseConfig > extends AlgoBaseProc <NodeSimilarity , NodeSimilarityResult , CONFIG > {
3932
@@ -54,82 +47,7 @@ protected AlgorithmFactory<NodeSimilarity, CONFIG> algorithmFactory(CONFIG confi
5447 return new NodeSimilarityFactory <>();
5548 }
5649
57- public Stream <WriteResult > write (
58- ComputationResult <NodeSimilarity , NodeSimilarityResult , CONFIG > computationResult
59- ) {
60- CONFIG config = computationResult .config ();
61-
62- if (computationResult .isGraphEmpty ()) {
63- return Stream .of (
64- new WriteResult (
65- computationResult .createMillis (),
66- 0 ,
67- 0 ,
68- 0 ,
69- 0 ,
70- 0 ,
71- Collections .emptyMap (),
72- config .toMap ()
73- )
74- );
75- }
76-
77- NodeSimilarityResult result = computationResult .result ();
78- NodeSimilarity algorithm = computationResult .algorithm ();
79- SimilarityGraphResult similarityGraphResult = result .maybeGraphResult ().get ();
80- Graph similarityGraph = similarityGraphResult .similarityGraph ();
81-
82- WriteResultBuilder resultBuilder = new WriteResultBuilder ();
83- resultBuilder
84- .withNodesCompared (similarityGraphResult .comparedNodes ())
85- .withRelationshipsWritten (similarityGraphResult .similarityGraph ().relationshipCount ());
86- resultBuilder .withCreateMillis (computationResult .createMillis ());
87- resultBuilder .withComputeMillis (computationResult .computeMillis ());
88- resultBuilder .withConfig (config );
89-
90- boolean shouldComputeHistogram = callContext
91- .outputFields ()
92- .anyMatch (s -> s .equalsIgnoreCase ("similarityDistribution" ));
93- if (shouldWrite (config ) && similarityGraph .relationshipCount () > 0 ) {
94- NodeSimilarityWriteConfig writeConfig = (NodeSimilarityWriteConfig ) config ;
95-
96- String writeRelationshipType = writeConfig .writeRelationshipType ();
97- String writeProperty = writeConfig .writeProperty ();
98-
99- runWithExceptionLogging (
100- "NodeSimilarity write-back failed" ,
101- () -> {
102- try (ProgressTimer ignored = ProgressTimer .start (resultBuilder ::withWriteMillis )) {
103- RelationshipExporter exporter = RelationshipExporter
104- .of (api , similarityGraph , algorithm .getTerminationFlag ())
105- .withLog (log )
106- .build ();
107- if (shouldComputeHistogram ) {
108- DoubleHistogram histogram = new DoubleHistogram (5 );
109- exporter .write (
110- writeRelationshipType ,
111- writeProperty ,
112- (node1 , node2 , similarity ) -> {
113- histogram .recordValue (similarity );
114- return true ;
115- }
116- );
117- resultBuilder .withHistogram (histogram );
118- } else {
119- exporter .write (writeRelationshipType , writeProperty );
120- }
121- }
122- }
123- );
124- } else if (shouldComputeHistogram ) {
125- try (ProgressTimer ignored = resultBuilder .timePostProcessing ()) {
126- resultBuilder .withHistogram (computeHistogram (similarityGraph ));
127- }
128- }
129- return Stream .of (resultBuilder .build ());
130- }
131-
132- private DoubleHistogram computeHistogram (Graph similarityGraph ) {
50+ DoubleHistogram computeHistogram (Graph similarityGraph ) {
13351 DoubleHistogram histogram = new DoubleHistogram (5 );
13452 similarityGraph .forEachNode (nodeId -> {
13553 similarityGraph .forEachRelationship (nodeId , Double .NaN , (node1 , node2 , property ) -> {
@@ -141,100 +59,4 @@ private DoubleHistogram computeHistogram(Graph similarityGraph) {
14159 return histogram ;
14260 }
14361
144- public static class WriteResult {
145- public final long loadMillis ;
146- public final long computeMillis ;
147- public final long writeMillis ;
148- public final long postProcessingMillis ;
149-
150- public final long nodesCompared ;
151- public final long relationshipsWritten ;
152-
153- public final Map <String , Object > similarityDistribution ;
154- public final Map <String , Object > configuration ;
155-
156- WriteResult (
157- long loadMillis ,
158- long computeMillis ,
159- long writeMillis ,
160- long postProcessingMillis ,
161- long nodesCompared ,
162- long relationshipsWritten ,
163- Map <String , Object > similarityDistribution ,
164- Map <String , Object > configuration
165- ) {
166- this .loadMillis = loadMillis ;
167- this .computeMillis = computeMillis ;
168- this .writeMillis = writeMillis ;
169- this .postProcessingMillis = postProcessingMillis ;
170- this .nodesCompared = nodesCompared ;
171- this .relationshipsWritten = relationshipsWritten ;
172- this .similarityDistribution = similarityDistribution ;
173- this .configuration = configuration ;
174- }
175- }
176-
177- static class WriteResultBuilder extends AbstractResultBuilder <WriteResult > {
178-
179- private long nodesCompared = 0L ;
180-
181- private long postProcessingMillis = -1L ;
182-
183- private Optional <DoubleHistogram > maybeHistogram = Optional .empty ();
184-
185- public WriteResultBuilder withNodesCompared (long nodesCompared ) {
186- this .nodesCompared = nodesCompared ;
187- return this ;
188- }
189-
190- WriteResultBuilder withHistogram (DoubleHistogram histogram ) {
191- this .maybeHistogram = Optional .of (histogram );
192- return this ;
193- }
194-
195- void setPostProcessingMillis (long postProcessingMillis ) {
196- this .postProcessingMillis = postProcessingMillis ;
197- }
198-
199- ProgressTimer timePostProcessing () {
200- return ProgressTimer .start (this ::setPostProcessingMillis );
201- }
202-
203- private Map <String , Object > distribution () {
204- if (maybeHistogram .isPresent ()) {
205- DoubleHistogram definitelyHistogram = maybeHistogram .get ();
206- return MapUtil .map (
207- "min" , definitelyHistogram .getMinValue (),
208- "max" , definitelyHistogram .getMaxValue (),
209- "mean" , definitelyHistogram .getMean (),
210- "stdDev" , definitelyHistogram .getStdDeviation (),
211- "p1" , definitelyHistogram .getValueAtPercentile (1 ),
212- "p5" , definitelyHistogram .getValueAtPercentile (5 ),
213- "p10" , definitelyHistogram .getValueAtPercentile (10 ),
214- "p25" , definitelyHistogram .getValueAtPercentile (25 ),
215- "p50" , definitelyHistogram .getValueAtPercentile (50 ),
216- "p75" , definitelyHistogram .getValueAtPercentile (75 ),
217- "p90" , definitelyHistogram .getValueAtPercentile (90 ),
218- "p95" , definitelyHistogram .getValueAtPercentile (95 ),
219- "p99" , definitelyHistogram .getValueAtPercentile (99 ),
220- "p100" , definitelyHistogram .getValueAtPercentile (100 )
221- );
222- }
223- return Collections .emptyMap ();
224- }
225-
226- @ Override
227- public WriteResult build () {
228- return new WriteResult (
229- createMillis ,
230- computeMillis ,
231- writeMillis ,
232- postProcessingMillis ,
233- nodesCompared ,
234- relationshipsWritten ,
235- distribution (),
236- config .toMap ()
237- );
238- }
239- }
24062}
0 commit comments