Skip to content

Commit 4529c32

Browse files
committed
add jvector framework
1 parent 40ac0a9 commit 4529c32

File tree

18 files changed

+1764
-1
lines changed

18 files changed

+1764
-1
lines changed

hugegraph-server/hugegraph-core/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
<eclipse-collections.version>11.1.0</eclipse-collections.version>
4545
<fastutil.version>8.5.9</fastutil.version>
4646
<jjwt.version>0.11.5</jjwt.version>
47+
<jvector.version>4.0.0-rc.2</jvector.version>
4748
</properties>
4849

4950
<dependencies>
@@ -284,6 +285,13 @@
284285
</exclusion>
285286
</exclusions>
286287
</dependency>
288+
289+
<!-- https://mvnrepository.com/artifact/io.github.jbellis/jvector -->
290+
<dependency>
291+
<groupId>io.github.jbellis</groupId>
292+
<artifactId>jvector</artifactId>
293+
<version>${jvector.version}</version>
294+
</dependency>
287295
</dependencies>
288296

289297
<build>

hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/SerializerFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public static AbstractSerializer serializer(HugeConfig config, String name) {
4040
return new BinaryScatterSerializer(config);
4141
case "text":
4242
return new TextSerializer(config);
43+
case "vector":
44+
return new VectorSerializer(config);
4345
default:
4446
}
4547

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.hugegraph.backend.serializer;
19+
20+
import java.nio.ByteBuffer;
21+
import java.util.ArrayList;
22+
import java.util.Collection;
23+
import java.util.Collections;
24+
import java.util.List;
25+
26+
import org.apache.hugegraph.backend.id.Id;
27+
import org.apache.hugegraph.backend.store.BackendEntry;
28+
import org.apache.hugegraph.type.HugeType;
29+
30+
/**
31+
* Vector backend entry for handling vector index data
32+
* This entry is specifically designed for vector operations and jvector integration
33+
*/
34+
public class VectorBackendEntry implements BackendEntry {
35+
36+
// 基础字段(实现BackendEntry接口)
37+
private final HugeType type; // VECTOR_INDEX
38+
private final Id id; // 索引ID
39+
private final Id subId; // 顶点ID
40+
41+
// 向量核心字段
42+
private final String vectorId; // 向量唯一标识
43+
private final float[] vector; // 向量数据
44+
private final String metricType; // 度量类型 (L2, COSINE, DOT)
45+
private final Integer dimension; // 向量维度
46+
47+
public VectorBackendEntry(HugeType type, Id id, Id subId,
48+
String vectorId, float[] vector,
49+
String metricType, Integer dimension) {
50+
this.type = type;
51+
this.id = id;
52+
this.subId = subId;
53+
this.vectorId = vectorId;
54+
this.vector = vector;
55+
this.metricType = metricType;
56+
this.dimension = dimension;
57+
}
58+
59+
// 实现BackendEntry接口
60+
@Override
61+
public HugeType type() {
62+
return this.type;
63+
}
64+
65+
@Override
66+
public Id id() {
67+
return this.id;
68+
}
69+
70+
@Override
71+
public Id originId() {
72+
return this.id;
73+
}
74+
75+
@Override
76+
public Id subId() {
77+
return this.subId;
78+
}
79+
80+
@Override
81+
public long ttl() {
82+
return 0L; // 向量索引不过期
83+
}
84+
85+
@Override
86+
public boolean olap() {
87+
return false; // 向量索引不是OLAP数据
88+
}
89+
90+
// 向量特有方法
91+
public String vectorId() {
92+
return this.vectorId;
93+
}
94+
95+
public float[] vector() {
96+
return this.vector;
97+
}
98+
99+
public String metricType() {
100+
return this.metricType;
101+
}
102+
103+
public Integer dimension() {
104+
return this.dimension;
105+
}
106+
107+
// 为了兼容BackendEntry接口,提供columns方法
108+
@Override
109+
public Collection<BackendColumn> columns() {
110+
List<BackendColumn> cols = new ArrayList<>();
111+
if (this.vector != null) {
112+
cols.add(BackendColumn.of("vector".getBytes(), this.serializeVector()));
113+
}
114+
if (this.metricType != null) {
115+
cols.add(BackendColumn.of("metric".getBytes(), this.metricType.getBytes()));
116+
}
117+
if (this.dimension != null) {
118+
cols.add(BackendColumn.of("dimension".getBytes(),
119+
this.dimension.toString().getBytes()));
120+
}
121+
return Collections.unmodifiableList(cols);
122+
}
123+
124+
@Override
125+
public int columnsSize() {
126+
return this.columns().size();
127+
}
128+
129+
@Override
130+
public void columns(Collection<BackendColumn> columns) {
131+
// 向量索引不支持动态添加列
132+
throw new UnsupportedOperationException("VectorBackendEntry doesn't support dynamic columns");
133+
}
134+
135+
@Override
136+
public void columns(BackendColumn column) {
137+
throw new UnsupportedOperationException("VectorBackendEntry doesn't support dynamic columns");
138+
}
139+
140+
@Override
141+
public void merge(BackendEntry other) {
142+
throw new UnsupportedOperationException("VectorBackendEntry doesn't support merge");
143+
}
144+
145+
@Override
146+
public boolean mergeable(BackendEntry other) {
147+
return false; // 向量索引不支持合并
148+
}
149+
150+
@Override
151+
public void clear() {
152+
throw new UnsupportedOperationException("VectorBackendEntry doesn't support clear");
153+
}
154+
155+
@Override
156+
public boolean belongToMe(BackendColumn column) {
157+
// 向量索引的列都属于自己
158+
return true;
159+
}
160+
161+
private byte[] serializeVector() {
162+
if (this.vector == null || this.vector.length == 0) {
163+
return new byte[0];
164+
}
165+
ByteBuffer buffer = ByteBuffer.allocate(this.vector.length * 4);
166+
for (float f : this.vector) {
167+
buffer.putFloat(f);
168+
}
169+
return buffer.array();
170+
}
171+
172+
@Override
173+
public String toString() {
174+
return String.format("VectorBackendEntry{type=%s, id=%s, subId=%s, vectorId=%s, dimension=%d}",
175+
this.type, this.id, this.subId, this.vectorId, this.dimension);
176+
}
177+
178+
@Override
179+
public boolean equals(Object obj) {
180+
if (!(obj instanceof VectorBackendEntry)) {
181+
return false;
182+
}
183+
VectorBackendEntry other = (VectorBackendEntry) obj;
184+
return this.type.equals(other.type) &&
185+
this.id.equals(other.id) &&
186+
this.subId.equals(other.subId) &&
187+
this.vectorId.equals(other.vectorId);
188+
}
189+
190+
@Override
191+
public int hashCode() {
192+
return this.type.hashCode() ^
193+
this.id.hashCode() ^
194+
this.subId.hashCode() ^
195+
this.vectorId.hashCode();
196+
}
197+
}

0 commit comments

Comments
 (0)