annoy-rb 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,242 @@
1
+
2
+ // This is from https://code.google.com/p/mman-win32/
3
+ //
4
+ // Licensed under MIT
5
+
6
+ #ifndef _MMAN_WIN32_H
7
+ #define _MMAN_WIN32_H
8
+
9
+ #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
10
+ #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
11
+ #endif
12
+
13
+ #include <sys/types.h>
14
+ #include <windows.h>
15
+ #include <errno.h>
16
+ #include <io.h>
17
+
18
+ #define PROT_NONE 0
19
+ #define PROT_READ 1
20
+ #define PROT_WRITE 2
21
+ #define PROT_EXEC 4
22
+
23
+ #define MAP_FILE 0
24
+ #define MAP_SHARED 1
25
+ #define MAP_PRIVATE 2
26
+ #define MAP_TYPE 0xf
27
+ #define MAP_FIXED 0x10
28
+ #define MAP_ANONYMOUS 0x20
29
+ #define MAP_ANON MAP_ANONYMOUS
30
+
31
+ #define MAP_FAILED ((void *)-1)
32
+
33
+ /* Flags for msync. */
34
+ #define MS_ASYNC 1
35
+ #define MS_SYNC 2
36
+ #define MS_INVALIDATE 4
37
+
38
+ #ifndef FILE_MAP_EXECUTE
39
+ #define FILE_MAP_EXECUTE 0x0020
40
+ #endif
41
+
42
+ static int __map_mman_error(const DWORD err, const int deferr)
43
+ {
44
+ if (err == 0)
45
+ return 0;
46
+ //TODO: implement
47
+ return err;
48
+ }
49
+
50
+ static DWORD __map_mmap_prot_page(const int prot)
51
+ {
52
+ DWORD protect = 0;
53
+
54
+ if (prot == PROT_NONE)
55
+ return protect;
56
+
57
+ if ((prot & PROT_EXEC) != 0)
58
+ {
59
+ protect = ((prot & PROT_WRITE) != 0) ?
60
+ PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
61
+ }
62
+ else
63
+ {
64
+ protect = ((prot & PROT_WRITE) != 0) ?
65
+ PAGE_READWRITE : PAGE_READONLY;
66
+ }
67
+
68
+ return protect;
69
+ }
70
+
71
+ static DWORD __map_mmap_prot_file(const int prot)
72
+ {
73
+ DWORD desiredAccess = 0;
74
+
75
+ if (prot == PROT_NONE)
76
+ return desiredAccess;
77
+
78
+ if ((prot & PROT_READ) != 0)
79
+ desiredAccess |= FILE_MAP_READ;
80
+ if ((prot & PROT_WRITE) != 0)
81
+ desiredAccess |= FILE_MAP_WRITE;
82
+ if ((prot & PROT_EXEC) != 0)
83
+ desiredAccess |= FILE_MAP_EXECUTE;
84
+
85
+ return desiredAccess;
86
+ }
87
+
88
+ inline void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
89
+ {
90
+ HANDLE fm, h;
91
+
92
+ void * map = MAP_FAILED;
93
+
94
+ #ifdef _MSC_VER
95
+ #pragma warning(push)
96
+ #pragma warning(disable: 4293)
97
+ #endif
98
+
99
+ const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ?
100
+ (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
101
+ const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
102
+ (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
103
+ const DWORD protect = __map_mmap_prot_page(prot);
104
+ const DWORD desiredAccess = __map_mmap_prot_file(prot);
105
+
106
+ const off_t maxSize = off + (off_t)len;
107
+
108
+ const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ?
109
+ (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
110
+ const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
111
+ (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
112
+
113
+ #ifdef _MSC_VER
114
+ #pragma warning(pop)
115
+ #endif
116
+
117
+ errno = 0;
118
+
119
+ if (len == 0
120
+ /* Unsupported flag combinations */
121
+ || (flags & MAP_FIXED) != 0
122
+ /* Usupported protection combinations */
123
+ || prot == PROT_EXEC)
124
+ {
125
+ errno = EINVAL;
126
+ return MAP_FAILED;
127
+ }
128
+
129
+ h = ((flags & MAP_ANONYMOUS) == 0) ?
130
+ (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
131
+
132
+ if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
133
+ {
134
+ errno = EBADF;
135
+ return MAP_FAILED;
136
+ }
137
+
138
+ fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
139
+
140
+ if (fm == NULL)
141
+ {
142
+ errno = __map_mman_error(GetLastError(), EPERM);
143
+ return MAP_FAILED;
144
+ }
145
+
146
+ map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
147
+
148
+ CloseHandle(fm);
149
+
150
+ if (map == NULL)
151
+ {
152
+ errno = __map_mman_error(GetLastError(), EPERM);
153
+ return MAP_FAILED;
154
+ }
155
+
156
+ return map;
157
+ }
158
+
159
+ inline int munmap(void *addr, size_t len)
160
+ {
161
+ if (UnmapViewOfFile(addr))
162
+ return 0;
163
+
164
+ errno = __map_mman_error(GetLastError(), EPERM);
165
+
166
+ return -1;
167
+ }
168
+
169
+ inline int mprotect(void *addr, size_t len, int prot)
170
+ {
171
+ DWORD newProtect = __map_mmap_prot_page(prot);
172
+ DWORD oldProtect = 0;
173
+
174
+ if (VirtualProtect(addr, len, newProtect, &oldProtect))
175
+ return 0;
176
+
177
+ errno = __map_mman_error(GetLastError(), EPERM);
178
+
179
+ return -1;
180
+ }
181
+
182
+ inline int msync(void *addr, size_t len, int flags)
183
+ {
184
+ if (FlushViewOfFile(addr, len))
185
+ return 0;
186
+
187
+ errno = __map_mman_error(GetLastError(), EPERM);
188
+
189
+ return -1;
190
+ }
191
+
192
+ inline int mlock(const void *addr, size_t len)
193
+ {
194
+ if (VirtualLock((LPVOID)addr, len))
195
+ return 0;
196
+
197
+ errno = __map_mman_error(GetLastError(), EPERM);
198
+
199
+ return -1;
200
+ }
201
+
202
+ inline int munlock(const void *addr, size_t len)
203
+ {
204
+ if (VirtualUnlock((LPVOID)addr, len))
205
+ return 0;
206
+
207
+ errno = __map_mman_error(GetLastError(), EPERM);
208
+
209
+ return -1;
210
+ }
211
+
212
+ #if !defined(__MINGW32__)
213
+ inline int ftruncate(const int fd, const int64_t size) {
214
+ if (fd < 0) {
215
+ errno = EBADF;
216
+ return -1;
217
+ }
218
+
219
+ HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
220
+ LARGE_INTEGER li_start, li_size;
221
+ li_start.QuadPart = static_cast<int64_t>(0);
222
+ li_size.QuadPart = size;
223
+ if (SetFilePointerEx(h, li_start, NULL, FILE_CURRENT) == ~0 ||
224
+ SetFilePointerEx(h, li_size, NULL, FILE_BEGIN) == ~0 ||
225
+ !SetEndOfFile(h)) {
226
+ unsigned long error = GetLastError();
227
+ fprintf(stderr, "I/O error while truncating: %lu\n", error);
228
+ switch (error) {
229
+ case ERROR_INVALID_HANDLE:
230
+ errno = EBADF;
231
+ break;
232
+ default:
233
+ errno = EIO;
234
+ break;
235
+ }
236
+ return -1;
237
+ }
238
+ return 0;
239
+ }
240
+ #endif
241
+
242
+ #endif
data/lib/annoy.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'annoy/version'
4
- require 'annoy/annoy'
4
+ require 'annoy/annoyext'
5
5
 
6
6
  module Annoy
7
7
  # AnnoyIndex is a class that provides functions for k-nearest neighbors search.
@@ -68,9 +68,10 @@ module Annoy
68
68
  # Build a forest of index trees. After building, no more items can be added.
69
69
  #
70
70
  # @param n_trees [Integer] The number of trees. More trees gives higher search precision.
71
+ # @param n_jobs [Integer] The number of threads used to build the trees. If -1 is given, uses all available CPU cores.
71
72
  # @return [Boolean]
72
- def build(n_trees)
73
- @index.build(n_trees)
73
+ def build(n_trees, n_jobs: -1)
74
+ @index.build(n_trees, n_jobs)
74
75
  end
75
76
 
76
77
  # Save the search index to disk. After saving, no more items can be added.
data/lib/annoy/version.rb CHANGED
@@ -3,5 +3,5 @@
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.1.0'.freeze
6
+ VERSION = '0.3.0'.freeze
7
7
  end
data/sig/annoy.rbs ADDED
@@ -0,0 +1,114 @@
1
+ module Annoy
2
+ VERSION: String
3
+
4
+ class AnnoyIndex
5
+ attr_reader n_features: Integer
6
+ attr_reader metric: String
7
+
8
+ def initialize: (n_features: Integer n_features, ?metric: String metric) -> void
9
+ def add_item: (Integer i, Array[Float | Integer] v) -> bool
10
+ def build: (Integer n_trees, ?n_jobs: Integer n_jobs) -> bool
11
+ def save: (String filename, ?prefault: bool prefault) -> bool
12
+ def load: (String filename, ?prefault: bool prefault) -> bool
13
+ def unload: () -> bool
14
+ def get_nns_by_item: (Integer i, Integer n, ?search_k: Integer search_k, ?include_distances: (true | false) include_distances) -> ([Array[Integer], Array[Float | Integer]] | Array[Integer])
15
+ def get_nns_by_vector: (Array[Float | Integer] v, Integer n, ?search_k: Integer search_k, ?include_distances: (true | false) include_distances) -> ([Array[Integer], Array[Float | Integer]] | Array[Integer])
16
+ def get_item: (Integer i) -> Array[Float | Integer]
17
+ def get_distance: (Integer i, Integer j) -> (Float | Integer)
18
+ def n_items: () -> Integer
19
+ def n_trees: () -> Integer
20
+ def on_disk_build: (String filename) -> bool
21
+ def verbose: (bool flag) -> nil
22
+ def seed: (Integer s) -> nil
23
+ end
24
+
25
+ class AnnoyIndexAngular
26
+ def initialize: (Integer n_features) -> void
27
+ def add_item: (Integer i, Array[Float] v) -> bool
28
+ def build: (Integer n_trees, Integer n_jobs) -> bool
29
+ def save: (String filename, bool prefault) -> bool
30
+ def load: (String filename, bool prefault) -> bool
31
+ def unload: () -> bool
32
+ def get_nns_by_item: (Integer i, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Float]] | Array[Integer])
33
+ def get_nns_by_vector: (Array[Float] v, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Float]] | Array[Integer])
34
+ def get_item: (Integer i) -> Array[Float]
35
+ def get_distance: (Integer i, Integer j) -> Float
36
+ def n_items: () -> Integer
37
+ def n_trees: () -> Integer
38
+ def on_disk_build: (String filename) -> bool
39
+ def verbose: (bool flag) -> nil
40
+ def seed: (Integer s) -> nil
41
+ end
42
+
43
+ class AnnoyIndexDotProduct
44
+ def initialize: (Integer n_features) -> void
45
+ def add_item: (Integer i, Array[Float] v) -> bool
46
+ def build: (Integer n_trees, Integer n_jobs) -> bool
47
+ def save: (String filename, bool prefault) -> bool
48
+ def load: (String filename, bool prefault) -> bool
49
+ def unload: () -> bool
50
+ def get_nns_by_item: (Integer i, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Float]] | Array[Integer])
51
+ def get_nns_by_vector: (Array[Float] v, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Float]] | Array[Integer])
52
+ def get_item: (Integer i) -> Array[Float]
53
+ def get_distance: (Integer i, Integer j) -> Float
54
+ def n_items: () -> Integer
55
+ def n_trees: () -> Integer
56
+ def on_disk_build: (String filename) -> bool
57
+ def verbose: (bool flag) -> nil
58
+ def seed: (Integer s) -> nil
59
+ end
60
+
61
+ class AnnoyIndexHamming
62
+ def initialize: (Integer n_features) -> void
63
+ def add_item: (Integer i, Array[Integer] v) -> bool
64
+ def build: (Integer n_trees, Integer n_jobs) -> bool
65
+ def save: (String filename, bool prefault) -> bool
66
+ def load: (String filename, bool prefault) -> bool
67
+ def unload: () -> bool
68
+ def get_nns_by_item: (Integer i, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Integer]] | Array[Integer])
69
+ def get_nns_by_vector: (Array[Integer] v, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Integer]] | Array[Integer])
70
+ def get_item: (Integer i) -> Array[Integer]
71
+ def get_distance: (Integer i, Integer j) -> Integer
72
+ def n_items: () -> Integer
73
+ def n_trees: () -> Integer
74
+ def on_disk_build: (String filename) -> bool
75
+ def verbose: (bool flag) -> nil
76
+ def seed: (Integer s) -> nil
77
+ end
78
+
79
+ class AnnoyIndexEuclidean
80
+ def initialize: (Integer n_features) -> void
81
+ def add_item: (Integer i, Array[Float] v) -> bool
82
+ def build: (Integer n_trees, Integer n_jobs) -> bool
83
+ def save: (String filename, bool prefault) -> bool
84
+ def load: (String filename, bool prefault) -> bool
85
+ def unload: () -> bool
86
+ def get_nns_by_item: (Integer i, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Float]] | Array[Integer])
87
+ def get_nns_by_vector: (Array[Float] v, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Float]] | Array[Integer])
88
+ def get_item: (Integer i) -> Array[Float]
89
+ def get_distance: (Integer i, Integer j) -> Float
90
+ def n_items: () -> Integer
91
+ def n_trees: () -> Integer
92
+ def on_disk_build: (String filename) -> bool
93
+ def verbose: (bool flag) -> nil
94
+ def seed: (Integer s) -> nil
95
+ end
96
+
97
+ class AnnoyIndexManhattan
98
+ def initialize: (Integer n_features) -> void
99
+ def add_item: (Integer i, Array[Float] v) -> bool
100
+ def build: (Integer n_trees, Integer n_jobs) -> bool
101
+ def save: (String filename, bool prefault) -> bool
102
+ def load: (String filename, bool prefault) -> bool
103
+ def unload: () -> bool
104
+ def get_nns_by_item: (Integer i, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Float]] | Array[Integer])
105
+ def get_nns_by_vector: (Array[Float] v, Integer n, Integer search_k, (true | false) include_distances) -> ([Array[Integer], Array[Float]] | Array[Integer])
106
+ def get_item: (Integer i) -> Array[Float]
107
+ def get_distance: (Integer i, Integer j) -> Float
108
+ def n_items: () -> Integer
109
+ def n_trees: () -> Integer
110
+ def on_disk_build: (String filename) -> bool
111
+ def verbose: (bool flag) -> nil
112
+ def seed: (Integer s) -> nil
113
+ end
114
+ end
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.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-08 00:00:00.000000000 Z
11
+ date: 2021-05-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Annoy.rb is a Ruby binding for the Annoy (Approximate Nearest Neighbors
14
14
  Oh Yeah).
