@@ -18,7 +18,7 @@ bool resizeIndex(HNSW index, unsigned long int new_max_elements);
1818bool markDelete(HNSW index, unsigned long int label);
1919bool unmarkDelete(HNSW index, unsigned long int label);
2020bool isMarkedDeleted(HNSW index, unsigned long int label);
21- bool updatePoint(HNSW index, float *vec, unsigned long int label);
21+ bool updatePoint(HNSW index, float *vec, unsigned long int label, float updateNeighborProbability );
2222
2323void getDataByLabel(HNSW index, unsigned long int label, float* out_data);
2424*/
@@ -30,13 +30,6 @@ import (
3030 "unsafe"
3131)
3232
33- func toSlice (v * C.float , len int ) []float32 {
34- // 创建一个指向C数组的slice
35- slice := (* [1 << 30 ]float32 )(unsafe .Pointer (v ))[:len :len ]
36- // 复制slice的值,将其转换为一个新的Go切片
37- return append ([]float32 (nil ), slice ... )
38- }
39-
4033type HNSW struct {
4134 index C.HNSW
4235 spaceType string
@@ -79,7 +72,7 @@ func Load(location string, dim int, spaceType string) *HNSW {
7972 return & hnsw
8073}
8174
82- // Unload TODO Test for release the graph memory
75+ // Unload release the graph memory
8376func (h * HNSW ) Unload () bool {
8477 if h .index == nil {
8578 return false
@@ -129,7 +122,7 @@ func (h *HNSW) AddPoint(vector []float32, label uint32) bool {
129122
130123// AddBatchPoints add some points on graph with goroutine
131124func (h * HNSW ) AddBatchPoints (vectors [][]float32 , labels []uint32 , coroutines int ) bool {
132- if len (vectors ) != len (labels ) {
125+ if len (vectors ) != len (labels ) || coroutines < 1 {
133126 return false
134127 }
135128
@@ -174,7 +167,12 @@ func (h *HNSW) SearchKNN(vector []float32, N int) ([]uint32, []float32) {
174167 return labels [:numResult ], dists [:numResult ]
175168}
176169
170+ // SearchBatchKNN search multiple points on graph with knn-algorithm
177171func (h * HNSW ) SearchBatchKNN (vectors [][]float32 , N , coroutines int ) ([][]uint32 , [][]float32 ) {
172+ if coroutines < 1 {
173+ coroutines = 1
174+ }
175+
178176 var lock sync.Mutex
179177 labelList := make ([][]uint32 , len (vectors ))
180178 distList := make ([][]float32 , len (vectors ))
@@ -240,6 +238,39 @@ func (h *HNSW) GetLabelIsMarkedDeleted(label uint32) bool {
240238 return isDelete
241239}
242240
241+ // UpdatePoint update point on graph
242+ func (h * HNSW ) UpdatePoint (vector []float32 , label uint32 , updateNeighborProbability float32 ) bool {
243+ isUpdate := bool (C .updatePoint (h .index , (* C .float )(unsafe .Pointer (& vector [0 ])), C .ulong (label ), C .float (updateNeighborProbability )))
244+ return isUpdate
245+ }
246+
247+ // UpdateBatchPoints update points on graph
248+ func (h * HNSW ) UpdateBatchPoints (vectors [][]float32 , labels []uint32 , updateNeighborProbabilities []float32 , coroutines int ) bool {
249+ if len (vectors ) != len (labels ) && len (labels ) != len (updateNeighborProbabilities ) || coroutines < 1 {
250+ return false
251+ }
252+
253+ b := len (vectors ) / coroutines
254+ var wg sync.WaitGroup
255+ for i := 0 ; i < coroutines ; i ++ {
256+ wg .Add (1 )
257+
258+ end := (i + 1 ) * b
259+ if i == coroutines - 1 && len (vectors ) > end {
260+ end = len (vectors )
261+ }
262+ go func (thisVectors [][]float32 , thisLabels []uint32 , thisProb []float32 ) {
263+ defer wg .Done ()
264+ for j := 0 ; j < len (thisVectors ); j ++ {
265+ h .UpdatePoint (thisVectors [j ], thisLabels [j ], thisProb [j ])
266+ }
267+ }(vectors [i * b :end ], labels [i * b :end ], updateNeighborProbabilities [i * b :end ])
268+ }
269+
270+ wg .Wait ()
271+ return true
272+ }
273+
243274// GetMaxElements get index max elements
244275func (h * HNSW ) GetMaxElements () int {
245276 maxElements := int (C .getMaxElements (h .index ))
0 commit comments