3939import java .util .Arrays ;
4040import java .util .List ;
4141
42- public abstract class InMemoryRelationshipCursor extends RelationshipRecord implements RelationshipVisitor <RuntimeException >, StorageRelationshipCursor {
42+ import static org .neo4j .gds .utils .StringFormatting .formatWithLocale ;
43+
44+ public abstract class InMemoryRelationshipCursor
45+ extends RelationshipRecord
46+ implements RelationshipVisitor <RuntimeException >, StorageRelationshipCursor , RelationshipIds .UpdateListener {
4347
4448 protected final CypherGraphStore graphStore ;
4549 protected final TokenHolders tokenHolders ;
@@ -70,7 +74,7 @@ public InMemoryRelationshipCursor(CypherGraphStore graphStore, TokenHolders toke
7074 this .propertyValuesCache = new DoubleArrayList ();
7175
7276 this .maxRelationshipId = 0 ;
73- this .graphStore .relationshipIds ().registerUpdateListener (this :: newRelationshipIdContextAdded );
77+ this .graphStore .relationshipIds ().registerUpdateListener (this );
7478 }
7579
7680 @ Override
@@ -122,6 +126,21 @@ public boolean next() {
122126 }
123127 }
124128
129+ @ Override
130+ public void onRelationshipIdsAdded (RelationshipIds .RelationshipIdContext relationshipIdContext ) {
131+ this .relationshipIdContexts .add (relationshipIdContext );
132+ this .adjacencyCursorCache .add (relationshipIdContext .adjacencyList ().rawAdjacencyCursor ());
133+ this .propertyCursorCache .add (
134+ Arrays
135+ .stream (relationshipIdContext .adjacencyProperties ())
136+ .map (AdjacencyProperties ::rawPropertyCursor )
137+ .toArray (PropertyCursor []::new )
138+ );
139+ var newSize = this .propertyCursorCache .stream ().mapToInt (cursor -> cursor .length ).max ().orElse (0 );
140+ this .propertyValuesCache = new DoubleArrayList (new double [newSize ]);
141+ this .maxRelationshipId += relationshipIdContext .relationshipCount ();
142+ }
143+
125144 @ Override
126145 public void reset () {
127146 this .relationshipContextIndex = -1 ;
@@ -133,7 +152,7 @@ public void reset() {
133152 setId (NO_ID );
134153 }
135154
136- public void resetCursors () {
155+ protected void resetCursors () {
137156 relationshipContextIndex = -1 ;
138157 relationshipTypeOffset = 0 ;
139158 adjacencyCursor = null ;
@@ -155,20 +174,6 @@ public void properties(StoragePropertyCursor propertyCursor, InMemoryPropertySel
155174 inMemoryCursor .initRelationshipPropertyCursor (this .sourceId , propertyIds , propertyValuesCache , selection );
156175 }
157176
158- private void newRelationshipIdContextAdded (RelationshipIds .RelationshipIdContext relationshipIdContext ) {
159- this .relationshipIdContexts .add (relationshipIdContext );
160- this .adjacencyCursorCache .add (relationshipIdContext .adjacencyList ().rawAdjacencyCursor ());
161- this .propertyCursorCache .add (
162- Arrays
163- .stream (relationshipIdContext .adjacencyProperties ())
164- .map (AdjacencyProperties ::rawPropertyCursor )
165- .toArray (PropertyCursor []::new )
166- );
167- var newSize = this .propertyCursorCache .stream ().mapToInt (cursor -> cursor .length ).max ().orElse (0 );
168- this .propertyValuesCache = new DoubleArrayList (new double [newSize ]);
169- this .maxRelationshipId += relationshipIdContext .relationshipCount ();
170- }
171-
172177 private boolean progressToNextContext () {
173178 relationshipContextIndex ++;
174179
@@ -193,17 +198,29 @@ private boolean progressToNextContext() {
193198 return true ;
194199 }
195200
196- protected void findContextAndInitializeCursor (RelationshipIds .RelationshipIdContext context ) {
197- for (int i = 0 ; i < relationshipIdContexts .size (); i ++) {
198- if (i > 0 ) {
199- relationshipTypeOffset += relationshipIdContexts .get (i - 1 ).relationshipCount ();
201+ protected void initializeForRelationshipReference (long reference ) {
202+ graphStore .relationshipIds ().resolveRelationshipId (reference , (nodeId , offset , context ) -> {
203+ this .sourceId = nodeId ;
204+ findContextAndInitializeCursor (context );
205+
206+ for (long i = 0 ; i < offset ; i ++) {
207+ next ();
200208 }
201- if (relationshipIdContexts .get (i ) == context ) {
202- this .relationshipContextIndex = i ;
203- initializeCursorForContext (context );
204- break ;
209+ setId (reference - 1 );
210+ return null ;
211+ });
212+ }
213+
214+ private void findContextAndInitializeCursor (RelationshipIds .RelationshipIdContext context ) {
215+ while (progressToNextContext ()) {
216+ if (relationshipIdContexts .get (relationshipContextIndex ) == context ) {
217+ return ;
205218 }
206219 }
220+ throw new IllegalStateException (formatWithLocale (
221+ "No relationship context for relationship type %s was found" ,
222+ context .relationshipType ().name ()
223+ ));
207224 }
208225
209226 private void initializeCursorForContext (RelationshipIds .RelationshipIdContext context ) {
0 commit comments