@@ -19,31 +19,35 @@ extensions:
19
19
  - ext/annoy/extconf.rb
20
20
  extra_rdoc_files: []
21
21
  files:
22
+ - ".github/workflows/build.yml"
22
23
  - ".gitignore"
23
24
  - ".rspec"
24
- - ".travis.yml"
25
25
  - CHANGELOG.md
26
26
  - CODE_OF_CONDUCT.md
27
27
  - Gemfile
28
28
  - LICENSE.txt
29
29
  - README.md
30
30
  - Rakefile
31
+ - Steepfile
31
32
  - annoy-rb.gemspec
32
- - ext/annoy/annoy.cpp
33
- - ext/annoy/annoy.hpp
33
+ - ext/annoy/annoyext.cpp
34
+ - ext/annoy/annoyext.hpp
34
35
  - ext/annoy/extconf.rb
35
36
  - ext/annoy/src/annoylib.h
36
37
  - ext/annoy/src/kissrandom.h
38
+ - ext/annoy/src/mman.h
37
39
  - lib/annoy.rb
38
40
  - lib/annoy/version.rb
41
+ - sig/annoy.rbs
39
42
  homepage: https://github.com/yoshoku/annoy.rb
40
43
  licenses:
41
44
  - Apache-2.0
42
45
  metadata:
43
46
  homepage_uri: https://github.com/yoshoku/annoy.rb
44
47
  source_code_uri: https://github.com/yoshoku/annoy.rb
45
- changelog_uri: https://github.com/yoshoku/annoy.rb/blob/master/CHANGELOG.md
46
- post_install_message:
48
+ changelog_uri: https://github.com/yoshoku/annoy.rb/blob/main/CHANGELOG.md
49
+ documentation_uri: https://yoshoku.github.io/annoy.rb/doc/
50
+ post_install_message:
47
51
  rdoc_options: []
48
52
  require_paths:
49
53
  - lib
@@ -58,8 +62,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
62
  - !ruby/object:Gem::Version
59
63
  version: '0'
60
64
  requirements: []
61
- rubygems_version: 3.1.2
62
- signing_key:
65
+ rubygems_version: 3.1.6
66
+ signing_key:
63
67
  specification_version: 4
64
68
  summary: Ruby binding for the Annoy (Approximate Nearest Neighbors Oh Yeah).
65
69
  test_files: []