Skip to content

Commit 8d2a88e

Browse files
authored
Add: Broader GoLang API #654
2 parents ff50d79 + f222b5f commit 8d2a88e

File tree

2 files changed

+438
-14
lines changed

2 files changed

+438
-14
lines changed

golang/lib.go

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,25 @@ func (a Quantization) String() string {
111111
}
112112
}
113113

114+
func (a Quantization) CValue() C.usearch_scalar_kind_t {
115+
switch a {
116+
case F16:
117+
return C.usearch_scalar_f16_k
118+
case F32:
119+
return C.usearch_scalar_f32_k
120+
case F64:
121+
return C.usearch_scalar_f64_k
122+
case I8:
123+
return C.usearch_scalar_i8_k
124+
case B1:
125+
return C.usearch_scalar_b1_k
126+
case BF16:
127+
return C.usearch_scalar_bf16_k
128+
default:
129+
return C.usearch_scalar_unknown_k
130+
}
131+
}
132+
114133
// IndexConfig represents the configuration options for initializing a USearch index.
115134
type IndexConfig struct {
116135
Quantization Quantization // The scalar kind used for quantization of vector data during indexing.
@@ -161,20 +180,7 @@ func NewIndex(conf IndexConfig) (index *Index, err error) {
161180
options.metric_kind = conf.Metric.CValue()
162181

163182
// Map the quantization method
164-
switch conf.Quantization {
165-
case F16:
166-
options.quantization = C.usearch_scalar_f16_k
167-
case F32:
168-
options.quantization = C.usearch_scalar_f32_k
169-
case F64:
170-
options.quantization = C.usearch_scalar_f64_k
171-
case I8:
172-
options.quantization = C.usearch_scalar_i8_k
173-
case B1:
174-
options.quantization = C.usearch_scalar_b1_k
175-
default:
176-
options.quantization = C.usearch_scalar_unknown_k
177-
}
183+
options.quantization = conf.Quantization.CValue()
178184

179185
var errorMessage *C.char
180186
ptr := C.usearch_init(&options, (*C.usearch_error_t)(&errorMessage))
@@ -361,6 +367,20 @@ func (index *Index) Add(key Key, vec []float32) error {
361367
return nil
362368
}
363369

370+
// Add adds a vector with a specified key to the index.
371+
func (index *Index) AddWithPointer(key Key, vec unsafe.Pointer) error {
372+
if index.opaque_handle == nil {
373+
panic("Index is uninitialized")
374+
}
375+
376+
var errorMessage *C.char
377+
C.usearch_add((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (C.usearch_key_t)(key), vec, index.config.Quantization.CValue(), (*C.usearch_error_t)(&errorMessage))
378+
if errorMessage != nil {
379+
return errors.New(C.GoString(errorMessage))
380+
}
381+
return nil
382+
}
383+
364384
// Remove removes the vector associated with the given key from the index.
365385
func (index *Index) Remove(key Key) error {
366386
if index.opaque_handle == nil {
@@ -428,6 +448,17 @@ func Distance(vec1 []float32, vec2 []float32, dims uint, metric Metric) (float32
428448
return float32(dist), nil
429449
}
430450

451+
// Distance computes the distance between two vectors
452+
func DistanceWithPointer(vec1 unsafe.Pointer, vec2 unsafe.Pointer, dims uint, metric Metric, quantization Quantization) (float32, error) {
453+
454+
var errorMessage *C.char
455+
dist := C.usearch_distance(vec1, vec2, quantization.CValue(), C.size_t(dims), metric.CValue(), (*C.usearch_error_t)(&errorMessage))
456+
if errorMessage != nil {
457+
return 0, errors.New(C.GoString(errorMessage))
458+
}
459+
return float32(dist), nil
460+
}
461+
431462
// Search performs k-Approximate Nearest Neighbors Search for the closest vectors to the query vector.
432463
func (index *Index) Search(query []float32, limit uint) (keys []Key, distances []float32, err error) {
433464
if index.opaque_handle == nil {
@@ -450,6 +481,25 @@ func (index *Index) Search(query []float32, limit uint) (keys []Key, distances [
450481
return keys, distances, nil
451482
}
452483

484+
// Search performs k-Approximate Nearest Neighbors Search for the closest vectors to the query vector.
485+
func (index *Index) SearchWithPointer(query unsafe.Pointer, limit uint) (keys []Key, distances []float32, err error) {
486+
if index.opaque_handle == nil {
487+
panic("Index is uninitialized")
488+
}
489+
490+
keys = make([]Key, limit)
491+
distances = make([]float32, limit)
492+
var errorMessage *C.char
493+
count := uint(C.usearch_search((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), query, index.config.Quantization.CValue(), (C.size_t)(limit), (*C.usearch_key_t)(&keys[0]), (*C.usearch_distance_t)(&distances[0]), (*C.usearch_error_t)(&errorMessage)))
494+
if errorMessage != nil {
495+
return nil, nil, errors.New(C.GoString(errorMessage))
496+
}
497+
498+
keys = keys[:count]
499+
distances = distances[:count]
500+
return keys, distances, nil
501+
}
502+
453503
// ExactSearch is a multithreaded exact nearest neighbors search
454504
func ExactSearch(dataset []float32, queries []float32, dataset_size uint, queries_size uint,
455505
dataset_stride uint, queries_stride uint, dims uint, metric Metric,
@@ -476,6 +526,26 @@ func ExactSearch(dataset []float32, queries []float32, dataset_size uint, querie
476526
return keys, distances, nil
477527
}
478528

529+
// ExactSearch is a multithreaded exact nearest neighbors search
530+
func ExactSearchWithPointer(dataset unsafe.Pointer, queries unsafe.Pointer, dataset_size uint, queries_size uint,
531+
dataset_stride uint, queries_stride uint, dims uint, metric Metric, quantization Quantization,
532+
count uint, threads uint, keys_stride uint, distances_stride uint) (keys []Key, distances []float32, err error) {
533+
534+
keys = make([]Key, count)
535+
distances = make([]float32, count)
536+
var errorMessage *C.char
537+
C.usearch_exact_search(dataset, C.size_t(dataset_size), C.size_t(dataset_stride), queries, C.size_t(queries_size), C.size_t(queries_stride),
538+
quantization.CValue(), C.size_t(dims), metric.CValue(), C.size_t(count), C.size_t(threads),
539+
(*C.usearch_key_t)(&keys[0]), C.size_t(keys_stride), (*C.usearch_distance_t)(&distances[0]), C.size_t(distances_stride), (*C.usearch_error_t)(&errorMessage))
540+
if errorMessage != nil {
541+
return nil, nil, errors.New(C.GoString(errorMessage))
542+
}
543+
544+
keys = keys[:count]
545+
distances = distances[:count]
546+
return keys, distances, nil
547+
}
548+
479549
// Save saves the index to a specified buffer.
480550
func (index *Index) SaveBuffer(buf []byte, buffer_size uint) error {
481551
if index.opaque_handle == nil {

0 commit comments

Comments
 (0)