### Question:
Knn extends Algorithm<Knn, Knn.Result> { static void reverseNeighbors( long nodeId, HugeObjectArray<LongArrayList> allNeighbors, HugeObjectArray<LongArrayList> reverseNeighbors ) { var neighbors = allNeighbors.get(nodeId); if (neighbors != null) { for (var neighbor : neighbors) { assert neighbor.value != nodeId; var oldReverse = reverseNeighbors.get(neighbor.value); if (oldReverse == null) { oldReverse = new LongArrayList(); reverseNeighbors.set(neighbor.value, oldReverse); } oldReverse.add(nodeId); } } } Knn(Graph graph, KnnBaseConfig config, KnnContext context);  Knn(
        long nodeCount,
        KnnBaseConfig config,
        SimilarityComputer similarityComputer,
        KnnContext context
    ); long nodeCount(); KnnContext context(); @Override Result compute(); @Override Knn me(); @Override void release();  }### Answer:
@Test void testReverseEmptyList() { var nodeCount = 42; var neighbors = HugeObjectArray.newArray(LongArrayList.class, nodeCount, AllocationTracker.empty()); var reverseNeighbors = HugeObjectArray.newArray(LongArrayList.class, nodeCount, AllocationTracker.empty()); Knn.reverseNeighbors(0, neighbors, reverseNeighbors); assertThat(reverseNeighbors.get(0)).isNull(); var neighborsFrom0 = LongArrayList.from(LongStream.range(1, nodeCount).toArray()); neighbors.set(0, neighborsFrom0); }
@Test void testReverseAllAsNeighbor() { var nodeCount = 42; var neighbors = HugeObjectArray.newArray(LongArrayList.class, nodeCount, AllocationTracker.empty()); var reverseNeighbors = HugeObjectArray.newArray(LongArrayList.class, nodeCount, AllocationTracker.empty()); var neighborsFrom0 = LongArrayList.from(LongStream.range(1, nodeCount).toArray()); neighbors.set(0, neighborsFrom0); Knn.reverseNeighbors(0, neighbors, reverseNeighbors); assertThat(reverseNeighbors.get(0)).isNull(); for (int i = 1; i < nodeCount; i++) { var reversed = reverseNeighbors.get(i); assertThat(reversed) .isNotNull() .singleElement() .extracting("value") .isEqualTo(0L); } }
@Test void testReverseSingleNeighbors() { var nodeCount = 42; var neighbors = HugeObjectArray.newArray(LongArrayList.class, nodeCount, AllocationTracker.empty()); var reverseNeighbors = HugeObjectArray.newArray(LongArrayList.class, nodeCount, AllocationTracker.empty()); neighbors.setAll(nodeId -> nodeId == 0 ? null : LongArrayList.from(0)); for (int nodeId = 0; nodeId < nodeCount; nodeId++) { Knn.reverseNeighbors(nodeId, neighbors, reverseNeighbors); } assertThat(reverseNeighbors.get(0)) .isNotNull() .extracting(c -> c.value) .containsExactly(LongStream.range(1, nodeCount).boxed().toArray(Long[]::new)); for (int i = 1; i < nodeCount; i++) { assertThat(reverseNeighbors.get(i)).isNull(); } }