annoy-rb 0.7.1 → 0.7.2
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.
- 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).
|