19
19
*/
20
20
package org .neo4j .gds .applications .algorithms .pathfinding ;
21
21
22
- import org .neo4j .gds .api .ExportedRelationship ;
23
22
import org .neo4j .gds .api .Graph ;
24
23
import org .neo4j .gds .api .GraphStore ;
25
- import org .neo4j .gds .api .IdMap ;
26
24
import org .neo4j .gds .api .ResultStore ;
27
- import org .neo4j .gds .api .nodeproperties .ValueType ;
28
- import org .neo4j .gds .applications .algorithms .machinery .RequestScopedDependencies ;
29
- import org .neo4j .gds .applications .algorithms .machinery .WriteContext ;
25
+ import org .neo4j .gds .applications .algorithms .machinery .WriteRelationshipService ;
30
26
import org .neo4j .gds .applications .algorithms .machinery .WriteStep ;
31
27
import org .neo4j .gds .applications .algorithms .metadata .RelationshipsWritten ;
32
- import org .neo4j .gds .core .concurrency .Concurrency ;
33
- import org .neo4j .gds .core .utils .logging .LoggerForProgressTrackingAdapter ;
34
28
import org .neo4j .gds .core .utils .progress .JobId ;
35
- import org .neo4j .gds .core .utils .progress .tasks .TaskProgressTracker ;
36
- import org .neo4j .gds .core .write .RelationshipStreamExporter ;
37
- import org .neo4j .gds .logging .Log ;
38
- import org .neo4j .gds .paths .PathResult ;
39
29
import org .neo4j .gds .paths .bellmanford .AllShortestPathsBellmanFordWriteConfig ;
40
30
import org .neo4j .gds .paths .bellmanford .BellmanFordResult ;
41
- import org .neo4j .values .storable .Value ;
42
- import org .neo4j .values .storable .Values ;
43
-
44
- import java .util .List ;
45
-
46
- import static org .neo4j .gds .paths .dijkstra .config .ShortestPathDijkstraWriteConfig .COSTS_KEY ;
47
- import static org .neo4j .gds .paths .dijkstra .config .ShortestPathDijkstraWriteConfig .NODE_IDS_KEY ;
48
- import static org .neo4j .gds .paths .dijkstra .config .ShortestPathDijkstraWriteConfig .TOTAL_COST_KEY ;
49
31
50
32
class BellmanFordWriteStep implements WriteStep <BellmanFordResult , RelationshipsWritten > {
51
- private final Log log ;
52
- private final RequestScopedDependencies requestScopedDependencies ;
53
- private final WriteContext writeContext ;
33
+ private final WriteRelationshipService writeRelationshipService ;
54
34
private final AllShortestPathsBellmanFordWriteConfig configuration ;
55
35
56
36
BellmanFordWriteStep (
57
- Log log ,
58
- RequestScopedDependencies requestScopedDependencies ,
59
- WriteContext writeContext ,
37
+ WriteRelationshipService writeRelationshipService ,
60
38
AllShortestPathsBellmanFordWriteConfig configuration
61
39
) {
62
- this .log = log ;
63
- this .requestScopedDependencies = requestScopedDependencies ;
64
40
this .configuration = configuration ;
65
- this .writeContext = writeContext ;
41
+ this .writeRelationshipService = writeRelationshipService ;
66
42
}
67
43
68
44
@ Override
@@ -73,126 +49,33 @@ public RelationshipsWritten execute(
73
49
BellmanFordResult result ,
74
50
JobId jobId
75
51
) {
76
- var writeRelationshipType = configuration .writeRelationshipType ();
77
52
78
53
var writeNodeIds = configuration .writeNodeIds ();
79
54
var writeCosts = configuration .writeCosts ();
80
55
56
+ var specification = new PathFindingWriteRelationshipSpecification (graph ,writeNodeIds ,writeCosts );
57
+ var keys = specification .createKeys ();
58
+ var types = specification .createTypes ();
59
+
81
60
var paths = result .shortestPaths ();
82
61
if (configuration .writeNegativeCycles () && result .containsNegativeCycle ()) {
83
62
paths = result .negativeCycles ();
84
63
}
85
-
86
- var relationshipStream = paths .mapPaths (
87
- pathResult -> new ExportedRelationship (
88
- pathResult .sourceNode (),
89
- pathResult .targetNode (),
90
- createValues (graph , pathResult , writeNodeIds , writeCosts )
91
- )
92
- );
93
-
94
- var progressTracker = new TaskProgressTracker (
95
- RelationshipStreamExporter .baseTask ("Write shortest Paths" ),
96
- new LoggerForProgressTrackingAdapter (log ),
97
- new Concurrency (1 ),
98
- requestScopedDependencies .taskRegistryFactory ()
99
- );
100
-
101
- var exporter = writeContext .relationshipStreamExporterBuilder ()
102
- .withIdMappingOperator (graph ::toOriginalNodeId )
103
- .withRelationships (relationshipStream )
104
- .withTerminationFlag (requestScopedDependencies .terminationFlag ())
105
- .withProgressTracker (progressTracker )
106
- .withResultStore (configuration .resolveResultStore (resultStore ))
107
- .withJobId (configuration .jobId ())
108
- .build ();
109
-
110
- // effect
111
- var relationshipsWritten = exporter .write (
112
- writeRelationshipType ,
113
- createKeys (writeNodeIds , writeCosts ),
114
- createTypes (writeNodeIds , writeCosts )
115
- );
116
-
117
- // reporting
118
- return new RelationshipsWritten (relationshipsWritten );
119
- }
120
-
121
- private Value [] createValues (IdMap idMap , PathResult pathResult , boolean writeNodeIds , boolean writeCosts ) {
122
- if (writeNodeIds && writeCosts ) {
123
- return new Value []{
124
- Values .doubleValue (pathResult .totalCost ()),
125
- Values .longArray (toOriginalIds (idMap , pathResult .nodeIds ())),
126
- Values .doubleArray (pathResult .costs ())
127
- };
128
- }
129
- if (writeNodeIds ) {
130
- return new Value []{
131
- Values .doubleValue (pathResult .totalCost ()),
132
- Values .longArray (toOriginalIds (idMap , pathResult .nodeIds ())),
133
- };
134
- }
135
- if (writeCosts ) {
136
- return new Value []{
137
- Values .doubleValue (pathResult .totalCost ()),
138
- Values .doubleArray (pathResult .costs ())
139
- };
140
- }
141
- return new Value []{
142
- Values .doubleValue (pathResult .totalCost ()),
143
- };
144
- }
145
-
146
- private long [] toOriginalIds (IdMap idMap , long [] internalIds ) {
147
- for (int i = 0 ; i < internalIds .length ; i ++) {
148
- internalIds [i ] = idMap .toOriginalNodeId (internalIds [i ]);
149
- }
150
- return internalIds ;
151
- }
152
-
153
- private List <String > createKeys (boolean writeNodeIds , boolean writeCosts ) {
154
- if (writeNodeIds && writeCosts ) {
155
- return List .of (
156
- TOTAL_COST_KEY ,
157
- NODE_IDS_KEY ,
158
- COSTS_KEY
159
- );
160
- }
161
- if (writeNodeIds ) {
162
- return List .of (
163
- TOTAL_COST_KEY ,
164
- NODE_IDS_KEY
165
- );
166
- }
167
- if (writeCosts ) {
168
- return List .of (
169
- TOTAL_COST_KEY ,
170
- COSTS_KEY
64
+ try (
65
+ var relationshipStream = paths .mapPaths (specification ::createRelationship );
66
+ ) {
67
+
68
+ return writeRelationshipService .writeFromRelationshipStream (
69
+ configuration .writeRelationshipType (),
70
+ keys ,
71
+ types ,
72
+ relationshipStream ,
73
+ graph .rootIdMap (),
74
+ "Write shortest Paths" ,
75
+ configuration .resolveResultStore (resultStore ),
76
+ configuration .jobId ()
171
77
);
172
78
}
173
- return List .of (TOTAL_COST_KEY );
174
79
}
175
80
176
- private List <ValueType > createTypes (boolean writeNodeIds , boolean writeCosts ) {
177
- if (writeNodeIds && writeCosts ) {
178
- return List .of (
179
- ValueType .DOUBLE ,
180
- ValueType .LONG_ARRAY ,
181
- ValueType .DOUBLE_ARRAY
182
- );
183
- }
184
- if (writeNodeIds ) {
185
- return List .of (
186
- ValueType .DOUBLE ,
187
- ValueType .LONG_ARRAY
188
- );
189
- }
190
- if (writeCosts ) {
191
- return List .of (
192
- ValueType .DOUBLE ,
193
- ValueType .DOUBLE_ARRAY
194
- );
195
- }
196
- return List .of (ValueType .DOUBLE );
197
- }
198
81
}
0 commit comments