Skip to content

Commit 5d07bce

Browse files
committed
save point -- in the middle of just mess
1 parent 8bdf410 commit 5d07bce

File tree

10 files changed

+275
-125
lines changed

10 files changed

+275
-125
lines changed

fdb-extensions/src/main/java/com/apple/foundationdb/async/hnsw/AbstractNode.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
package com.apple.foundationdb.async.hnsw;
2222

2323
import com.apple.foundationdb.tuple.Tuple;
24-
import com.christianheina.langx.half4j.Half;
2524
import com.google.common.collect.ImmutableList;
2625

2726
import javax.annotation.Nonnull;
@@ -35,16 +34,12 @@ abstract class AbstractNode<N extends Neighbor> implements Node<N> {
3534
@Nonnull
3635
private final Tuple primaryKey;
3736

38-
@Nonnull
39-
private final Vector<Half> vector;
40-
4137
@Nonnull
4238
private final List<N> neighbors;
4339

44-
protected AbstractNode(@Nonnull final Tuple primaryKey, @Nonnull final Vector<Half> vector,
40+
protected AbstractNode(@Nonnull final Tuple primaryKey,
4541
@Nonnull final List<N> neighbors) {
4642
this.primaryKey = primaryKey;
47-
this.vector = vector;
4843
this.neighbors = ImmutableList.copyOf(neighbors);
4944
}
5045

@@ -54,11 +49,6 @@ public Tuple getPrimaryKey() {
5449
return primaryKey;
5550
}
5651

57-
@Nonnull
58-
public Vector<Half> getVector() {
59-
return vector;
60-
}
61-
6252
@Nonnull
6353
@Override
6454
public List<N> getNeighbors() {

fdb-extensions/src/main/java/com/apple/foundationdb/async/hnsw/ByNodeStorageAdapter.java

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -75,21 +75,22 @@ public ByNodeStorageAdapter(@Nonnull final HNSW.Config config, @Nonnull final Su
7575
}
7676

7777
@Override
78-
public CompletableFuture<NodeKeyWithLayer> fetchEntryNodeKey(@Nonnull final ReadTransaction readTransaction) {
78+
public CompletableFuture<EntryPointAndLayer> fetchEntryNodeKey(@Nonnull final ReadTransaction readTransaction) {
7979
final byte[] key = getEntryNodeSubspace().pack();
8080

8181
return readTransaction.get(key)
8282
.thenApply(valueBytes -> {
8383
if (valueBytes == null) {
8484
return null; // not a single node in the index
8585
}
86+
final OnReadListener onReadListener = getOnReadListener();
87+
onReadListener.onKeyValueRead(key, valueBytes);
8688

8789
final Tuple entryTuple = Tuple.fromBytes(valueBytes);
8890
final int lMax = (int)entryTuple.getLong(0);
8991
final Tuple primaryKey = entryTuple.getNestedTuple(1);
90-
final OnReadListener onReadListener = getOnReadListener();
91-
onReadListener.onKeyValueRead(key, valueBytes);
92-
return new NodeKeyWithLayer(lMax, primaryKey);
92+
final Tuple vectorTuple = entryTuple.getNestedTuple(2);
93+
return new EntryPointAndLayer(lMax, primaryKey, vectorFromTuple(vectorTuple));
9394
});
9495
}
9596

@@ -156,77 +157,79 @@ private Tuple toTuple(@Nonnull final Node node) {
156157
return Tuple.from(node.getKind().getSerialized(), slotTuples);
157158
}
158159

159-
@Nonnull
160-
@Override
161-
public CompletableFuture<Node> fetchNodeInternal(@Nonnull final ReadTransaction transaction,
162-
@Nonnull final byte[] nodeId) {
163-
final byte[] key = packWithSubspace(nodeId);
164-
return transaction.get(key)
165-
.thenApply(valueBytes -> {
166-
if (valueBytes == null) {
167-
return null;
168-
}
169-
final Node node = nodeFromTuple(nodeId, Tuple.fromBytes(valueBytes));
170-
final OnReadListener onReadListener = getOnReadListener();
171-
onReadListener.onNodeRead(node);
172-
onReadListener.onKeyValueRead(node, key, valueBytes);
173-
return node;
174-
});
175-
}
176-
177160
@Nonnull
178161
private <N extends Neighbor> Node<N> nodeFromTuple(@Nonnull final Node.NodeCreator<N> creator,
179162
@Nonnull final Tuple tuple) {
180163
final NodeKind nodeKind = NodeKind.fromSerializedNodeKind((byte)tuple.getLong(0));
181164
final Tuple primaryKey = tuple.getNestedTuple(1);
182-
final Tuple vectorTuple = tuple.getNestedTuple(2);
183-
final Tuple neighborsTuple = tuple.getNestedTuple(3);
165+
final Tuple vectorTuple;
166+
final Tuple neighborsTuple;
167+
168+
switch (nodeKind) {
169+
case DATA:
170+
vectorTuple = tuple.getNestedTuple(2);
171+
neighborsTuple = tuple.getNestedTuple(3);
172+
return dataNodeFromTuples(creator, primaryKey, vectorTuple, neighborsTuple);
173+
case INTERMEDIATE:
174+
neighborsTuple = tuple.getNestedTuple(3);
175+
return intermediateNodeFromTuples(creator, primaryKey, neighborsTuple);
176+
default:
177+
throw new IllegalStateException("unknown node kind");
178+
}
179+
}
184180

185-
final Half[] vectorHalfs = new Half[vectorTuple.size()];
186-
for (int i = 0; i < vectorTuple.size(); i ++) {
187-
vectorHalfs[i] = Half.shortBitsToHalf(shortFromBytes(vectorTuple.getBytes(i)));
181+
@Nonnull
182+
private <N extends Neighbor> Node<N> dataNodeFromTuples(@Nonnull final Node.NodeCreator<N> creator,
183+
@Nonnull final Tuple primaryKey,
184+
@Nonnull final Tuple vectorTuple,
185+
@Nonnull final Tuple neighborsTuple) {
186+
final Vector<Half> vector = vectorFromTuple(vectorTuple);
187+
188+
List<Neighbor> neighbors = Lists.newArrayListWithExpectedSize(neighborsTuple.size());
189+
190+
for (final Object neighborObject : neighborsTuple) {
191+
final Tuple neighborTuple = (Tuple)neighborObject;
192+
neighbors.add(new Neighbor(neighborTuple));
188193
}
189-
final Vector.HalfVector vector = new Vector.HalfVector(vectorHalfs);
190-
List<NeighborWithVector> neighborsWithVectors = null;
194+
195+
return creator.create(NodeKind.DATA, primaryKey, vector, neighbors);
196+
}
197+
198+
@Nonnull
199+
private <N extends Neighbor> Node<N> intermediateNodeFromTuples(@Nonnull final Node.NodeCreator<N> creator,
200+
@Nonnull final Tuple primaryKey,
201+
@Nonnull final Tuple neighborsTuple) {
202+
List<NeighborWithVector> neighborsWithVectors = Lists.newArrayListWithExpectedSize(neighborsTuple.size());
191203
Half[] neighborVectorHalfs = null;
192-
List<Neighbor> neighbors = null;
193204

194205
for (final Object neighborObject : neighborsTuple) {
195206
final Tuple neighborTuple = (Tuple)neighborObject;
196-
switch (nodeKind) {
197-
case DATA:
198-
if (neighbors == null) {
199-
neighbors = Lists.newArrayListWithExpectedSize(neighborsTuple.size());
200-
}
201-
neighbors.add(new Neighbor(neighborTuple));
202-
break;
203-
204-
case INTERMEDIATE:
205-
final Tuple neighborPrimaryKey = neighborTuple.getNestedTuple(0);
206-
final Tuple neighborVectorTuple = neighborTuple.getNestedTuple(1);
207-
if (neighborsWithVectors == null) {
208-
neighborsWithVectors = Lists.newArrayListWithExpectedSize(neighborsTuple.size());
209-
neighborVectorHalfs = new Half[neighborVectorTuple.size()];
210-
}
211-
212-
for (int i = 0; i < neighborVectorTuple.size(); i ++) {
213-
neighborVectorHalfs[i] = Half.shortBitsToHalf(shortFromBytes(neighborVectorTuple.getBytes(i)));
214-
}
215-
neighborsWithVectors.add(new NeighborWithVector(neighborPrimaryKey, new Vector.HalfVector(neighborVectorHalfs)));
216-
break;
207+
final Tuple neighborPrimaryKey = neighborTuple.getNestedTuple(0);
208+
final Tuple neighborVectorTuple = neighborTuple.getNestedTuple(1);
209+
if (neighborVectorHalfs == null) {
210+
neighborVectorHalfs = new Half[neighborVectorTuple.size()];
211+
}
217212

218-
default:
219-
throw new IllegalStateException("unknown node kind");
213+
for (int i = 0; i < neighborVectorTuple.size(); i ++) {
214+
neighborVectorHalfs[i] = Half.shortBitsToHalf(shortFromBytes(neighborVectorTuple.getBytes(i)));
220215
}
216+
neighborsWithVectors.add(new NeighborWithVector(neighborPrimaryKey, new Vector.HalfVector(neighborVectorHalfs)));
221217
}
222218

223-
Verify.verify((nodeKind == NodeKind.DATA && neighbors != null) ||
224-
(nodeKind == NodeKind.INTERMEDIATE && neighborsWithVectors != null));
219+
return creator.create(NodeKind.INTERMEDIATE, primaryKey, null, neighborsWithVectors);
220+
}
225221

226-
return creator.create(nodeKind, primaryKey, vector,
227-
nodeKind == NodeKind.DATA ? neighbors : neighborsWithVectors);
222+
@Nonnull
223+
private Vector<Half> vectorFromTuple(final Tuple vectorTuple) {
224+
final Half[] vectorHalfs = new Half[vectorTuple.size()];
225+
for (int i = 0; i < vectorTuple.size(); i ++) {
226+
vectorHalfs[i] = Half.shortBitsToHalf(shortFromBytes(vectorTuple.getBytes(i)));
227+
}
228+
return new Vector.HalfVector(vectorHalfs);
228229
}
229230

231+
232+
230233
@Nonnull
231234
@Override
232235
public <S extends NodeSlot, N extends AbstractNode<S, N>> AbstractChangeSet<S, N>

fdb-extensions/src/main/java/com/apple/foundationdb/async/hnsw/DataNode.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,23 @@
2323
import com.apple.foundationdb.tuple.Tuple;
2424
import com.christianheina.langx.half4j.Half;
2525
import com.google.common.base.Verify;
26-
import com.google.common.collect.Lists;
2726

2827
import javax.annotation.Nonnull;
2928
import javax.annotation.Nullable;
3029
import java.util.List;
30+
import java.util.Objects;
3131

3232
/**
33-
* A leaf node of the R-tree. A leaf node holds the actual data in {@link ItemSlot}s.
33+
* TODO.
3434
*/
3535
class DataNode extends AbstractNode<Neighbor> {
36+
@Nonnull
37+
private final Vector<Half> vector;
38+
3639
public DataNode(@Nonnull final Tuple primaryKey, @Nonnull final Vector<Half> vector,
3740
@Nonnull final List<Neighbor> neighbors) {
38-
super(primaryKey, vector, neighbors);
41+
super(primaryKey, neighbors);
42+
this.vector = vector;
3943
}
4044

4145
@Nonnull
@@ -44,6 +48,11 @@ public NodeKind getKind() {
4448
return NodeKind.DATA;
4549
}
4650

51+
@Nonnull
52+
public Vector<Half> getVector() {
53+
return vector;
54+
}
55+
4756
@Nonnull
4857
@Override
4958
public DataNode asDataNode() {
@@ -71,9 +80,9 @@ public NodeCreator<Neighbor> sameCreator() {
7180
@SuppressWarnings("unchecked")
7281
public static Node<Neighbor> creator(@Nonnull final NodeKind nodeKind,
7382
@Nonnull final Tuple primaryKey,
74-
@Nonnull final Vector<Half> vector,
83+
@Nullable final Vector<Half> vector,
7584
@Nonnull final List<? extends Neighbor> neighbors) {
7685
Verify.verify(nodeKind == NodeKind.INTERMEDIATE);
77-
return new DataNode(primaryKey, vector, (List<Neighbor>)neighbors);
86+
return new DataNode(primaryKey, Objects.requireNonNull(vector), (List<Neighbor>)neighbors);
7887
}
7988
}
Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,31 @@
2323
import com.apple.foundationdb.tuple.Tuple;
2424

2525
import javax.annotation.Nonnull;
26+
import java.util.List;
2627

27-
class NodeKeyWithLayerAndDistance extends NodeKeyWithLayer {
28+
class Element {
29+
@Nonnull
30+
private final Tuple primaryKey;
2831
private final double distance;
2932

30-
public NodeKeyWithLayerAndDistance(final int layer, @Nonnull final Tuple primaryKey, final double distance) {
31-
super(layer, primaryKey);
33+
public Element(@Nonnull final Tuple primaryKey, final double distance) {
34+
this.primaryKey = primaryKey;
3235
this.distance = distance;
3336
}
3437

38+
@Nonnull
39+
public Tuple getPrimaryKey() {
40+
return primaryKey;
41+
}
42+
3543
public double getDistance() {
3644
return distance;
3745
}
46+
47+
@Nonnull
48+
public static Iterable<Tuple> primaryKeys(@Nonnull List<Element> elements) {
49+
return () -> elements.stream()
50+
.map(Element::getPrimaryKey)
51+
.iterator();
52+
}
3853
}

fdb-extensions/src/main/java/com/apple/foundationdb/async/hnsw/NodeKeyWithLayer.java renamed to fdb-extensions/src/main/java/com/apple/foundationdb/async/hnsw/EntryPointAndLayer.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,21 @@
2121
package com.apple.foundationdb.async.hnsw;
2222

2323
import com.apple.foundationdb.tuple.Tuple;
24+
import com.christianheina.langx.half4j.Half;
2425

2526
import javax.annotation.Nonnull;
2627

27-
class NodeKeyWithLayer {
28+
class EntryPointAndLayer {
2829
private final int layer;
2930
@Nonnull
3031
private final Tuple primaryKey;
32+
@Nonnull
33+
private final Vector<Half> vector;
3134

32-
public NodeKeyWithLayer(final int layer, @Nonnull final Tuple primaryKey) {
35+
public EntryPointAndLayer(final int layer, @Nonnull final Tuple primaryKey, @Nonnull final Vector<Half> vector) {
3336
this.layer = layer;
3437
this.primaryKey = primaryKey;
38+
this.vector = vector;
3539
}
3640

3741
public int getLayer() {
@@ -42,4 +46,9 @@ public int getLayer() {
4246
public Tuple getPrimaryKey() {
4347
return primaryKey;
4448
}
49+
50+
@Nonnull
51+
public Vector<Half> getVector() {
52+
return vector;
53+
}
4554
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* NodeWithLayer.java
3+
*
4+
* This source file is part of the FoundationDB open source project
5+
*
6+
* Copyright 2015-2025 Apple Inc. and the FoundationDB project authors
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
package com.apple.foundationdb.async.hnsw;
22+
23+
import com.apple.foundationdb.tuple.Tuple;
24+
25+
import javax.annotation.Nonnull;
26+
27+
class GreedyResult {
28+
private final int layer;
29+
@Nonnull
30+
private final Tuple primaryKey;
31+
private final double distance;
32+
33+
public GreedyResult(final int layer, @Nonnull final Tuple primaryKey, final double distance) {
34+
this.layer = layer;
35+
this.primaryKey = primaryKey;
36+
this.distance = distance;
37+
}
38+
39+
public int getLayer() {
40+
return layer;
41+
}
42+
43+
@Nonnull
44+
public Tuple getPrimaryKey() {
45+
return primaryKey;
46+
}
47+
48+
public double getDistance() {
49+
return distance;
50+
}
51+
52+
public Element toElement() {
53+
return new Element(getPrimaryKey(), getDistance());
54+
}
55+
}

0 commit comments

Comments
 (0)