annoy-rb 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/ext/annoy/annoyext.cpp +10 -10
- data/ext/annoy/annoyext.hpp +113 -44
- data/lib/annoy/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25b6e3d18705801e5458c656517e57d5bb42fb42846bc4cde36107787bc0f506
|
4
|
+
data.tar.gz: caca0acd3a163bc4a0e09dfe7a30dfcd975d3b123f7bce76f44263545271d8d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c8a5dca9dacb2004e17ac14c2e362424b40a1532ee785c17ba85e01b02a5c40e2defd352362b97e6098b3a69d7f5e62011dba62d7ddf47b4b81fa6cd4e482f9
|
7
|
+
data.tar.gz: e50f8d449dc142bb80c4caeab0c4450a80b1f3f0f0979d6a460f9115bbbc80fa6d934d006463ce8da04a10a17929ed125ffd985aadc8a50c5d6979dbe1be3026
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 0.7.2
|
2
|
+
|
3
|
+
- Refactor native extension codes to set rb_data_type_t.wrap_struct_name for each metric and dtype.
|
4
|
+
|
1
5
|
## 0.7.1
|
2
6
|
|
3
7
|
- Fix bug that item elements are converted to unsingned integers when dtype is set to float32 ([#3](https://github.com/yoshoku/annoy-rb/issues/3)).
|
data/ext/annoy/annoyext.cpp
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* Annoy.rb is a Ruby binding for the Annoy (Approximate Nearest Neighbors Oh Yeah).
|
3
3
|
*
|
4
|
-
* Copyright (c) 2020-
|
4
|
+
* Copyright (c) 2020-2023 Atsushi Tatsuma
|
5
5
|
*
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
* you may not use this file except in compliance with the License.
|
@@ -20,14 +20,14 @@
|
|
20
20
|
|
21
21
|
extern "C" void Init_annoyext(void) {
|
22
22
|
VALUE rb_mAnnoy = rb_define_module("Annoy");
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
RbAnnoyIndexAngular::define_class(rb_mAnnoy, "AnnoyIndexAngular");
|
24
|
+
RbAnnoyIndexDotProduct::define_class(rb_mAnnoy, "AnnoyIndexDotProduct");
|
25
|
+
RbAnnoyIndexHamming::define_class(rb_mAnnoy, "AnnoyIndexHamming");
|
26
|
+
RbAnnoyIndexEuclidean::define_class(rb_mAnnoy, "AnnoyIndexEuclidean");
|
27
|
+
RbAnnoyIndexManhattan::define_class(rb_mAnnoy, "AnnoyIndexManhattan");
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
RbAnnoyIndexAngularFloat32::define_class(rb_mAnnoy, "AnnoyIndexAngularFloat32");
|
30
|
+
RbAnnoyIndexDotProductFloat32::define_class(rb_mAnnoy, "AnnoyIndexDotProductFloat32");
|
31
|
+
RbAnnoyIndexEuclideanFloat32::define_class(rb_mAnnoy, "AnnoyIndexEuclideanFloat32");
|
32
|
+
RbAnnoyIndexManhattanFloat32::define_class(rb_mAnnoy, "AnnoyIndexManhattanFloat32");
|
33
33
|
}
|
data/ext/annoy/annoyext.hpp
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* Annoy.rb is a Ruby binding for the Annoy (Approximate Nearest Neighbors Oh Yeah).
|
3
3
|
*
|
4
|
-
* Copyright (c) 2020-
|
4
|
+
* Copyright (c) 2020-2023 Atsushi Tatsuma
|
5
5
|
*
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
* you may not use this file except in compliance with the License.
|
@@ -35,31 +35,36 @@ typedef AnnoyIndexSingleThreadedBuildPolicy AnnoyIndexThreadedBuildPolicy;
|
|
35
35
|
#endif
|
36
36
|
|
37
37
|
// clang-format off
|
38
|
-
template<typename
|
39
|
-
template<typename
|
40
|
-
template<typename
|
41
|
-
template<typename
|
42
|
-
template<typename
|
38
|
+
template<typename El> using AnnoyIndexAngular = AnnoyIndex<int32_t, El, Angular, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
|
39
|
+
template<typename El> using AnnoyIndexDotProduct = AnnoyIndex<int32_t, El, DotProduct, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
|
40
|
+
template<typename El> using AnnoyIndexHamming = AnnoyIndex<int32_t, El, Hamming, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
|
41
|
+
template<typename El> using AnnoyIndexEuclidean = AnnoyIndex<int32_t, El, Euclidean, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
|
42
|
+
template<typename El> using AnnoyIndexManhattan = AnnoyIndex<int32_t, El, Manhattan, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
|
43
43
|
// clang-format on
|
44
44
|
|
45
|
-
template <class
|
45
|
+
template <class Idx, typename El, class Impl>
|
46
|
+
class RbAnnoyIndex {
|
46
47
|
public:
|
48
|
+
// static const rb_data_type_t annoy_index_type;
|
49
|
+
|
47
50
|
static VALUE annoy_index_alloc(VALUE self) {
|
48
|
-
|
49
|
-
new (ptr)
|
50
|
-
return TypedData_Wrap_Struct(self, &annoy_index_type, ptr);
|
51
|
+
Idx* ptr = (Idx*)ruby_xmalloc(sizeof(Idx));
|
52
|
+
new (ptr) Idx();
|
53
|
+
return TypedData_Wrap_Struct(self, &Impl::annoy_index_type, ptr);
|
51
54
|
};
|
52
55
|
|
53
56
|
static void annoy_index_free(void* ptr) {
|
54
|
-
((
|
57
|
+
((Idx*)ptr)->~AnnoyIndex();
|
55
58
|
ruby_xfree(ptr);
|
56
59
|
};
|
57
60
|
|
58
|
-
static size_t annoy_index_size(const void* ptr) {
|
61
|
+
static size_t annoy_index_size(const void* ptr) {
|
62
|
+
return sizeof(*((Idx*)ptr));
|
63
|
+
};
|
59
64
|
|
60
|
-
static
|
61
|
-
|
62
|
-
TypedData_Get_Struct(self,
|
65
|
+
static Idx* get_annoy_index(VALUE self) {
|
66
|
+
Idx* ptr;
|
67
|
+
TypedData_Get_Struct(self, Idx, &Impl::annoy_index_type, ptr);
|
63
68
|
return ptr;
|
64
69
|
};
|
65
70
|
|
@@ -86,12 +91,10 @@ public:
|
|
86
91
|
};
|
87
92
|
|
88
93
|
private:
|
89
|
-
static const rb_data_type_t annoy_index_type;
|
90
|
-
|
91
94
|
static VALUE _annoy_index_init(VALUE self, VALUE _n_dims) {
|
92
95
|
const int n_dims = NUM2INT(_n_dims);
|
93
|
-
|
94
|
-
new (ptr)
|
96
|
+
Idx* ptr = get_annoy_index(self);
|
97
|
+
new (ptr) Idx(n_dims);
|
95
98
|
return Qnil;
|
96
99
|
};
|
97
100
|
|
@@ -109,9 +112,9 @@ private:
|
|
109
112
|
return Qfalse;
|
110
113
|
}
|
111
114
|
|
112
|
-
|
115
|
+
El* vec = (El*)ruby_xmalloc(n_dims * sizeof(El));
|
113
116
|
for (int i = 0; i < n_dims; i++) {
|
114
|
-
vec[i] = (
|
117
|
+
vec[i] = (El)(typeid(El) == typeid(uint64_t) ? NUM2UINT(rb_ary_entry(arr, i)) : NUM2DBL(rb_ary_entry(arr, i)));
|
115
118
|
}
|
116
119
|
|
117
120
|
char* error;
|
@@ -180,7 +183,7 @@ private:
|
|
180
183
|
const int search_k = NUM2INT(_search_k);
|
181
184
|
const bool include_distances = _include_distances == Qtrue ? true : false;
|
182
185
|
std::vector<int32_t> neighbors;
|
183
|
-
std::vector<
|
186
|
+
std::vector<El> distances;
|
184
187
|
|
185
188
|
get_annoy_index(self)->get_nns_by_item(idx, n_neighbors, search_k, &neighbors, include_distances ? &distances : NULL);
|
186
189
|
|
@@ -195,7 +198,7 @@ private:
|
|
195
198
|
const int sz_distances = distances.size();
|
196
199
|
VALUE distances_arr = rb_ary_new2(sz_distances);
|
197
200
|
for (int i = 0; i < sz_distances; i++) {
|
198
|
-
rb_ary_store(distances_arr, i, typeid(
|
201
|
+
rb_ary_store(distances_arr, i, typeid(El) == typeid(uint64_t) ? UINT2NUM(distances[i]) : DBL2NUM(distances[i]));
|
199
202
|
}
|
200
203
|
VALUE res = rb_ary_new2(2);
|
201
204
|
rb_ary_store(res, 0, neighbors_arr);
|
@@ -220,16 +223,16 @@ private:
|
|
220
223
|
return Qfalse;
|
221
224
|
}
|
222
225
|
|
223
|
-
|
226
|
+
El* vec = (El*)ruby_xmalloc(n_dims * sizeof(El));
|
224
227
|
for (int i = 0; i < n_dims; i++) {
|
225
|
-
vec[i] = (
|
228
|
+
vec[i] = (El)(typeid(El) == typeid(uint64_t) ? NUM2UINT(rb_ary_entry(_vec, i)) : NUM2DBL(rb_ary_entry(_vec, i)));
|
226
229
|
}
|
227
230
|
|
228
231
|
const int n_neighbors = NUM2INT(_n_neighbors);
|
229
232
|
const int search_k = NUM2INT(_search_k);
|
230
233
|
const bool include_distances = _include_distances == Qtrue ? true : false;
|
231
234
|
std::vector<int32_t> neighbors;
|
232
|
-
std::vector<
|
235
|
+
std::vector<El> distances;
|
233
236
|
|
234
237
|
get_annoy_index(self)->get_nns_by_vector(vec, n_neighbors, search_k, &neighbors, include_distances ? &distances : NULL);
|
235
238
|
|
@@ -246,7 +249,7 @@ private:
|
|
246
249
|
const int sz_distances = distances.size();
|
247
250
|
VALUE distances_arr = rb_ary_new2(sz_distances);
|
248
251
|
for (int i = 0; i < sz_distances; i++) {
|
249
|
-
rb_ary_store(distances_arr, i, typeid(
|
252
|
+
rb_ary_store(distances_arr, i, typeid(El) == typeid(uint64_t) ? UINT2NUM(distances[i]) : DBL2NUM(distances[i]));
|
250
253
|
}
|
251
254
|
VALUE res = rb_ary_new2(2);
|
252
255
|
rb_ary_store(res, 0, neighbors_arr);
|
@@ -260,13 +263,13 @@ private:
|
|
260
263
|
static VALUE _annoy_index_get_item(VALUE self, VALUE _idx) {
|
261
264
|
const int32_t idx = (int32_t)NUM2INT(_idx);
|
262
265
|
const int n_dims = get_annoy_index(self)->get_f();
|
263
|
-
|
266
|
+
El* vec = (El*)ruby_xmalloc(n_dims * sizeof(El));
|
264
267
|
VALUE arr = rb_ary_new2(n_dims);
|
265
268
|
|
266
269
|
get_annoy_index(self)->get_item(idx, vec);
|
267
270
|
|
268
271
|
for (int i = 0; i < n_dims; i++) {
|
269
|
-
rb_ary_store(arr, i, typeid(
|
272
|
+
rb_ary_store(arr, i, typeid(El) == typeid(uint64_t) ? UINT2NUM(vec[i]) : DBL2NUM(vec[i]));
|
270
273
|
}
|
271
274
|
|
272
275
|
ruby_xfree(vec);
|
@@ -276,8 +279,8 @@ private:
|
|
276
279
|
static VALUE _annoy_index_get_distance(VALUE self, VALUE _i, VALUE _j) {
|
277
280
|
const int32_t i = (int32_t)NUM2INT(_i);
|
278
281
|
const int32_t j = (int32_t)NUM2INT(_j);
|
279
|
-
const
|
280
|
-
return typeid(
|
282
|
+
const El dist = get_annoy_index(self)->get_distance(i, j);
|
283
|
+
return typeid(El) == typeid(uint64_t) ? UINT2NUM(dist) : DBL2NUM(dist);
|
281
284
|
};
|
282
285
|
|
283
286
|
static VALUE _annoy_index_get_n_items(VALUE self) {
|
@@ -321,19 +324,85 @@ private:
|
|
321
324
|
};
|
322
325
|
};
|
323
326
|
|
324
|
-
|
325
|
-
|
326
|
-
const rb_data_type_t
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
327
|
+
class RbAnnoyIndexAngular : public RbAnnoyIndex<AnnoyIndexAngular<double>, double, RbAnnoyIndexAngular> {
|
328
|
+
public:
|
329
|
+
static const rb_data_type_t annoy_index_type;
|
330
|
+
};
|
331
|
+
|
332
|
+
const rb_data_type_t RbAnnoyIndexAngular::annoy_index_type = {
|
333
|
+
"RbAnnoyIndexAngular", { NULL, RbAnnoyIndexAngular::annoy_index_free, RbAnnoyIndexAngular::annoy_index_size }, NULL, NULL, 0
|
334
|
+
};
|
335
|
+
|
336
|
+
class RbAnnoyIndexDotProduct : public RbAnnoyIndex<AnnoyIndexDotProduct<double>, double, RbAnnoyIndexDotProduct> {
|
337
|
+
public:
|
338
|
+
static const rb_data_type_t annoy_index_type;
|
339
|
+
};
|
340
|
+
|
341
|
+
const rb_data_type_t RbAnnoyIndexDotProduct::annoy_index_type = {
|
342
|
+
"RbAnnoyIndexDotProduct", { NULL, RbAnnoyIndexDotProduct::annoy_index_free, RbAnnoyIndexDotProduct::annoy_index_size }, NULL, NULL, 0
|
343
|
+
};
|
344
|
+
|
345
|
+
class RbAnnoyIndexHamming : public RbAnnoyIndex<AnnoyIndexHamming<uint64_t>, uint64_t, RbAnnoyIndexHamming> {
|
346
|
+
public:
|
347
|
+
static const rb_data_type_t annoy_index_type;
|
348
|
+
};
|
349
|
+
|
350
|
+
const rb_data_type_t RbAnnoyIndexHamming::annoy_index_type = {
|
351
|
+
"RbAnnoyIndexHamming", { NULL, RbAnnoyIndexHamming::annoy_index_free, RbAnnoyIndexHamming::annoy_index_size }, NULL, NULL, 0
|
352
|
+
};
|
353
|
+
|
354
|
+
class RbAnnoyIndexEuclidean : public RbAnnoyIndex<AnnoyIndexEuclidean<double>, double, RbAnnoyIndexEuclidean> {
|
355
|
+
public:
|
356
|
+
static const rb_data_type_t annoy_index_type;
|
357
|
+
};
|
358
|
+
|
359
|
+
const rb_data_type_t RbAnnoyIndexEuclidean::annoy_index_type = {
|
360
|
+
"RbAnnoyIndexEuclidean", { NULL, RbAnnoyIndexEuclidean::annoy_index_free, RbAnnoyIndexEuclidean::annoy_index_size }, NULL, NULL, 0
|
361
|
+
};
|
362
|
+
|
363
|
+
class RbAnnoyIndexManhattan : public RbAnnoyIndex<AnnoyIndexManhattan<double>, double, RbAnnoyIndexManhattan> {
|
364
|
+
public:
|
365
|
+
static const rb_data_type_t annoy_index_type;
|
366
|
+
};
|
367
|
+
|
368
|
+
const rb_data_type_t RbAnnoyIndexManhattan::annoy_index_type = {
|
369
|
+
"RbAnnoyIndexManhattan", { NULL, RbAnnoyIndexManhattan::annoy_index_free, RbAnnoyIndexManhattan::annoy_index_size }, NULL, NULL, 0
|
370
|
+
};
|
371
|
+
|
372
|
+
class RbAnnoyIndexAngularFloat32 : public RbAnnoyIndex<AnnoyIndexAngular<float>, float, RbAnnoyIndexAngularFloat32> {
|
373
|
+
public:
|
374
|
+
static const rb_data_type_t annoy_index_type;
|
375
|
+
};
|
376
|
+
|
377
|
+
const rb_data_type_t RbAnnoyIndexAngularFloat32::annoy_index_type = {
|
378
|
+
"RbAnnoyIndexAngularFloat32", { NULL, RbAnnoyIndexAngularFloat32::annoy_index_free, RbAnnoyIndexAngularFloat32::annoy_index_size }, NULL, NULL, 0
|
379
|
+
};
|
380
|
+
|
381
|
+
class RbAnnoyIndexDotProductFloat32 : public RbAnnoyIndex<AnnoyIndexDotProduct<float>, float, RbAnnoyIndexDotProductFloat32> {
|
382
|
+
public:
|
383
|
+
static const rb_data_type_t annoy_index_type;
|
384
|
+
};
|
385
|
+
|
386
|
+
const rb_data_type_t RbAnnoyIndexDotProductFloat32::annoy_index_type = {
|
387
|
+
"RbAnnoyIndexDotProductFloat32", { NULL, RbAnnoyIndexDotProductFloat32::annoy_index_free, RbAnnoyIndexDotProductFloat32::annoy_index_size }, NULL, NULL, 0
|
388
|
+
};
|
389
|
+
|
390
|
+
class RbAnnoyIndexEuclideanFloat32 : public RbAnnoyIndex<AnnoyIndexEuclidean<float>, float, RbAnnoyIndexEuclideanFloat32> {
|
391
|
+
public:
|
392
|
+
static const rb_data_type_t annoy_index_type;
|
393
|
+
};
|
394
|
+
|
395
|
+
const rb_data_type_t RbAnnoyIndexEuclideanFloat32::annoy_index_type = {
|
396
|
+
"RbAnnoyIndexEuclideanFloat32", { NULL, RbAnnoyIndexEuclideanFloat32::annoy_index_free, RbAnnoyIndexEuclideanFloat32::annoy_index_size }, NULL, NULL, 0
|
397
|
+
};
|
398
|
+
|
399
|
+
class RbAnnoyIndexManhattanFloat32 : public RbAnnoyIndex<AnnoyIndexManhattan<float>, float, RbAnnoyIndexManhattanFloat32> {
|
400
|
+
public:
|
401
|
+
static const rb_data_type_t annoy_index_type;
|
402
|
+
};
|
403
|
+
|
404
|
+
const rb_data_type_t RbAnnoyIndexManhattanFloat32::annoy_index_type = {
|
405
|
+
"RbAnnoyIndexManhattanFloat32", { NULL, RbAnnoyIndexManhattanFloat32::annoy_index_free, RbAnnoyIndexManhattanFloat32::annoy_index_size }, NULL, NULL, 0
|
336
406
|
};
|
337
|
-
// clang-format on
|
338
407
|
|
339
408
|
#endif /* ANNOYEXT_HPP */
|
data/lib/annoy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: annoy-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yoshoku
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Annoy.rb provides Ruby bindings for the Annoy (Approximate Nearest Neighbors
|
14
14
|
Oh Yeah).
|
@@ -57,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
57
|
- !ruby/object:Gem::Version
|
58
58
|
version: '0'
|
59
59
|
requirements: []
|
60
|
-
rubygems_version: 3.
|
60
|
+
rubygems_version: 3.3.26
|
61
61
|
signing_key:
|
62
62
|
specification_version: 4
|
63
63
|
summary: Ruby bindings for the Annoy (Approximate Nearest Neighbors Oh Yeah).
|