usearch 2.7.0 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/Dockerfile.libs +1 -1
- package/.github/workflows/release.yml +1 -1
- package/CITATION.cff +1 -1
- package/Cargo.toml +1 -1
- package/README.md +1 -1
- package/conanfile.py +1 -1
- package/csharp/nuget/nuget-package.props +1 -1
- package/include/usearch/index.hpp +1 -1
- package/package.json +1 -1
- package/python/lib.cpp +1 -1
- package/python/scripts/test_tooling.py +11 -0
- package/rust/lib.cpp +5 -0
- package/rust/lib.hpp +5 -0
- package/rust/lib.rs +45 -5
- package/wasmer.toml +1 -1
|
@@ -7,7 +7,7 @@ ARG docker_ip
|
|
|
7
7
|
ARG user_pass
|
|
8
8
|
|
|
9
9
|
RUN apt-get update && \
|
|
10
|
-
apt-get install -y --no-install-recommends cmake g++-12 build-essential libjemalloc-dev golang openssh-client sshpass && \
|
|
10
|
+
apt-get install -y --no-install-recommends cmake g++-12 libc++-dev build-essential libjemalloc-dev golang openssh-client sshpass && \
|
|
11
11
|
apt-get clean && \
|
|
12
12
|
rm -rf /var/lib/apt/lists/*
|
|
13
13
|
|
|
@@ -95,7 +95,7 @@ jobs:
|
|
|
95
95
|
--build-arg docker_ip=${{ steps.dockerip.outputs.docker_ip }} \
|
|
96
96
|
--build-arg user_pass=${{ steps.userpass.outputs.user_pass }} \
|
|
97
97
|
--file .github/workflows/Dockerfile.libs \
|
|
98
|
-
--tag unum/
|
|
98
|
+
--tag unum/usearch-library:latest \
|
|
99
99
|
--load .
|
|
100
100
|
- name: Clear Docker buildx cache
|
|
101
101
|
run: docker buildx prune --all --force
|
package/CITATION.cff
CHANGED
package/Cargo.toml
CHANGED
package/README.md
CHANGED
package/conanfile.py
CHANGED
|
@@ -7,7 +7,7 @@ required_conan_version = ">=1.53.0"
|
|
|
7
7
|
class USearchConan(ConanFile):
|
|
8
8
|
|
|
9
9
|
name = "usearch"
|
|
10
|
-
version = '2.7.
|
|
10
|
+
version = '2.7.1'
|
|
11
11
|
license = "Apache-2.0"
|
|
12
12
|
description = "Smaller & Faster Single-File Vector Search Engine from Unum"
|
|
13
13
|
homepage = "https://github.com/unum-cloud/usearch"
|
package/package.json
CHANGED
package/python/lib.cpp
CHANGED
|
@@ -373,8 +373,8 @@ static void search_typed( //
|
|
|
373
373
|
atomic_error.store("Operation has been terminated");
|
|
374
374
|
return false;
|
|
375
375
|
}
|
|
376
|
-
return true;
|
|
377
376
|
}
|
|
377
|
+
return true;
|
|
378
378
|
});
|
|
379
379
|
|
|
380
380
|
// At the end report the latest numbers, because the reporter thread may be finished earlier
|
|
@@ -118,5 +118,16 @@ def test_multi_index():
|
|
|
118
118
|
index_b.add(43, vectors[1])
|
|
119
119
|
|
|
120
120
|
indexes = Indexes([index_a, index_b])
|
|
121
|
+
|
|
122
|
+
# Search top 10 for 1
|
|
121
123
|
matches = indexes.search(vectors[2], 10)
|
|
122
124
|
assert len(matches) == 2
|
|
125
|
+
|
|
126
|
+
# Search top 1 for 1
|
|
127
|
+
matches = indexes.search(vectors[2], 1)
|
|
128
|
+
assert len(matches) == 1
|
|
129
|
+
|
|
130
|
+
# Search top 10 for 3
|
|
131
|
+
matches = indexes.search(vectors, 10)
|
|
132
|
+
assert len(matches) == 3
|
|
133
|
+
assert len(matches[0].keys) == 2
|
package/rust/lib.cpp
CHANGED
|
@@ -42,6 +42,11 @@ size_t NativeIndex::get_f32(key_t key, rust::Slice<float> vec) const { if (vec.s
|
|
|
42
42
|
size_t NativeIndex::get_f64(key_t key, rust::Slice<double> vec) const { if (vec.size() % dimensions()) throw std::invalid_argument("Vector length must be a multiple of index dimensionality"); return index_->get(key, vec.data(), vec.size() / dimensions()); }
|
|
43
43
|
// clang-format on
|
|
44
44
|
|
|
45
|
+
size_t NativeIndex::expansion_add() const { return index_->expansion_add(); }
|
|
46
|
+
size_t NativeIndex::expansion_search() const { return index_->expansion_search(); }
|
|
47
|
+
void NativeIndex::change_expansion_add(size_t n) const { index_->change_expansion_add(n); }
|
|
48
|
+
void NativeIndex::change_expansion_search(size_t n) const { index_->change_expansion_search(n); }
|
|
49
|
+
|
|
45
50
|
size_t NativeIndex::remove(key_t key) const {
|
|
46
51
|
labeling_result_t result = index_->remove(key);
|
|
47
52
|
result.error.raise();
|
package/rust/lib.hpp
CHANGED
|
@@ -36,6 +36,11 @@ class NativeIndex {
|
|
|
36
36
|
size_t get_f32(key_t key, rust::Slice<float> vector) const;
|
|
37
37
|
size_t get_f64(key_t key, rust::Slice<double> vector) const;
|
|
38
38
|
|
|
39
|
+
size_t expansion_add() const;
|
|
40
|
+
size_t expansion_search() const;
|
|
41
|
+
void change_expansion_add(size_t n) const;
|
|
42
|
+
void change_expansion_search(size_t n) const;
|
|
43
|
+
|
|
39
44
|
size_t count(key_t key) const;
|
|
40
45
|
size_t remove(key_t key) const;
|
|
41
46
|
size_t rename(key_t from, key_t to) const;
|
package/rust/lib.rs
CHANGED
|
@@ -46,6 +46,11 @@ pub mod ffi {
|
|
|
46
46
|
/// Low-level C++ interface that is further wrapped into the high-level `Index`
|
|
47
47
|
type NativeIndex;
|
|
48
48
|
|
|
49
|
+
pub fn expansion_add(self: &NativeIndex) -> usize;
|
|
50
|
+
pub fn expansion_search(self: &NativeIndex) -> usize;
|
|
51
|
+
pub fn change_expansion_add(self: &NativeIndex, n: usize) -> Result<()>;
|
|
52
|
+
pub fn change_expansion_search(self: &NativeIndex, n: usize) -> Result<()>;
|
|
53
|
+
|
|
49
54
|
pub fn new_native_index(options: &IndexOptions) -> Result<UniquePtr<NativeIndex>>;
|
|
50
55
|
pub fn reserve(self: &NativeIndex, capacity: usize) -> Result<()>;
|
|
51
56
|
pub fn dimensions(self: &NativeIndex) -> usize;
|
|
@@ -176,6 +181,26 @@ impl Index {
|
|
|
176
181
|
}
|
|
177
182
|
}
|
|
178
183
|
|
|
184
|
+
/// Retrieves the expansion value used during index creation.
|
|
185
|
+
pub fn expansion_add(self: &Index) -> usize {
|
|
186
|
+
self.inner.expansion_add()
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/// Retrieves the expansion value used during search.
|
|
190
|
+
pub fn expansion_search(self: &Index) -> usize {
|
|
191
|
+
self.inner.expansion_search()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/// Updates the expansion value used during index creation. Rarely used.
|
|
195
|
+
pub fn change_expansion_add(self: &Index, n: usize) -> Result<(), cxx::Exception> {
|
|
196
|
+
self.inner.change_expansion_add(n)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/// Updates the expansion value used during search operations.
|
|
200
|
+
pub fn change_expansion_search(self: &Index, n: usize) -> Result<(), cxx::Exception> {
|
|
201
|
+
self.inner.change_expansion_search(n)
|
|
202
|
+
}
|
|
203
|
+
|
|
179
204
|
/// Performs k-Approximate Nearest Neighbors (kANN) Search for closest vectors to the provided query.
|
|
180
205
|
///
|
|
181
206
|
/// # Arguments
|
|
@@ -204,10 +229,10 @@ impl Index {
|
|
|
204
229
|
T::add(self, key, vector)
|
|
205
230
|
}
|
|
206
231
|
|
|
207
|
-
/// Extracts one or more vectors matching specified key.
|
|
208
|
-
/// The `vector` slice must be a multiple number of dimensions in the index.
|
|
209
|
-
/// After the execution return the number `X` of vectors found.
|
|
210
|
-
/// The first `X * dimensions` elements
|
|
232
|
+
/// Extracts one or more vectors matching the specified key.
|
|
233
|
+
/// The `vector` slice must be a multiple of the number of dimensions in the index.
|
|
234
|
+
/// After the execution, return the number `X` of vectors found.
|
|
235
|
+
/// The vector slice's first `X * dimensions` elements will be filled.
|
|
211
236
|
///
|
|
212
237
|
/// If you are a novice user, consider `export`.
|
|
213
238
|
///
|
|
@@ -224,7 +249,7 @@ impl Index {
|
|
|
224
249
|
}
|
|
225
250
|
|
|
226
251
|
/// Extracts one or more vectors matching specified key into supplied resizable vector.
|
|
227
|
-
/// The `vector` is resized to a multiple number of dimensions in the index.
|
|
252
|
+
/// The `vector` is resized to a multiple of the number of dimensions in the index.
|
|
228
253
|
///
|
|
229
254
|
/// # Arguments
|
|
230
255
|
///
|
|
@@ -448,6 +473,9 @@ mod tests {
|
|
|
448
473
|
|
|
449
474
|
let index = Index::new(&options).unwrap();
|
|
450
475
|
|
|
476
|
+
assert!(index.expansion_add() > 0);
|
|
477
|
+
assert!(index.expansion_search() > 0);
|
|
478
|
+
|
|
451
479
|
assert!(index.reserve(10).is_ok());
|
|
452
480
|
assert!(index.capacity() >= 10);
|
|
453
481
|
assert!(index.connectivity() != 0);
|
|
@@ -464,7 +492,11 @@ mod tests {
|
|
|
464
492
|
index.memory_usage(),
|
|
465
493
|
index.capacity(),
|
|
466
494
|
);
|
|
495
|
+
assert!(index.change_expansion_add(10).is_ok());
|
|
496
|
+
assert_eq!(index.expansion_add(), 10);
|
|
467
497
|
assert!(index.add(42, &first).is_ok());
|
|
498
|
+
assert!(index.change_expansion_add(12).is_ok());
|
|
499
|
+
assert_eq!(index.expansion_add(), 12);
|
|
468
500
|
assert!(index.add(43, &second).is_ok());
|
|
469
501
|
assert_eq!(index.size(), 2);
|
|
470
502
|
println!(
|
|
@@ -475,11 +507,19 @@ mod tests {
|
|
|
475
507
|
index.capacity(),
|
|
476
508
|
);
|
|
477
509
|
|
|
510
|
+
assert!(index.change_expansion_search(10).is_ok());
|
|
511
|
+
assert_eq!(index.expansion_search(), 10);
|
|
478
512
|
// Read back the tags
|
|
479
513
|
let results = index.search(&first, 10).unwrap();
|
|
480
514
|
println!("{:?}", results);
|
|
481
515
|
assert_eq!(results.keys.len(), 2);
|
|
482
516
|
|
|
517
|
+
assert!(index.change_expansion_search(12).is_ok());
|
|
518
|
+
assert_eq!(index.expansion_search(), 12);
|
|
519
|
+
let results = index.search(&first, 10).unwrap();
|
|
520
|
+
println!("{:?}", results);
|
|
521
|
+
assert_eq!(results.keys.len(), 2);
|
|
522
|
+
|
|
483
523
|
// Validate serialization
|
|
484
524
|
assert!(index.save("index.rust.usearch").is_ok());
|
|
485
525
|
assert!(index.load("index.rust.usearch").is_ok());
|