usearch 2.3.2 → 2.4.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/prerelease.yml +3 -3
- package/.github/workflows/release.yml +96 -5
- package/CITATION.cff +1 -1
- package/CMakeLists.txt +2 -2
- package/Cargo.toml +1 -1
- package/README.md +2 -2
- package/c/CMakeLists.txt +1 -1
- package/c/README.md +1 -1
- package/conanfile.py +14 -7
- package/cpp/test.cpp +7 -0
- package/csharp/nuget/nuget-package.props +1 -1
- package/csharp/src/Cloud.Unum.USearch.Tests/USearchIndexTests.cs +1013 -0
- package/docs/format.md +40 -17
- package/include/usearch/index.hpp +2 -2
- package/include/usearch/index_dense.hpp +47 -27
- package/include/usearch/index_plugins.hpp +516 -7
- package/package.json +2 -2
- package/python/lib.cpp +8 -5
- package/python/scripts/cluster.ipynb +0 -7
- package/python/usearch/index.py +25 -13
- package/rust/lib.rs +24 -2
- package/wasmer.toml +1 -1
- package/csharp/src/Cloud.Unum.USearch.Tests/InitTests.cs +0 -306
package/python/usearch/index.py
CHANGED
|
@@ -476,6 +476,7 @@ class Index:
|
|
|
476
476
|
multi: bool = False,
|
|
477
477
|
path: Optional[os.PathLike] = None,
|
|
478
478
|
view: bool = False,
|
|
479
|
+
enable_key_lookups: bool = True,
|
|
479
480
|
) -> None:
|
|
480
481
|
"""Construct the index and compiles the functions, if requested (expensive).
|
|
481
482
|
|
|
@@ -565,6 +566,7 @@ class Index:
|
|
|
565
566
|
expansion_add=expansion_add,
|
|
566
567
|
expansion_search=expansion_search,
|
|
567
568
|
multi=multi,
|
|
569
|
+
enable_key_lookups=enable_key_lookups,
|
|
568
570
|
metric_kind=self._metric_kind,
|
|
569
571
|
metric_pointer=self._metric_pointer,
|
|
570
572
|
metric_signature=self._metric_signature,
|
|
@@ -986,6 +988,8 @@ class Index:
|
|
|
986
988
|
|
|
987
989
|
def reset(self):
|
|
988
990
|
"""Erases all members from index, closing files, and returning RAM to OS."""
|
|
991
|
+
if not hasattr(self, "_compiled"):
|
|
992
|
+
return
|
|
989
993
|
self._compiled.reset()
|
|
990
994
|
|
|
991
995
|
def __del__(self):
|
|
@@ -1175,23 +1179,28 @@ class Index:
|
|
|
1175
1179
|
|
|
1176
1180
|
@property
|
|
1177
1181
|
def specs(self) -> Dict[str, Union[str, int, bool]]:
|
|
1182
|
+
if not hasattr(self, "_compiled"):
|
|
1183
|
+
return "usearch.Index(failed)"
|
|
1178
1184
|
return {
|
|
1179
|
-
"
|
|
1180
|
-
"
|
|
1181
|
-
"
|
|
1182
|
-
"
|
|
1183
|
-
"
|
|
1184
|
-
"
|
|
1185
|
-
"
|
|
1186
|
-
"
|
|
1187
|
-
"
|
|
1188
|
-
"
|
|
1189
|
-
"
|
|
1190
|
-
"
|
|
1185
|
+
"type": "usearch.Index",
|
|
1186
|
+
"ndim": self.ndim,
|
|
1187
|
+
"connectivity": self.connectivity,
|
|
1188
|
+
"expansion_add": self.expansion_add,
|
|
1189
|
+
"expansion_search": self.expansion_search,
|
|
1190
|
+
"size": self.size,
|
|
1191
|
+
"jit": self.jit,
|
|
1192
|
+
"hardware_acceleration": self.hardware_acceleration,
|
|
1193
|
+
"dtype": self.dtype,
|
|
1194
|
+
"path": self.path,
|
|
1195
|
+
"compiled_with_openmp": USES_OPENMP,
|
|
1196
|
+
"compiled_with_simsimd": USES_SIMSIMD,
|
|
1197
|
+
"compiled_with_native_f16": USES_NATIVE_F16,
|
|
1191
1198
|
}
|
|
1192
1199
|
|
|
1193
1200
|
def __repr__(self) -> str:
|
|
1194
|
-
|
|
1201
|
+
if not hasattr(self, "_compiled"):
|
|
1202
|
+
return "usearch.Index(failed)"
|
|
1203
|
+
f = "usearch.Index({} x {}, {}, connectivity: {}, expansion: {} & {}, {:,} vectors in {} levels, {} hardware acceleration)"
|
|
1195
1204
|
return f.format(
|
|
1196
1205
|
self.dtype,
|
|
1197
1206
|
self.ndim,
|
|
@@ -1201,9 +1210,12 @@ class Index:
|
|
|
1201
1210
|
self.expansion_search,
|
|
1202
1211
|
len(self),
|
|
1203
1212
|
self.nlevels,
|
|
1213
|
+
self.hardware_acceleration,
|
|
1204
1214
|
)
|
|
1205
1215
|
|
|
1206
1216
|
def _repr_pretty_(self, printer, cycle) -> str:
|
|
1217
|
+
if not hasattr(self, "_compiled"):
|
|
1218
|
+
return "usearch.Index(failed)"
|
|
1207
1219
|
level_stats = [
|
|
1208
1220
|
f"--- {i}. {self.level_stats(i).nodes:,} nodes" for i in range(self.nlevels)
|
|
1209
1221
|
]
|
package/rust/lib.rs
CHANGED
|
@@ -81,7 +81,18 @@ pub mod ffi {
|
|
|
81
81
|
///
|
|
82
82
|
/// * `key` - The key associated with the vector.
|
|
83
83
|
/// * `vector` - A slice containing the vector data.
|
|
84
|
-
|
|
84
|
+
fn add<T>(self: &Index, key: u64, vector: &[T]) -> Result<()> {
|
|
85
|
+
// Use type-based dispatch
|
|
86
|
+
if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i8>() {
|
|
87
|
+
add_i8(key, unsafe { std::mem::transmute::<&[T], &[i8]>(vector) })
|
|
88
|
+
} else if std::any::TypeId::of::<T>() == std::any::TypeId::of::<f32>() {
|
|
89
|
+
add_f32(key, unsafe { std::mem::transmute::<&[T], &[f32]>(vector) })
|
|
90
|
+
} else if std::any::TypeId::of::<T>() == std::any::TypeId::of::<f64>() {
|
|
91
|
+
add_f64(key, unsafe { std::mem::transmute::<&[T], &[f64]>(vector) })
|
|
92
|
+
} else {
|
|
93
|
+
Err(Box::new("Unsupported type"))
|
|
94
|
+
}
|
|
95
|
+
}
|
|
85
96
|
|
|
86
97
|
pub fn add_i8(self: &Index, key: u64, vector: &[i8]) -> Result<()>;
|
|
87
98
|
pub fn add_f16(self: &Index, key: u64, vector: &[u16]) -> Result<()>;
|
|
@@ -98,7 +109,18 @@ pub mod ffi {
|
|
|
98
109
|
/// # Returns
|
|
99
110
|
///
|
|
100
111
|
/// A `Result` containing the matches found.
|
|
101
|
-
pub fn search(self: &Index, query: &[
|
|
112
|
+
pub fn search<T>(self: &Index, query: &[T], count: usize) -> Result<Matches> {
|
|
113
|
+
// Use type-based dispatch
|
|
114
|
+
if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i8>() {
|
|
115
|
+
search_i8(unsafe { std::mem::transmute::<&[T], &[i8]>(query) }, count)
|
|
116
|
+
} else if std::any::TypeId::of::<T>() == std::any::TypeId::of::<f32>() {
|
|
117
|
+
search_f32(unsafe { std::mem::transmute::<&[T], &[f32]>(query) }, count)
|
|
118
|
+
} else if std::any::TypeId::of::<T>() == std::any::TypeId::of::<f64>() {
|
|
119
|
+
search_f64(unsafe { std::mem::transmute::<&[T], &[f64]>(query) }, count)
|
|
120
|
+
} else {
|
|
121
|
+
Err(Box::new("Unsupported type"))
|
|
122
|
+
}
|
|
123
|
+
}
|
|
102
124
|
|
|
103
125
|
pub fn search_i8(self: &Index, query: &[i8], count: usize) -> Result<Matches>;
|
|
104
126
|
pub fn search_f16(self: &Index, query: &[u16], count: usize) -> Result<Matches>;
|
package/wasmer.toml
CHANGED
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
using Cloud.Unum.USearch;
|
|
2
|
-
|
|
3
|
-
namespace Cloud.Unum.USearch.Tests;
|
|
4
|
-
|
|
5
|
-
public class InitTests
|
|
6
|
-
{
|
|
7
|
-
// Epsilon for real values comparisons
|
|
8
|
-
private const float Epsilon = 0.000001f;
|
|
9
|
-
|
|
10
|
-
[Fact]
|
|
11
|
-
public void InitializedAndDisposedSucceeds()
|
|
12
|
-
{
|
|
13
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 3))
|
|
14
|
-
{
|
|
15
|
-
Assert.NotNull(index);
|
|
16
|
-
Assert.Equal((uint)3, index.Dimensions());
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
[Fact]
|
|
21
|
-
public void AddDoubleVectorSucceeds()
|
|
22
|
-
{
|
|
23
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float64, 3))
|
|
24
|
-
{
|
|
25
|
-
index.Add(1, new double[] { 1.0, 2.0, 3.0 });
|
|
26
|
-
Assert.True(index.Contains(1));
|
|
27
|
-
Assert.False(index.Contains(2));
|
|
28
|
-
Assert.Equal((uint)1, index.Size());
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
[Fact]
|
|
33
|
-
public void AddDoubleVectorsUnderSameKeySucceeds()
|
|
34
|
-
{
|
|
35
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float64, 3, multi: true))
|
|
36
|
-
{
|
|
37
|
-
index.Add(1, new double[] { 1.0, 2.0, 3.0 });
|
|
38
|
-
index.Add(2, new double[] { 1.0, 2.0, 3.0 });
|
|
39
|
-
index.Add(3, new double[] { 1.0, 2.0, 3.0 });
|
|
40
|
-
index.Add(1, new double[] { 1.0, 2.0, 3.0 });
|
|
41
|
-
index.Add(2, new double[] { 1.0, 2.0, 3.0 });
|
|
42
|
-
Assert.True(index.Contains(1));
|
|
43
|
-
Assert.True(index.Contains(2));
|
|
44
|
-
Assert.True(index.Contains(3));
|
|
45
|
-
Assert.Equal((uint)5, index.Size());
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
[Fact]
|
|
50
|
-
public void ItCanGetMultipleFloatVectorsForSingleKey()
|
|
51
|
-
{
|
|
52
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 3, multi: true))
|
|
53
|
-
{
|
|
54
|
-
var inputVectors = new float[][] {
|
|
55
|
-
new float[] { 1.0f, 6.0f, 11.0f },
|
|
56
|
-
new float[] { 2.0f, 7.0f, 12.0f },
|
|
57
|
-
new float[] { 3.0f, 8.0f, 13.0f },
|
|
58
|
-
new float[] { 5.0f, 10.0f, 15.0f }
|
|
59
|
-
};
|
|
60
|
-
index.Add(
|
|
61
|
-
new ulong[] { 2, 2, 2, 2 },
|
|
62
|
-
inputVectors
|
|
63
|
-
);
|
|
64
|
-
Assert.True(index.Contains(2));
|
|
65
|
-
Assert.Equal((uint)4, index.Size());
|
|
66
|
-
Assert.Equal(4, index.Count(2));
|
|
67
|
-
|
|
68
|
-
int foundVectorsCount = index.Get(2, 3, out float[][] retrievedVectors);
|
|
69
|
-
Assert.Equal(3, foundVectorsCount);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
[Fact]
|
|
74
|
-
public void ItCanGetMultipleDoubleVectorsForSingleKey()
|
|
75
|
-
{
|
|
76
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float64, 3, multi: true))
|
|
77
|
-
{
|
|
78
|
-
var inputVectors = new double[][] {
|
|
79
|
-
new double[] { 1.0, 6.0, 11.0 },
|
|
80
|
-
new double[] { 2.0, 7.0, 12.0 },
|
|
81
|
-
new double[] { 3.0, 8.0, 13.0 },
|
|
82
|
-
new double[] { 5.0, 10.0, 15.0 }
|
|
83
|
-
};
|
|
84
|
-
index.Add(
|
|
85
|
-
new ulong[] { 2, 2, 2, 2 },
|
|
86
|
-
inputVectors
|
|
87
|
-
);
|
|
88
|
-
Assert.True(index.Contains(2));
|
|
89
|
-
Assert.Equal((uint)4, index.Size());
|
|
90
|
-
Assert.Equal(4, index.Count(2));
|
|
91
|
-
|
|
92
|
-
int foundVectorsCount = index.Get(2, 3, out double[][] retrievedVectors);
|
|
93
|
-
Assert.Equal(3, foundVectorsCount);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
[Fact]
|
|
98
|
-
public void AddFloatVectorSucceeds()
|
|
99
|
-
{
|
|
100
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 3))
|
|
101
|
-
{
|
|
102
|
-
index.Add(1, new float[] { 1.0f, 2.0f, 3.0f });
|
|
103
|
-
Assert.Equal((uint)1, index.Size());
|
|
104
|
-
Assert.True(index.Contains(1));
|
|
105
|
-
Assert.False(index.Contains(2));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
[Fact]
|
|
110
|
-
public void AddFloatVectorsUnderSameKeySucceeds()
|
|
111
|
-
{
|
|
112
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 3, multi: true))
|
|
113
|
-
{
|
|
114
|
-
index.Add(1, new float[] { 1.0f, 2.0f, 3.0f });
|
|
115
|
-
index.Add(2, new float[] { 1.0f, 2.0f, 3.0f });
|
|
116
|
-
index.Add(3, new float[] { 1.0f, 2.0f, 3.0f });
|
|
117
|
-
index.Add(1, new float[] { 1.0f, 2.0f, 3.0f });
|
|
118
|
-
index.Add(2, new float[] { 1.0f, 2.0f, 3.0f });
|
|
119
|
-
Assert.True(index.Contains(1));
|
|
120
|
-
Assert.True(index.Contains(2));
|
|
121
|
-
Assert.True(index.Contains(3));
|
|
122
|
-
Assert.Equal((uint)5, index.Size());
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
[Fact]
|
|
127
|
-
public void AddGetFloatVectorSucceeds()
|
|
128
|
-
{
|
|
129
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 3))
|
|
130
|
-
{
|
|
131
|
-
var inputVector = new float[] { 1.0f, 2.0f, 3.0f };
|
|
132
|
-
index.Add(1, inputVector);
|
|
133
|
-
Assert.Equal((uint)1, index.Size());
|
|
134
|
-
Assert.True(index.Contains(1));
|
|
135
|
-
Assert.False(index.Contains(2));
|
|
136
|
-
Assert.True(index.Get(1, out float[] retrievedVector) == 1);
|
|
137
|
-
Assert.NotNull(retrievedVector);
|
|
138
|
-
bool areEqual = inputVector
|
|
139
|
-
.Zip(retrievedVector, (a, b) => (a, b))
|
|
140
|
-
.All(pair => Math.Abs(pair.a - pair.b) <= Epsilon);
|
|
141
|
-
|
|
142
|
-
Assert.True(areEqual);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
[Fact]
|
|
147
|
-
public void AddGetDoubleVectorSucceeds()
|
|
148
|
-
{
|
|
149
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 3))
|
|
150
|
-
{
|
|
151
|
-
var inputVector = new double[] { 1.0, 2.0, 3.33 };
|
|
152
|
-
index.Add(1, inputVector);
|
|
153
|
-
Assert.Equal((uint)1, index.Size());
|
|
154
|
-
Assert.True(index.Contains(1));
|
|
155
|
-
Assert.False(index.Contains(2));
|
|
156
|
-
Assert.True(index.Get(1, out double[] retrievedVector) == 1);
|
|
157
|
-
Assert.NotNull(retrievedVector);
|
|
158
|
-
bool areEqual = inputVector
|
|
159
|
-
.Zip(retrievedVector, (a, b) => (a, b))
|
|
160
|
-
.All(pair => Math.Abs(pair.a - pair.b) <= Epsilon);
|
|
161
|
-
|
|
162
|
-
Assert.True(areEqual);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
[Fact]
|
|
167
|
-
public void ItThrowsException_AddAddWithSameKeyAndGetVector()
|
|
168
|
-
{
|
|
169
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 3))
|
|
170
|
-
{
|
|
171
|
-
ulong key = 1;
|
|
172
|
-
float[] vector1 = { 1.0f, 2.0f, 33.3f };
|
|
173
|
-
index.Add(key, vector1);
|
|
174
|
-
float[] vector2 = { 3.0f, 4.0f, 34.2f };
|
|
175
|
-
Assert.Throws<USearchException>(() => index.Add(key, vector2));
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
[Fact]
|
|
180
|
-
public void TestAddRemoveAddAndGet()
|
|
181
|
-
{
|
|
182
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 2))
|
|
183
|
-
{
|
|
184
|
-
ulong key = 1;
|
|
185
|
-
float[] vector = { 1.0f, 2.0f };
|
|
186
|
-
|
|
187
|
-
index.Add(key, vector);
|
|
188
|
-
Assert.True(index.Contains(key));
|
|
189
|
-
index.Remove(key);
|
|
190
|
-
Assert.False(index.Contains(key));
|
|
191
|
-
index.Add(key, vector);
|
|
192
|
-
Assert.True(index.Contains(key));
|
|
193
|
-
Assert.True(index.Get(key, out float[] retrievedVector) == 1);
|
|
194
|
-
Assert.Equal(vector, retrievedVector);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
[Fact]
|
|
199
|
-
public void TestAddRemoveAddWithSameKeyVectorAndGet()
|
|
200
|
-
{
|
|
201
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 2))
|
|
202
|
-
{
|
|
203
|
-
ulong key = 1;
|
|
204
|
-
float[] vector = { 1.0f, 2.0f };
|
|
205
|
-
|
|
206
|
-
index.Add(key, vector);
|
|
207
|
-
Assert.True(index.Contains(key));
|
|
208
|
-
index.Remove(key);
|
|
209
|
-
Assert.False(index.Contains(key));
|
|
210
|
-
index.Add(key, vector);
|
|
211
|
-
Assert.True(index.Contains(key));
|
|
212
|
-
Assert.True(index.Get(key, out float[] retrievedVector) == 1);
|
|
213
|
-
Assert.Equal(vector, retrievedVector);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
[Fact]
|
|
218
|
-
public void TestGetKeyThatNotExist()
|
|
219
|
-
{
|
|
220
|
-
using (var index = new USearchIndex(MetricKind.Cos, ScalarKind.Float32, 2))
|
|
221
|
-
{
|
|
222
|
-
Assert.True(index.Get(1, out float[] retrievedVector) == 0);
|
|
223
|
-
Assert.False(index.Contains(1));
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
[Fact]
|
|
228
|
-
public void Search_FindsExpectedResults()
|
|
229
|
-
{
|
|
230
|
-
using (var index = new USearchIndex(MetricKind.L2sq, ScalarKind.Float32, 2))
|
|
231
|
-
{
|
|
232
|
-
index.Add(
|
|
233
|
-
Enumerable.Range(1, 5).Select(i => (ulong)i).ToArray(),
|
|
234
|
-
new float[][]
|
|
235
|
-
{
|
|
236
|
-
new float[] { -0.5f, -0.6f },
|
|
237
|
-
new float[] { -0.1f, -0.1f },
|
|
238
|
-
new float[] { 0.2f, 0.2f },
|
|
239
|
-
new float[] { 0.7f, 0.8f },
|
|
240
|
-
new float[] { 0.9f, 1.0f }
|
|
241
|
-
}
|
|
242
|
-
);
|
|
243
|
-
var queryVector = new float[] { 0.0f, 0.0f };
|
|
244
|
-
|
|
245
|
-
var matches = index.Search(queryVector, 2, out ulong[] keys, out float[] distances);
|
|
246
|
-
|
|
247
|
-
Assert.Equal(2, matches);
|
|
248
|
-
Assert.Contains(2UL, keys);
|
|
249
|
-
Assert.Contains(3UL, keys);
|
|
250
|
-
Assert.Equal(0.02, distances[0], Epsilon);
|
|
251
|
-
Assert.Equal(0.08, distances[1], Epsilon);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
[Fact]
|
|
256
|
-
public void Search_AfterRemovingKey_FindsExpectedResults()
|
|
257
|
-
{
|
|
258
|
-
using (var index = new USearchIndex(MetricKind.L2sq, ScalarKind.Float32, 2))
|
|
259
|
-
{
|
|
260
|
-
index.Add(1, new float[] { 0.1f, 0.2f });
|
|
261
|
-
index.Add(2, new float[] { 0.2f, 0.3f });
|
|
262
|
-
index.Add(3, new float[] { 0.3f, 0.4f });
|
|
263
|
-
index.Remove(2);
|
|
264
|
-
var queryVector = new float[] { 0.2f, 0.3f };
|
|
265
|
-
|
|
266
|
-
var matches = index.Search(queryVector, 2, out ulong[] keys, out float[] distances);
|
|
267
|
-
|
|
268
|
-
Assert.Equal(2, matches);
|
|
269
|
-
Assert.Contains(1UL, keys);
|
|
270
|
-
Assert.Contains(3UL, keys);
|
|
271
|
-
Assert.DoesNotContain(2UL, keys);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
[Fact]
|
|
276
|
-
public void Search_WithVectorsLessThanResultsLimit()
|
|
277
|
-
{
|
|
278
|
-
using (var index = new USearchIndex(MetricKind.L2sq, ScalarKind.Float32, 2))
|
|
279
|
-
{
|
|
280
|
-
index.Add(1, new float[] { 0.9f, 0.9f });
|
|
281
|
-
index.Add(2, new float[] { 0.8f, 0.8f });
|
|
282
|
-
var queryVector = new float[] { 0.1f, 0.2f };
|
|
283
|
-
|
|
284
|
-
var matches = index.Search(queryVector, 10, out ulong[] keys, out float[] distances);
|
|
285
|
-
|
|
286
|
-
Assert.Equal(2, matches);
|
|
287
|
-
Assert.Contains(1UL, keys);
|
|
288
|
-
Assert.Contains(2UL, keys);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
[Fact]
|
|
293
|
-
public void ItCanRenameKey()
|
|
294
|
-
{
|
|
295
|
-
using (var index = new USearchIndex(MetricKind.L2sq, ScalarKind.Float32, 2))
|
|
296
|
-
{
|
|
297
|
-
index.Add(1, new float[] { 0.9f, 0.9f });
|
|
298
|
-
index.Add(2, new float[] { 0.8f, 0.8f });
|
|
299
|
-
index.Rename(1, 3);
|
|
300
|
-
Assert.False(index.Contains(1));
|
|
301
|
-
Assert.True(index.Contains(2));
|
|
302
|
-
Assert.True(index.Contains(3));
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
}
|