|
19 | 19 | */ |
20 | 20 | package org.neo4j.gds.applications.algorithms.pathfinding; |
21 | 21 |
|
22 | | -import org.neo4j.gds.api.ExportedRelationship; |
23 | | -import org.neo4j.gds.api.ResultStore; |
24 | | -import org.neo4j.gds.api.ResultStoreEntry; |
25 | | -import org.neo4j.gds.api.nodeproperties.ValueType; |
26 | 22 | import org.neo4j.gds.applications.algorithms.machinery.SideEffect; |
27 | 23 | import org.neo4j.gds.core.loading.GraphResources; |
28 | | -import org.neo4j.gds.core.utils.progress.JobId; |
29 | | -import org.neo4j.gds.paths.PathResult; |
30 | 24 | import org.neo4j.gds.paths.dijkstra.PathFindingResult; |
31 | | -import org.neo4j.values.storable.Value; |
32 | | -import org.neo4j.values.storable.Values; |
33 | 25 |
|
34 | | -import java.util.List; |
| 26 | +import java.util.Map; |
35 | 27 | import java.util.Optional; |
36 | 28 | import java.util.stream.Stream; |
37 | 29 |
|
38 | | -public class StorePathsSideEffect implements SideEffect<PathFindingResult, Void> { |
39 | | - private final ResultStore resultStore; |
| 30 | +/** |
| 31 | + * This is our hook for storing Dijkstra paths in a place where they can later be found. |
| 32 | + * I.e. we stick them in a map, keyed by relationship type as a pseudo parameter. |
| 33 | + * The paths themselves are represented as internal node ids, costs of the hops between them, and the sum of the costs. |
| 34 | + * It is the responsibility of outer layers to map the internal node ids back into user space. |
| 35 | + */ |
| 36 | +class StorePathsSideEffect implements SideEffect<PathFindingResult, Void> { |
| 37 | + private final Map<String, Stream<PathUsingInternalNodeIds>> paths; |
40 | 38 | private final String relationshipTypeAsString; |
41 | | - private final List<String> propertyKeys; |
42 | | - private final List<ValueType> propertyTypes; |
43 | 39 |
|
44 | | - public StorePathsSideEffect( |
45 | | - ResultStore resultStore, |
46 | | - String relationshipTypeAsString, |
47 | | - List<String> propertyKeys, |
48 | | - List<ValueType> propertyTypes |
| 40 | + StorePathsSideEffect( |
| 41 | + Map<String, Stream<PathUsingInternalNodeIds>> paths, |
| 42 | + String relationshipTypeAsString |
49 | 43 | ) { |
50 | | - this.resultStore = resultStore; |
| 44 | + this.paths = paths; |
51 | 45 | this.relationshipTypeAsString = relationshipTypeAsString; |
52 | | - this.propertyKeys = propertyKeys; |
53 | | - this.propertyTypes = propertyTypes; |
54 | 46 | } |
55 | 47 |
|
56 | 48 | @Override |
57 | 49 | public Optional<Void> process(GraphResources graphResources, Optional<PathFindingResult> pathFindingResult) { |
58 | 50 | if (pathFindingResult.isEmpty()) { |
59 | 51 | return Optional.empty(); |
60 | 52 | } |
61 | | - var actualPathResult = pathFindingResult.get(); |
62 | | - Stream<ExportedRelationship> relationshipStream = actualPathResult.mapPaths( |
63 | | - pathResult -> new ExportedRelationship( |
| 53 | + |
| 54 | + var actualPathResult = pathFindingResult.get(); |
| 55 | + |
| 56 | + // just record the paths, no conversions, that happens later |
| 57 | + var pathStream = actualPathResult.mapPaths( |
| 58 | + pathResult -> new PathUsingInternalNodeIds( |
64 | 59 | pathResult.sourceNode(), |
65 | 60 | pathResult.targetNode(), |
66 | | - createValues(pathResult) |
67 | | - )); |
68 | | - |
69 | | - ResultStoreEntry.RelationshipStream streamEntry = new ResultStoreEntry.RelationshipStream( |
70 | | - relationshipTypeAsString, |
71 | | - propertyKeys, |
72 | | - propertyTypes, |
73 | | - relationshipStream, |
74 | | - graphResources.graph()::toOriginalNodeId |
| 61 | + pathResult.nodeIds(), |
| 62 | + pathResult.costs(), |
| 63 | + pathResult.totalCost() |
| 64 | + ) |
75 | 65 | ); |
76 | | - resultStore.add(JobId.parse(this.relationshipTypeAsString), streamEntry); |
77 | 66 |
|
78 | | - return Optional.empty(); |
79 | | - } |
| 67 | + paths.put(relationshipTypeAsString, pathStream); |
80 | 68 |
|
81 | | - private Value[] createValues(PathResult pathResult) { |
82 | | - return new Value[]{ |
83 | | - Values.doubleValue(pathResult.totalCost()), |
84 | | - Values.longArray(pathResult.nodeIds()), |
85 | | - Values.doubleArray(pathResult.costs()) |
86 | | - }; |
| 69 | + // we have no interesting metadata |
| 70 | + return Optional.empty(); |
87 | 71 | } |
88 | 72 | } |
0 commit comments