@@ -176,13 +176,26 @@ private Node<NodeReferenceWithVector> nodeFromRaw(final int layer,
176176 @ Nonnull
177177 private NodeReferenceWithVector neighborFromRaw (final int layer , final @ Nonnull byte [] key , final byte [] value ) {
178178 final OnReadListener onReadListener = getOnReadListener ();
179-
180179 onReadListener .onKeyValueRead (layer , key , value );
180+
181181 final Tuple neighborKeyTuple = getDataSubspace ().unpack (key );
182182 final Tuple neighborValueTuple = Tuple .fromBytes (value );
183183
184- final Tuple neighborPrimaryKey = neighborKeyTuple .getNestedTuple (2 ); // neighbor primary key
185- final RealVector neighborVector = StorageAdapter .vectorFromTuple (getConfig (), neighborValueTuple ); // the entire value is the vector
184+ return neighborFromTuples (neighborKeyTuple , neighborValueTuple );
185+ }
186+
187+ /**
188+ * Constructs a {@code NodeReferenceWithVector} from tuples retrieved from storage.
189+ * <p>
190+ * @param keyTuple the key tuple from the database, which contains the neighbor's primary key.
191+ * @param valueTuple the value tuple from the database, which represents the neighbor's vector.
192+ * @return a new {@link NodeReferenceWithVector} instance representing the deserialized neighbor.
193+ * @throws IllegalArgumentException if the key or value byte arrays are malformed and cannot be unpacked.
194+ */
195+ @ Nonnull
196+ private NodeReferenceWithVector neighborFromTuples (final @ Nonnull Tuple keyTuple , final Tuple valueTuple ) {
197+ final Tuple neighborPrimaryKey = keyTuple .getNestedTuple (2 ); // neighbor primary key
198+ final RealVector neighborVector = StorageAdapter .vectorFromTuple (getConfig (), valueTuple ); // the entire value is the vector
186199 return new NodeReferenceWithVector (neighborPrimaryKey , neighborVector );
187200 }
188201
@@ -308,6 +321,7 @@ private byte[] getNeighborKey(final int layer,
308321 @ Override
309322 public Iterable <Node <NodeReferenceWithVector >> scanLayer (@ Nonnull final ReadTransaction readTransaction , int layer ,
310323 @ Nullable final Tuple lastPrimaryKey , int maxNumRead ) {
324+ final OnReadListener onReadListener = getOnReadListener ();
311325 final byte [] layerPrefix = getDataSubspace ().pack (Tuple .from (layer ));
312326 final Range range =
313327 lastPrimaryKey == null
@@ -317,30 +331,29 @@ public Iterable<Node<NodeReferenceWithVector>> scanLayer(@Nonnull final ReadTran
317331 final AsyncIterable <KeyValue > itemsIterable =
318332 readTransaction .getRange (range ,
319333 maxNumRead , false , StreamingMode .ITERATOR );
320- int numRead = 0 ;
321334 Tuple nodePrimaryKey = null ;
322335 ImmutableList .Builder <Node <NodeReferenceWithVector >> nodeBuilder = ImmutableList .builder ();
323- ImmutableList .Builder <NodeReferenceWithVector > neighborsBuilder = ImmutableList . builder () ;
336+ ImmutableList .Builder <NodeReferenceWithVector > neighborsBuilder = null ;
324337 for (final KeyValue item : itemsIterable ) {
325- final NodeReferenceWithVector neighbor =
326- neighborFromRaw (layer , item .getKey (), item .getValue ());
327- final Tuple primaryKeyFromNodeReference = neighbor .getPrimaryKey ();
328- if (nodePrimaryKey == null ) {
329- nodePrimaryKey = primaryKeyFromNodeReference ;
330- } else {
331- if (!nodePrimaryKey .equals (primaryKeyFromNodeReference )) {
338+ final byte [] key = item .getKey ();
339+ final byte [] value = item .getValue ();
340+ onReadListener .onKeyValueRead (layer , key , value );
341+
342+ final Tuple neighborKeyTuple = getDataSubspace ().unpack (key );
343+ final Tuple neighborValueTuple = Tuple .fromBytes (value );
344+ final NodeReferenceWithVector neighbor = neighborFromTuples (neighborKeyTuple , neighborValueTuple );
345+ final Tuple nodePrimaryKeyFromNeighbor = neighborKeyTuple .getNestedTuple (1 );
346+ if (nodePrimaryKey == null || !nodePrimaryKey .equals (nodePrimaryKeyFromNeighbor )) {
347+ if (nodePrimaryKey != null ) {
332348 nodeBuilder .add (getNodeFactory ().create (nodePrimaryKey , null , neighborsBuilder .build ()));
333349 }
350+ nodePrimaryKey = nodePrimaryKeyFromNeighbor ;
351+ neighborsBuilder = ImmutableList .builder ();
334352 }
335353 neighborsBuilder .add (neighbor );
336- numRead ++;
337- }
338-
339- // there may be a rest
340- if (numRead > 0 && numRead < maxNumRead ) {
341- nodeBuilder .add (getNodeFactory ().create (nodePrimaryKey , null , neighborsBuilder .build ()));
342354 }
343355
356+ // there may be a rest; throw it away
344357 return nodeBuilder .build ();
345358 }
346359}
0 commit comments