usearch 1.2.2 → 2.0.0
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/prerelease.yml +71 -0
- package/.github/workflows/release.yml +77 -2
- package/.github/workflows/update_version.sh +1 -0
- package/.gitignore +11 -1
- package/.vscode/settings.json +5 -1
- package/CMakeLists.txt +1 -0
- package/Cargo.toml +1 -1
- package/README.md +31 -18
- package/c/lib.cpp +38 -4
- package/c/test.c +117 -114
- package/c/usearch.h +28 -1
- package/conanfile.py +1 -1
- package/cpp/test.cpp +2 -2
- package/csharp/.editorconfig +361 -0
- package/csharp/Cloud.Unum.USearch.sln +34 -0
- package/csharp/DEV_SETUP.md +51 -0
- package/csharp/Directory.Build.props +29 -0
- package/csharp/README.md +77 -0
- package/csharp/build_and_test.cmd +31 -0
- package/csharp/build_and_test.sh +30 -0
- package/csharp/eng/build_lib.sh +65 -0
- package/csharp/eng/clean.sh +12 -0
- package/csharp/nuget/NUGET.md +11 -0
- package/csharp/nuget/nuget-package.props +33 -0
- package/csharp/pack.sh +56 -0
- package/csharp/src/Cloud.Unum.USearch.Tests/Cloud.Unum.USearch.Tests.csproj +39 -0
- package/csharp/src/Cloud.Unum.USearch.Tests/InitTests.cs +306 -0
- package/csharp/src/Cloud.Unum.USearch.Tests/Usings.cs +1 -0
- package/docs/benchmarks.md +6 -6
- package/docs/compilation.md +1 -1
- package/include/usearch/index.hpp +172 -52
- package/include/usearch/index_dense.hpp +201 -64
- package/include/usearch/index_plugins.hpp +90 -69
- package/package.json +2 -2
- package/python/lib.cpp +99 -37
- package/python/scripts/test_index.py +38 -10
- package/python/usearch/index.py +87 -37
- package/rust/README.md +2 -2
- package/rust/lib.cpp +42 -19
- package/rust/lib.hpp +14 -0
- package/rust/lib.rs +85 -43
- package/wasmer.toml +1 -1
package/c/test.c
CHANGED
|
@@ -13,46 +13,18 @@
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
ASSERT(file, "Failed to open the file");
|
|
23
|
-
|
|
24
|
-
// Read vectors dimension and calculate count
|
|
25
|
-
int dim = 0;
|
|
26
|
-
size_t read = fread(&dim, sizeof(int), 1, file);
|
|
27
|
-
ASSERT(read == 1, "Failed to read from the file");
|
|
28
|
-
ASSERT(st.st_size % ((dim + 1) * sizeof(float)) == 0, "File does not contain a whole number of vectors");
|
|
29
|
-
*dimension = (size_t)dim;
|
|
30
|
-
*count = st.st_size / ((dim + 1) * sizeof(float));
|
|
31
|
-
|
|
32
|
-
// Allocate memory for the vectors' data
|
|
33
|
-
*data = (float*)malloc(*count * *dimension * sizeof(float));
|
|
34
|
-
ASSERT(*data, "Failed to allocate memory");
|
|
35
|
-
|
|
36
|
-
// Read the data
|
|
37
|
-
for (size_t i = 0; i < *count; ++i) {
|
|
38
|
-
read = fread(*data + i * *dimension, sizeof(float), *dimension, file);
|
|
39
|
-
ASSERT(read == *dimension, "Failed to read from the file");
|
|
40
|
-
if (i == *count - 1)
|
|
41
|
-
break;
|
|
42
|
-
|
|
43
|
-
// Skip
|
|
44
|
-
float skip;
|
|
45
|
-
read = fread(&skip, sizeof(float), 1, file);
|
|
46
|
-
ASSERT(read == 1, "Failed to read from the file");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
fclose(file);
|
|
16
|
+
float* create_vectors(size_t count, size_t dimensions) {
|
|
17
|
+
float* data = (float*)malloc(count * dimensions * sizeof(float));
|
|
18
|
+
ASSERT(data, "Failed to allocate memory");
|
|
19
|
+
for (size_t idx = 0; idx < count * dimensions; ++idx)
|
|
20
|
+
data[idx] = (float)rand() / (float)RAND_MAX;
|
|
21
|
+
return data;
|
|
50
22
|
}
|
|
51
23
|
|
|
52
|
-
usearch_init_options_t create_options(size_t
|
|
24
|
+
usearch_init_options_t create_options(size_t dimensions) {
|
|
53
25
|
usearch_init_options_t opts;
|
|
54
26
|
opts.connectivity = 2; // 32 in faiss
|
|
55
|
-
opts.dimensions =
|
|
27
|
+
opts.dimensions = dimensions;
|
|
56
28
|
opts.expansion_add = 40; // 40 in faiss
|
|
57
29
|
opts.expansion_search = 16; // 10 in faiss
|
|
58
30
|
opts.metric_kind = usearch_metric_ip_k;
|
|
@@ -61,14 +33,13 @@ usearch_init_options_t create_options(size_t vector_dimension) {
|
|
|
61
33
|
return opts;
|
|
62
34
|
}
|
|
63
35
|
|
|
64
|
-
void test_init(size_t
|
|
36
|
+
void test_init(size_t collection_size, size_t dimensions) {
|
|
65
37
|
printf("Test: Index Initialization...\n");
|
|
66
38
|
|
|
67
39
|
// Init index
|
|
68
|
-
usearch_index_t idx = NULL;
|
|
69
40
|
usearch_error_t error = NULL;
|
|
70
|
-
usearch_init_options_t opts = create_options(
|
|
71
|
-
idx = usearch_init(&opts, &error);
|
|
41
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
42
|
+
usearch_index_t idx = usearch_init(&opts, &error);
|
|
72
43
|
ASSERT(!error, error);
|
|
73
44
|
usearch_free(idx, &error);
|
|
74
45
|
ASSERT(!error, error);
|
|
@@ -79,15 +50,15 @@ void test_init(size_t vectors_count, size_t vector_dimension) {
|
|
|
79
50
|
|
|
80
51
|
ASSERT(usearch_size(idx, &error) == 0, error);
|
|
81
52
|
ASSERT(usearch_capacity(idx, &error) == 0, error);
|
|
82
|
-
ASSERT(usearch_dimensions(idx, &error) ==
|
|
53
|
+
ASSERT(usearch_dimensions(idx, &error) == dimensions, error);
|
|
83
54
|
ASSERT(usearch_connectivity(idx, &error) == opts.connectivity, error);
|
|
84
55
|
|
|
85
56
|
// Reserve
|
|
86
|
-
usearch_reserve(idx,
|
|
57
|
+
usearch_reserve(idx, collection_size, &error);
|
|
87
58
|
ASSERT(!error, error);
|
|
88
59
|
ASSERT(usearch_size(idx, &error) == 0, error);
|
|
89
|
-
ASSERT(usearch_capacity(idx, &error) ==
|
|
90
|
-
ASSERT(usearch_dimensions(idx, &error) ==
|
|
60
|
+
ASSERT(usearch_capacity(idx, &error) == collection_size, error);
|
|
61
|
+
ASSERT(usearch_dimensions(idx, &error) == dimensions, error);
|
|
91
62
|
ASSERT(usearch_connectivity(idx, &error) == opts.connectivity, error);
|
|
92
63
|
|
|
93
64
|
usearch_free(idx, &error);
|
|
@@ -96,110 +67,148 @@ void test_init(size_t vectors_count, size_t vector_dimension) {
|
|
|
96
67
|
printf("Test: Index Initialization - PASSED\n");
|
|
97
68
|
}
|
|
98
69
|
|
|
99
|
-
void test_add_vector(size_t
|
|
70
|
+
void test_add_vector(size_t collection_size, size_t dimensions) {
|
|
100
71
|
printf("Test: Add Vector...\n");
|
|
101
72
|
|
|
102
|
-
usearch_index_t idx = NULL;
|
|
103
73
|
usearch_error_t error = NULL;
|
|
104
|
-
usearch_init_options_t opts = create_options(
|
|
105
|
-
idx = usearch_init(&opts, &error);
|
|
106
|
-
usearch_reserve(idx,
|
|
74
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
75
|
+
usearch_index_t idx = usearch_init(&opts, &error);
|
|
76
|
+
usearch_reserve(idx, collection_size, &error);
|
|
107
77
|
|
|
108
78
|
// Add vectors
|
|
109
|
-
|
|
79
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
80
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
110
81
|
usearch_key_t key = i;
|
|
111
|
-
usearch_add(idx, key, data + i *
|
|
82
|
+
usearch_add(idx, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
112
83
|
ASSERT(!error, error);
|
|
113
84
|
}
|
|
114
85
|
|
|
115
|
-
ASSERT(usearch_size(idx, &error) ==
|
|
116
|
-
ASSERT(usearch_capacity(idx, &error) ==
|
|
86
|
+
ASSERT(usearch_size(idx, &error) == collection_size, error);
|
|
87
|
+
ASSERT(usearch_capacity(idx, &error) == collection_size, error);
|
|
117
88
|
|
|
118
89
|
// Check vectors in the index
|
|
119
|
-
for (size_t i = 0; i <
|
|
90
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
120
91
|
usearch_key_t key = i;
|
|
121
92
|
ASSERT(usearch_contains(idx, key, &error), error);
|
|
122
93
|
}
|
|
123
94
|
ASSERT(!usearch_contains(idx, -1, &error), error); // Non existing key
|
|
124
95
|
|
|
96
|
+
free(data);
|
|
125
97
|
usearch_free(idx, &error);
|
|
126
98
|
printf("Test: Add Vector - PASSED\n");
|
|
127
99
|
}
|
|
128
100
|
|
|
129
|
-
void test_find_vector(size_t
|
|
101
|
+
void test_find_vector(size_t collection_size, size_t dimensions) {
|
|
130
102
|
printf("Test: Find Vector...\n");
|
|
131
103
|
|
|
132
|
-
usearch_index_t idx = NULL;
|
|
133
104
|
usearch_error_t error = NULL;
|
|
134
|
-
usearch_init_options_t opts = create_options(
|
|
135
|
-
idx = usearch_init(&opts, &error);
|
|
136
|
-
usearch_reserve(idx,
|
|
105
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
106
|
+
usearch_index_t idx = usearch_init(&opts, &error);
|
|
107
|
+
usearch_reserve(idx, collection_size, &error);
|
|
137
108
|
|
|
138
109
|
// Create result buffers
|
|
139
|
-
int results_count =
|
|
110
|
+
int results_count = collection_size;
|
|
140
111
|
usearch_key_t* keys = (usearch_key_t*)malloc(results_count * sizeof(usearch_key_t));
|
|
141
112
|
float* distances = (float*)malloc(results_count * sizeof(float));
|
|
142
113
|
ASSERT(keys && distances, "Failed to allocate memory");
|
|
143
114
|
|
|
144
115
|
// Add vectors
|
|
145
|
-
|
|
116
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
117
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
146
118
|
usearch_key_t key = i;
|
|
147
|
-
usearch_add(idx, key, data + i *
|
|
119
|
+
usearch_add(idx, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
148
120
|
ASSERT(!error, error);
|
|
149
121
|
}
|
|
150
122
|
|
|
151
123
|
// Find the vectors
|
|
152
|
-
for (size_t i = 0; i <
|
|
153
|
-
const void *query_vector = data + i *
|
|
124
|
+
for (size_t i = 0; i < collection_size; i++) {
|
|
125
|
+
const void *query_vector = data + i * dimensions;
|
|
154
126
|
size_t found_count = usearch_search(idx, query_vector, usearch_scalar_f32_k, results_count, keys, distances, &error);
|
|
155
127
|
ASSERT(!error, error);
|
|
156
128
|
ASSERT(found_count = results_count, "Vector is missing");
|
|
157
129
|
}
|
|
158
130
|
|
|
131
|
+
free(data);
|
|
132
|
+
free(keys);
|
|
133
|
+
free(distances);
|
|
159
134
|
usearch_free(idx, &error);
|
|
160
135
|
printf("Test: Find Vector - PASSED\n");
|
|
161
136
|
}
|
|
162
137
|
|
|
163
|
-
void
|
|
138
|
+
void test_get_vector(size_t collection_size, size_t dimensions) {
|
|
139
|
+
printf("Test: Get Vector...\n");
|
|
140
|
+
|
|
141
|
+
usearch_error_t error = NULL;
|
|
142
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
143
|
+
opts.multi = true;
|
|
144
|
+
usearch_index_t idx = usearch_init(&opts, &error);
|
|
145
|
+
usearch_reserve(idx, collection_size, &error);
|
|
146
|
+
|
|
147
|
+
// Create result buffers
|
|
148
|
+
int results_count = collection_size;
|
|
149
|
+
float* vectors = (float*)malloc(results_count * dimensions * sizeof(float));
|
|
150
|
+
ASSERT(vectors, "Failed to allocate memory");
|
|
151
|
+
|
|
152
|
+
// Add multiple vectors with SAME key
|
|
153
|
+
usearch_key_t const key = 1;
|
|
154
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
155
|
+
for (size_t i = 0; i < collection_size; i++) {
|
|
156
|
+
usearch_add(idx, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
157
|
+
ASSERT(!error, error);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Retrieve vectors from index
|
|
161
|
+
size_t count = usearch_get(idx, key, collection_size, vectors, usearch_scalar_f32_k, &error);
|
|
162
|
+
ASSERT(count == results_count, "Vector is missing");
|
|
163
|
+
|
|
164
|
+
free(vectors);
|
|
165
|
+
free(data);
|
|
166
|
+
usearch_free(idx, &error);
|
|
167
|
+
|
|
168
|
+
printf("Test: Get Vector - PASSED\n");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
void test_remove_vector(size_t collection_size, size_t dimensions) {
|
|
164
172
|
printf("Test: Remove Vector...\n");
|
|
165
173
|
|
|
166
|
-
usearch_index_t idx = NULL;
|
|
167
174
|
usearch_error_t error = NULL;
|
|
168
|
-
usearch_init_options_t opts = create_options(
|
|
169
|
-
idx = usearch_init(&opts, &error);
|
|
170
|
-
usearch_reserve(idx,
|
|
175
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
176
|
+
usearch_index_t idx = usearch_init(&opts, &error);
|
|
177
|
+
usearch_reserve(idx, collection_size, &error);
|
|
171
178
|
|
|
172
179
|
// Add vectors
|
|
173
|
-
|
|
180
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
181
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
174
182
|
usearch_key_t key = i;
|
|
175
|
-
usearch_add(idx, key, data + i *
|
|
183
|
+
usearch_add(idx, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
176
184
|
ASSERT(!error, error);
|
|
177
185
|
}
|
|
178
186
|
|
|
179
187
|
// Remove the vectors
|
|
180
|
-
for (size_t i = 0; i <
|
|
188
|
+
for (size_t i = 0; i < collection_size; i++) {
|
|
181
189
|
usearch_key_t key = i;
|
|
182
190
|
usearch_remove(idx, key, &error);
|
|
183
|
-
ASSERT(error, "Currently, Remove is not supported");
|
|
191
|
+
ASSERT(!error, "Currently, Remove is not supported");
|
|
184
192
|
}
|
|
185
193
|
|
|
194
|
+
free(data);
|
|
186
195
|
usearch_free(idx, &error);
|
|
187
196
|
printf("Test: Remove Vector - PASSED\n");
|
|
188
197
|
}
|
|
189
198
|
|
|
190
|
-
void test_save_load(size_t
|
|
199
|
+
void test_save_load(size_t collection_size, size_t dimensions) {
|
|
191
200
|
printf("Test: Save/Load...\n");
|
|
192
201
|
|
|
193
|
-
usearch_index_t idx = NULL;
|
|
194
202
|
usearch_error_t error = NULL;
|
|
195
|
-
usearch_init_options_t opts = create_options(
|
|
196
|
-
idx = usearch_init(&opts, &error);
|
|
197
|
-
usearch_reserve(idx,
|
|
203
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
204
|
+
usearch_index_t idx = usearch_init(&opts, &error);
|
|
205
|
+
usearch_reserve(idx, collection_size, &error);
|
|
198
206
|
|
|
199
207
|
// Add vectors
|
|
200
|
-
|
|
208
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
209
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
201
210
|
usearch_key_t key = i;
|
|
202
|
-
usearch_add(idx, key, data + i *
|
|
211
|
+
usearch_add(idx, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
203
212
|
ASSERT(!error, error);
|
|
204
213
|
}
|
|
205
214
|
|
|
@@ -217,34 +226,35 @@ void test_save_load(size_t vectors_count, size_t vector_dimension, float const*
|
|
|
217
226
|
// Load
|
|
218
227
|
usearch_load(idx, "usearch_index.bin", &error);
|
|
219
228
|
ASSERT(!error, error);
|
|
220
|
-
ASSERT(usearch_size(idx, &error) ==
|
|
221
|
-
ASSERT(usearch_capacity(idx, &error) ==
|
|
222
|
-
ASSERT(usearch_dimensions(idx, &error) ==
|
|
229
|
+
ASSERT(usearch_size(idx, &error) == collection_size, error);
|
|
230
|
+
ASSERT(usearch_capacity(idx, &error) == collection_size, error);
|
|
231
|
+
ASSERT(usearch_dimensions(idx, &error) == dimensions, error);
|
|
223
232
|
ASSERT(usearch_connectivity(idx, &error) == opts.connectivity, error);
|
|
224
233
|
|
|
225
234
|
// Check vectors in the index
|
|
226
|
-
for (size_t i = 0; i <
|
|
235
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
227
236
|
usearch_key_t key = i;
|
|
228
237
|
ASSERT(usearch_contains(idx, key, &error), error);
|
|
229
238
|
}
|
|
230
239
|
|
|
240
|
+
free(data);
|
|
231
241
|
usearch_free(idx, &error);
|
|
232
242
|
printf("Test: Save/Load - PASSED\n");
|
|
233
243
|
}
|
|
234
244
|
|
|
235
|
-
void test_view(size_t
|
|
245
|
+
void test_view(size_t collection_size, size_t dimensions) {
|
|
236
246
|
printf("Test: View...\n");
|
|
237
247
|
|
|
238
|
-
usearch_index_t idx = NULL;
|
|
239
248
|
usearch_error_t error = NULL;
|
|
240
|
-
usearch_init_options_t opts = create_options(
|
|
241
|
-
idx = usearch_init(&opts, &error);
|
|
242
|
-
usearch_reserve(idx,
|
|
249
|
+
usearch_init_options_t opts = create_options(dimensions);
|
|
250
|
+
usearch_index_t idx = usearch_init(&opts, &error);
|
|
251
|
+
usearch_reserve(idx, collection_size, &error);
|
|
243
252
|
|
|
244
253
|
// Add vectors
|
|
245
|
-
|
|
254
|
+
float* data = create_vectors(collection_size, dimensions);
|
|
255
|
+
for (size_t i = 0; i < collection_size; ++i) {
|
|
246
256
|
usearch_key_t key = i;
|
|
247
|
-
usearch_add(idx, key, data + i *
|
|
257
|
+
usearch_add(idx, key, data + i * dimensions, usearch_scalar_f32_k, &error);
|
|
248
258
|
ASSERT(!error, error);
|
|
249
259
|
}
|
|
250
260
|
|
|
@@ -262,33 +272,26 @@ void test_view(size_t vectors_count, size_t vector_dimension, float const* data)
|
|
|
262
272
|
usearch_view(idx, "usearch_index.bin", &error);
|
|
263
273
|
ASSERT(!error, error);
|
|
264
274
|
|
|
275
|
+
free(data);
|
|
265
276
|
usearch_free(idx, &error);
|
|
266
277
|
printf("Test: View - PASSED\n");
|
|
267
278
|
}
|
|
268
279
|
|
|
269
|
-
int main(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
test_add_vector(vectors_count, vector_dimension, data);
|
|
285
|
-
test_find_vector(vectors_count, vector_dimension, data);
|
|
286
|
-
test_remove_vector(vectors_count, vector_dimension, data);
|
|
287
|
-
test_save_load(vectors_count, vector_dimension, data);
|
|
288
|
-
test_view(vectors_count, vector_dimension, data);
|
|
289
|
-
|
|
290
|
-
// Free vectors' buffer
|
|
291
|
-
free(data);
|
|
280
|
+
int main() {
|
|
281
|
+
|
|
282
|
+
size_t collection_sizes[] = {11, 512};
|
|
283
|
+
size_t dimensions[] = {83, 1};
|
|
284
|
+
for (size_t idx = 0; idx < sizeof(collection_sizes) / sizeof(collection_sizes[0]); ++idx) {
|
|
285
|
+
for (size_t jdx = 0; jdx < sizeof(dimensions) / sizeof(dimensions[0]); ++jdx) {
|
|
286
|
+
test_init(collection_sizes[idx], dimensions[jdx]);
|
|
287
|
+
test_add_vector(collection_sizes[idx], dimensions[jdx]);
|
|
288
|
+
test_find_vector(collection_sizes[idx], dimensions[jdx]);
|
|
289
|
+
test_get_vector(collection_sizes[idx], dimensions[jdx]);
|
|
290
|
+
test_remove_vector(collection_sizes[idx], dimensions[jdx]);
|
|
291
|
+
test_save_load(collection_sizes[idx], dimensions[jdx]);
|
|
292
|
+
test_view(collection_sizes[idx], dimensions[jdx]);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
292
295
|
|
|
293
296
|
return 0;
|
|
294
297
|
}
|
package/c/usearch.h
CHANGED
|
@@ -109,6 +109,12 @@ USEARCH_EXPORT usearch_index_t usearch_init(usearch_init_options_t* options, use
|
|
|
109
109
|
*/
|
|
110
110
|
USEARCH_EXPORT void usearch_free(usearch_index_t, usearch_error_t* error);
|
|
111
111
|
|
|
112
|
+
/**
|
|
113
|
+
* @brief Reports expected file size after serialization.
|
|
114
|
+
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
|
|
115
|
+
*/
|
|
116
|
+
USEARCH_EXPORT size_t usearch_serialized_length(usearch_index_t, usearch_error_t* error);
|
|
117
|
+
|
|
112
118
|
/**
|
|
113
119
|
* @brief Saves the index to a file.
|
|
114
120
|
* @param[in] path The file path where the index will be saved.
|
|
@@ -124,12 +130,33 @@ USEARCH_EXPORT void usearch_save(usearch_index_t, char const* path, usearch_erro
|
|
|
124
130
|
USEARCH_EXPORT void usearch_load(usearch_index_t, char const* path, usearch_error_t* error);
|
|
125
131
|
|
|
126
132
|
/**
|
|
127
|
-
* @brief Creates a view of the index from a file without
|
|
133
|
+
* @brief Creates a view of the index from a file without copying it into memory.
|
|
128
134
|
* @param[in] path The file path from where the view will be created.
|
|
129
135
|
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
|
|
130
136
|
*/
|
|
131
137
|
USEARCH_EXPORT void usearch_view(usearch_index_t, char const* path, usearch_error_t* error);
|
|
132
138
|
|
|
139
|
+
/**
|
|
140
|
+
* @brief Saves the index to an in-memory buffer.
|
|
141
|
+
* @param[in] buffer The in-memory continuous buffer where the index will be saved.
|
|
142
|
+
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
|
|
143
|
+
*/
|
|
144
|
+
USEARCH_EXPORT void usearch_save_buffer(usearch_index_t, void* buffer, size_t length, usearch_error_t* error);
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @brief Loads the index from an in-memory buffer.
|
|
148
|
+
* @param[in] buffer The in-memory continuous buffer from where the index will be loaded.
|
|
149
|
+
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
|
|
150
|
+
*/
|
|
151
|
+
USEARCH_EXPORT void usearch_load_buffer(usearch_index_t, void const* buffer, size_t length, usearch_error_t* error);
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @brief Creates a view of the index from an in-memory buffer without copying it into memory.
|
|
155
|
+
* @param[in] buffer The in-memory continuous buffer from where the view will be created.
|
|
156
|
+
* @param[out] error Pointer to a string where the error message will be stored, if an error occurs.
|
|
157
|
+
*/
|
|
158
|
+
USEARCH_EXPORT void usearch_view_buffer(usearch_index_t, void const* buffer, size_t length, usearch_error_t* error);
|
|
159
|
+
|
|
133
160
|
USEARCH_EXPORT size_t usearch_size(usearch_index_t, usearch_error_t* error);
|
|
134
161
|
USEARCH_EXPORT size_t usearch_capacity(usearch_index_t, usearch_error_t* error);
|
|
135
162
|
USEARCH_EXPORT size_t usearch_dimensions(usearch_index_t, usearch_error_t* error);
|
package/conanfile.py
CHANGED
|
@@ -4,7 +4,7 @@ from conans import ConanFile
|
|
|
4
4
|
class USearchConan(ConanFile):
|
|
5
5
|
|
|
6
6
|
name = 'USearch'
|
|
7
|
-
version = '
|
|
7
|
+
version = '2.0.0'
|
|
8
8
|
license = 'Apache 2.0'
|
|
9
9
|
url = 'https://github.com/unum-cloud/usearch'
|
|
10
10
|
description = 'Smaller & Faster Single-File Vector Search Engine from Unum'
|
package/cpp/test.cpp
CHANGED
|
@@ -118,7 +118,7 @@ void test_cosine(index_at& index, std::vector<std::vector<scalar_at>> const& vec
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
// Search again over mapped index
|
|
121
|
-
// file_head_result_t head =
|
|
121
|
+
// file_head_result_t head = index_dense_metadata_from_path("tmp.usearch");
|
|
122
122
|
// expect(head.size == 3);
|
|
123
123
|
index.view("tmp.usearch");
|
|
124
124
|
matched_count = index.search(vector_first, 5, args...).dump_to(matched_keys, matched_distances);
|
|
@@ -140,7 +140,7 @@ void test_cosine(index_at& index, std::vector<std::vector<scalar_at>> const& vec
|
|
|
140
140
|
|
|
141
141
|
// Check metadata
|
|
142
142
|
if constexpr (punned_ak) {
|
|
143
|
-
index_dense_metadata_result_t meta =
|
|
143
|
+
index_dense_metadata_result_t meta = index_dense_metadata_from_path("tmp.usearch");
|
|
144
144
|
expect(bool(meta));
|
|
145
145
|
}
|
|
146
146
|
}
|