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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1f1b7326f096ef01be709b819e6fcac709776e5561d931b8b8a5b022aed1dc2
4
- data.tar.gz: e767849b0970773b1c01307b830d6bbf15c250d86a4716d809867dc0cf8f211d
3
+ metadata.gz: 25b6e3d18705801e5458c656517e57d5bb42fb42846bc4cde36107787bc0f506
4
+ data.tar.gz: caca0acd3a163bc4a0e09dfe7a30dfcd975d3b123f7bce76f44263545271d8d1
5
5
  SHA512:
6
- metadata.gz: da4627d3414ed6ba062a3fb5d9ba546a32dced3e11d42ab4756badc219c29813b9d5389cbcb2159c027ad9a3b43c58f23f0f19660836c557d12c2c1b2a37330f
7
- data.tar.gz: f195b96f9010a67ccc01088006a09e1ec5f857e7226f3d6b7c58a9ab5205757365061bbd1eb571715bfcd24a8f47c00e6aea7fcc1d7024f8cb6e511b7cb37255
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)).
@@ -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-2022 Atsushi Tatsuma
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
- RbAnnoyIndex<AnnoyIndexAngular<double>, double>::define_class(rb_mAnnoy, "AnnoyIndexAngular");
24
- RbAnnoyIndex<AnnoyIndexDotProduct<double>, double>::define_class(rb_mAnnoy, "AnnoyIndexDotProduct");
25
- RbAnnoyIndex<AnnoyIndexHamming<uint64_t>, uint64_t>::define_class(rb_mAnnoy, "AnnoyIndexHamming");
26
- RbAnnoyIndex<AnnoyIndexEuclidean<double>, double>::define_class(rb_mAnnoy, "AnnoyIndexEuclidean");
27
- RbAnnoyIndex<AnnoyIndexManhattan<double>, double>::define_class(rb_mAnnoy, "AnnoyIndexManhattan");
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
- RbAnnoyIndex<AnnoyIndexAngular<float>, float>::define_class(rb_mAnnoy, "AnnoyIndexAngularFloat32");
30
- RbAnnoyIndex<AnnoyIndexDotProduct<float>, float>::define_class(rb_mAnnoy, "AnnoyIndexDotProductFloat32");
31
- RbAnnoyIndex<AnnoyIndexEuclidean<float>, float>::define_class(rb_mAnnoy, "AnnoyIndexEuclideanFloat32");
32
- RbAnnoyIndex<AnnoyIndexManhattan<float>, float>::define_class(rb_mAnnoy, "AnnoyIndexManhattanFloat32");
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
  }
@@ -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-2022 Atsushi Tatsuma
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 F> using AnnoyIndexAngular = AnnoyIndex<int32_t, F, Angular, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
39
- template<typename F> using AnnoyIndexDotProduct = AnnoyIndex<int32_t, F, DotProduct, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
40
- template<typename F> using AnnoyIndexHamming = AnnoyIndex<int32_t, F, Hamming, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
41
- template<typename F> using AnnoyIndexEuclidean = AnnoyIndex<int32_t, F, Euclidean, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
42
- template<typename F> using AnnoyIndexManhattan = AnnoyIndex<int32_t, F, Manhattan, Kiss64Random, AnnoyIndexThreadedBuildPolicy>;
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 T, typename F> class RbAnnoyIndex {
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
- T* ptr = (T*)ruby_xmalloc(sizeof(T));
49
- new (ptr) T();
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
- ((T*)ptr)->~AnnoyIndex();
57
+ ((Idx*)ptr)->~AnnoyIndex();
55
58
  ruby_xfree(ptr);
56
59
  };
57
60
 
58
- static size_t annoy_index_size(const void* ptr) { return sizeof(*((T*)ptr)); };
61
+ static size_t annoy_index_size(const void* ptr) {
62
+ return sizeof(*((Idx*)ptr));
63
+ };
59
64
 
60
- static T* get_annoy_index(VALUE self) {
61
- T* ptr;
62
- TypedData_Get_Struct(self, T, &annoy_index_type, ptr);
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
- T* ptr = get_annoy_index(self);
94
- new (ptr) T(n_dims);
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
- F* vec = (F*)ruby_xmalloc(n_dims * sizeof(F));
115
+ El* vec = (El*)ruby_xmalloc(n_dims * sizeof(El));
113
116
  for (int i = 0; i < n_dims; i++) {
114
- vec[i] = (F)(typeid(F) == typeid(uint64_t) ? NUM2UINT(rb_ary_entry(arr, i)) : NUM2DBL(rb_ary_entry(arr, 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<F> distances;
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(F) == typeid(uint64_t) ? UINT2NUM(distances[i]) : DBL2NUM(distances[i]));
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
- F* vec = (F*)ruby_xmalloc(n_dims * sizeof(F));
226
+ El* vec = (El*)ruby_xmalloc(n_dims * sizeof(El));
224
227
  for (int i = 0; i < n_dims; i++) {
225
- vec[i] = (F)(typeid(F) == typeid(uint64_t) ? NUM2UINT(rb_ary_entry(_vec, i)) : NUM2DBL(rb_ary_entry(_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<F> distances;
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(F) == typeid(uint64_t) ? UINT2NUM(distances[i]) : DBL2NUM(distances[i]));
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
- F* vec = (F*)ruby_xmalloc(n_dims * sizeof(F));
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(F) == typeid(uint64_t) ? UINT2NUM(vec[i]) : DBL2NUM(vec[i]));
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 F dist = get_annoy_index(self)->get_distance(i, j);
280
- return typeid(F) == typeid(uint64_t) ? UINT2NUM(dist) : DBL2NUM(dist);
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
- // clang-format off
325
- template<class T, typename F>
326
- const rb_data_type_t RbAnnoyIndex<T, F>::annoy_index_type = {
327
- "RbAnnoyIndex",
328
- {
329
- NULL,
330
- RbAnnoyIndex::annoy_index_free,
331
- RbAnnoyIndex::annoy_index_size
332
- },
333
- NULL,
334
- NULL,
335
- RUBY_TYPED_FREE_IMMEDIATELY
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
@@ -3,7 +3,7 @@
3
3
  # Annoy.rb is a Ruby wrapper for Annoy (Approximate Nearest Neighbors Oh Yeah).
4
4
  module Annoy
5
5
  # The version of Annoy.rb you are using.
6
- VERSION = '0.7.1'
6
+ VERSION = '0.7.2'
7
7
 
8
8
  # The version of Annoy included with gem.
9
9
  ANNOY_VERSION = '1.17.1'
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.1
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: 2022-09-30 00:00:00.000000000 Z
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.2.33
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).