Skip to content

Conversation

@cpegeric
Copy link
Contributor

@cpegeric cpegeric commented Jan 16, 2026

Add GetHandle and GetConfig to give access to the C handle for filtered search with pure C callback function to remove huge cgo overhead.

We want to pass the bloomfilter in C and process the callback functions in C instead of Go but cannot access the private handle and config for now.

The code below shows what we are trying to do from our side. This fix gives us the index handle and config to workaround with our own filtered_search_callback in C.


In C,

static int filtered_search_cb(usearch_key_t key, void *data) {
    bloomfilter_t *bf = (bloomfilter_t*) data;
    if (bf) {
        return bloomfilter_test(bf, (const char *)&key, sizeof(usearch_key_t));
    }
    return 1;
}

size_t usearchex_filtered_search_with_bloomfilter(
    usearch_index_t index,
    void const* query_vector, usearch_scalar_kind_t query_kind, size_t count,
    void *bf,
    usearch_key_t* keys, usearch_distance_t* distances, usearch_error_t* error) {

    return usearch_filtered_search((usearch_index_t)index, 
            query_vector, 
            (usearch_scalar_kind_t)query_kind, 
            count, 
            filtered_search_cb, 
            bf, 
            keys, 
            distances, 
            error);
}


In Go,


func FilteredSearchUnsafeWithBloomFilter(
	index *usearch.Index,
	query unsafe.Pointer,
	limit uint,
	bf *bloomfilter.CBloomFilter,
) (keys []usearch.Key, distances []float32, err error) {
	var errorMessage *C.char

	if index.GetHandle() == nil {
		panic("index is uninitialized")
	}
	handle := C.usearch_index_t(index.GetHandle())

	var bfptr unsafe.Pointer
	if bf != nil {
		bfptr = unsafe.Pointer(bf.Ptr())
	}

	if query == nil {
		return nil, nil, errors.New("query pointer cannot be nil")
	}

	if limit == 0 {
		return []usearch.Key{}, []float32{}, nil
	}

	keys = make([]usearch.Key, limit)
	distances = make([]float32, limit)

	resultCount := uint(C.usearchex_filtered_search_with_bloomfilter(
		handle,
		query,
		C.usearch_scalar_kind_t(index.GetConfig().Quantization.CValue()),
		C.size_t(limit),
		bfptr,
		(*C.usearch_key_t)(&keys[0]),
		(*C.usearch_distance_t)(&distances[0]),
		(*C.usearch_error_t)(&errorMessage)))

	if errorMessage != nil {
		return nil, nil, errors.New(C.GoString(errorMessage))
	}

	keys = keys[:resultCount]
	distances = distances[:resultCount]
	return keys, distances, nil
}

…red search with pure C callback function to remove huge cgo overhead
@cpegeric cpegeric changed the title Add: GetHandle and GetConfig to give access to the C handle Add: GetHandle and GetConfig to give access to the C handle in Golang Jan 16, 2026
@cpegeric cpegeric closed this Jan 16, 2026
@cpegeric cpegeric reopened this Jan 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant