Skip to content

Commit

Permalink
Fix: Unpacking JS batch requests
Browse files Browse the repository at this point in the history
Closes #303
ashvardanian committed Nov 9, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent cf1b58f commit b761680
Showing 3 changed files with 70 additions and 16 deletions.
76 changes: 64 additions & 12 deletions javascript/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,88 @@
# USearch for JavaScript

USearch is a high-performance library for building and querying vector search indexes, optimized for Node.js and WASM environments.

## Installation

USearch is available both for Node.js backend runtime and WASM frontend runtime.
For the first option, use the conventional `npm install`:
For Node.js environments, install USearch using `npm`:

```sh
npm install usearch
```

For latter:
For front-end applications using WASM, use the Wasmer package manager:

```sh
wasmer install unum/usearch
```

## Quickstart

Create an index, add vectors, and perform searches with ease:

```js
var index = new usearch.Index({ metric: 'cos', connectivity: 16n, dimensions: 3n })
index.add(42n, new Float32Array([0.2, 0.6, 0.4]))
var results = index.search(new Float32Array([0.2, 0.6, 0.4]), 10n)
const usearch = require('usearch');
const index = new usearch.Index({ metric: 'cos', connectivity: 16, dimensions: 3 });
index.add(42n, new Float32Array([0.2, 0.6, 0.4]));
const results = index.search(new Float32Array([0.2, 0.6, 0.4]), 10);

assert(index.size() === 1);
assert.deepEqual(results.keys, new BigUint64Array([42n]));
assert.deepEqual(results.distances, new Float32Array([0]));

assert.equal(index.size(), 1n)
assert.deepEqual(results.keys, new BigUint64Array([42n]))
assert.deepEqual(results.distances, new Float32Array([0]))
index.remove(42n);
```

## Serialization

Persist and restore your index with serialization methods:

```js
index.save('index.usearch'); // Save the index to a file
index.load('index.usearch'); // Load the index from a file
index.view('index.usearch'); // View the index from a file without loading into memory
```

## Advanced Index Configuration

Customize your index with additional configuration options:

```js
const index = new usearch.Index({
dimensions: 128,
metric: 'ip',
quantization: 'f32',
connectivity: 10,
expansion_add: 5,
expansion_search: 3,
multi: true
});
```

## Batch Operations

Process multiple vectors at once for efficiency.
For performance reasons we prefer a flattened `TypedArray` over an Array of Arrays:

```js
const keys = new BigUint64Array([15n, 16n]);
const vectors = new Float32Array([10, 20, 10, 25]);
index.add(keys, vectors);
```

Retrieve batch search results:

```js
const batchResults = index.search(vectors, 2);
const firstMatch = batchResults.get(0);
```

## Index Introspection

Inspect and interact with the index:

```js
index.save('index.usearch')
index.load('index.usearch')
index.view('index.usearch')
const dimensions = index.dimensions(); // Get the number of dimensions
const containsKey = index.contains(42n); // Check if a key is in the index
const count = index.count(42n); // Get the count of vectors for a key
```
4 changes: 2 additions & 2 deletions javascript/lib.cpp
Original file line number Diff line number Diff line change
@@ -196,8 +196,8 @@ Napi::Value CompiledIndex::Search(Napi::CallbackInfo const& ctx) {
executor.fixed(tasks, [&](std::size_t /*thread_idx*/, std::size_t task_idx) {
auto result = native_->search(vectors + task_idx * native_->dimensions(), wanted);
if (!result) {
// Handle the error appropriately
// For example, log the error or set some flag in the result_js object
Napi::TypeError::New(env, result.error.release()).ThrowAsJavaScriptException();
return env.Null();
} else {
counts_data[task_idx] = result.dump_to(matches_data + task_idx * native_->dimensions(),
distances_data + task_idx * native_->dimensions());
6 changes: 4 additions & 2 deletions javascript/usearch.js
Original file line number Diff line number Diff line change
@@ -247,10 +247,12 @@ class Index {
// Call the compiled method and create Matches or BatchMatches object with the result
const result = this._compiledIndex.search(normalizedVectors, k);
const countInQueries = normalizedVectors.length / Number(this._compiledIndex.dimensions());
const batchMatches = new BatchMatches(result[0], result[1], result[2], k);

if (countInQueries === 1) {
return new Matches(result[0], result[1]);
return batchMatches.get(0);
} else {
return new BatchMatches(result[0], result[1], result[2], k);
return batchMatches;
}
}

0 comments on commit b761680

Please sign in to comment.