librtree 0.8.0 → 0.8.5

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: 35028e6e74b4682479656b89086bf47fb42a43bd09ce7c9070df53adffcf4cec
4
- data.tar.gz: d58480430dada176e90f0e42e316b82be990fc4c414a993ce627a1b4b11ba707
3
+ metadata.gz: c9abe4061328dd6a2b8b9f1c00a38f76332a0f0a188af7a5d3e6f1125eab346e
4
+ data.tar.gz: 4029ed06803576cc76ec7bd8d3d1eb9a2d628da9fd982d04e80b643177fce244
5
5
  SHA512:
6
- metadata.gz: 5bcb8f2b41ccab397f5accef4846912e9932dd07fa540c020c114a079ed9252296a8324ae647452170a445babcceb03984f258d053eb55d45566ad1b6da03d67
7
- data.tar.gz: 8de9c0cbcfde749d139590c81d41b55bc78c73aa826cb5385f65e9b4a1c36e8a08abc3e1f5b751a082f33fadb3e56001dd8a391f93c6314f4728e5ec772454ab
6
+ metadata.gz: f6b7005f8ec37a45ff8ee894de5642eb969a26af72ad9fa330aeeae1c746447d786b309301e84116de595bed40f70bef8683fbd9a969b2b9c2cabb32e5c4d374
7
+ data.tar.gz: c4c6641e2cdfd9f14f21b50047fe2f304ab1446eb643a0f6cd3acd594fbc37469cf71c78434daa82b759bdb2741a1f887add7809d72c7bbc3f39886aee3ecc9b
data/ext/rtree/extconf.rb CHANGED
@@ -20,11 +20,9 @@ puts LIB_DIRS.inspect
20
20
 
21
21
  dir_config('librtree', HEADER_DIRS, LIB_DIRS)
22
22
 
23
- abort 'missing csv.h' unless find_header('csv.h')
24
23
  abort 'missing jansson.h' unless find_header('jansson.h')
25
24
  abort 'missing rtree.h' unless find_header('rtree.h')
26
25
 
27
- abort "libcsv is missing" unless find_library('csv', 'csv_init')
28
26
  abort "libjansson is missing" unless find_library('jansson', 'json_pack')
29
27
  abort "librtree is missing" unless find_library('rtree', 'rtree_new')
30
28
 
data/ext/rtree/rtree.c CHANGED
@@ -1,35 +1,48 @@
1
1
  #include <ruby.h>
2
2
  #include <ruby/io.h>
3
+ #include <ruby/version.h>
3
4
 
4
5
  #include <rtree.h>
6
+ #include <rtree/package.h>
5
7
 
6
8
  #include <errno.h>
7
9
  #include <stdint.h>
8
10
 
9
- typedef struct
10
- {
11
- void *rtree;
12
- } lrt_t;
13
11
 
14
- static void lrt_free(void *p)
12
+ static void lrt_dfree(void *p)
15
13
  {
16
- lrt_t *lrt = p;
17
-
18
- if (lrt->rtree)
19
- {
20
- rtree_destroy(lrt->rtree);
21
- lrt->rtree = NULL;
22
- }
14
+ rtree_destroy((rtree_t*)p);
23
15
  }
24
16
 
25
- static VALUE lrt_alloc(VALUE cls)
17
+ static size_t lrt_dsize(const void *p)
26
18
  {
27
- lrt_t *lrt;
28
- VALUE obj = Data_Make_Struct(cls, lrt_t, NULL, lrt_free, lrt);
19
+ return rtree_bytes((const rtree_t*)p);
20
+ }
29
21
 
30
- lrt->rtree = NULL;
22
+ static rb_data_type_t type = {
23
+ .wrap_struct_name = "rtree-wrap",
24
+ .function = {
25
+ .dmark = NULL,
26
+ .dfree = lrt_dfree,
27
+ .dsize = lrt_dsize,
28
+ #if RUBY_API_VERSION_CODE < 20700
29
+ .reserved = { NULL, NULL }
30
+ #else
31
+ .dcompact = NULL,
32
+ .reserved = { NULL }
33
+ #endif
34
+ },
35
+ .parent = NULL,
36
+ .data = NULL,
37
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
38
+ };
31
39
 
32
- return obj;
40
+ static VALUE lrt_alloc(VALUE cls)
41
+ {
42
+ rtree_t *rtree;;
43
+ if ((rtree = rtree_alloc()) == NULL)
44
+ rb_raise(rb_eNoMemError, "failed to alloc rtree");
45
+ return TypedData_Wrap_Struct(cls, &type, rtree);
33
46
  }
34
47
 
35
48
  static VALUE lrt_init(VALUE self, VALUE dim_obj, VALUE flags_obj)
@@ -40,31 +53,28 @@ static VALUE lrt_init(VALUE self, VALUE dim_obj, VALUE flags_obj)
40
53
  Check_Type(dim_obj, T_FIXNUM);
41
54
  state_flags_t flags = FIX2UINT(flags_obj);
42
55
 
43
- lrt_t *lrt;
44
- Data_Get_Struct(self, lrt_t, lrt);
56
+ rtree_t *rtree;
57
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
45
58
 
46
- if ((lrt->rtree = rtree_new(dim, flags)) == NULL)
47
- rb_raise(rb_eNoMemError, "failed to create rtree");
59
+ if ((rtree_init(rtree, dim, flags)) != 0)
60
+ rb_raise(rb_eNoMemError, "failed to init rtree");
48
61
 
49
62
  return self;
50
63
  }
51
64
 
52
65
  static VALUE lrt_release(VALUE self)
53
66
  {
54
- lrt_t *lrt;
55
- Data_Get_Struct(self, lrt_t, lrt);
56
-
57
- free(lrt->rtree);
58
-
67
+ rtree_t *rtree;
68
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
69
+ rtree_destroy(rtree);
59
70
  return self;
60
71
  }
61
72
 
62
73
  static VALUE lrt_height(VALUE self)
63
74
  {
64
- lrt_t *lrt;
65
- Data_Get_Struct(self, lrt_t, lrt);
66
-
67
- return INT2NUM(rtree_height(lrt->rtree));
75
+ rtree_t *rtree;
76
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
77
+ return INT2NUM(rtree_height(rtree));
68
78
  }
69
79
 
70
80
  static VALUE lrt_add_rect(VALUE self, VALUE id_obj, VALUE coord_obj)
@@ -72,11 +82,9 @@ static VALUE lrt_add_rect(VALUE self, VALUE id_obj, VALUE coord_obj)
72
82
  Check_Type(coord_obj, T_ARRAY);
73
83
  Check_Type(id_obj, T_FIXNUM);
74
84
 
75
- lrt_t *lrt;
76
- Data_Get_Struct(self, lrt_t, lrt);
85
+ rtree_t *rtree;
86
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
77
87
 
78
- rtree_t
79
- *rtree = lrt->rtree;
80
88
  rtree_id_t
81
89
  id = FIX2ULONG(id_obj);
82
90
  size_t
@@ -132,11 +140,10 @@ static VALUE lrt_update(VALUE self)
132
140
  if (!rb_block_given_p())
133
141
  rb_raise(rb_eArgError, "Expected block");
134
142
 
135
- lrt_t *lrt;
136
- Data_Get_Struct(self, lrt_t, lrt);
137
- rtree_t *rtree = lrt->rtree;
138
- size_t len = 2 * state_dims(rtree->state);
143
+ rtree_t *rtree;
144
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
139
145
 
146
+ size_t len = 2 * state_dims(rtree->state);
140
147
  int err = rtree_update(rtree, update_cb, &len);
141
148
 
142
149
  if (err != 0)
@@ -169,11 +176,9 @@ static VALUE lrt_search(VALUE self, VALUE coord_obj)
169
176
 
170
177
  Check_Type(coord_obj, T_ARRAY);
171
178
 
172
- lrt_t *lrt;
173
- Data_Get_Struct(self, lrt_t, lrt);
179
+ rtree_t *rtree;
180
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
174
181
 
175
- rtree_t
176
- *rtree = lrt->rtree;
177
182
  size_t
178
183
  len = RARRAY_LEN(coord_obj),
179
184
  dim = state_dims(rtree->state);
@@ -215,12 +220,7 @@ static VALUE deserialise(VALUE cls, VALUE io_obj, deserialise_t *f)
215
220
  rb_raise(rb_eRuntimeError, "Failed read from stream");
216
221
  }
217
222
 
218
- lrt_t *lrt;
219
- VALUE obj = Data_Make_Struct(cls, lrt_t, NULL, lrt_free, lrt);
220
-
221
- lrt->rtree = rtree;
222
-
223
- return obj;
223
+ return TypedData_Wrap_Struct(cls, &type, rtree);
224
224
  }
225
225
 
226
226
  static VALUE lrt_json_read(VALUE cls, VALUE io_obj)
@@ -259,12 +259,7 @@ static VALUE lrt_csv_read(VALUE cls,
259
259
  rb_raise(rb_eRuntimeError, "Failed read from stream");
260
260
  }
261
261
 
262
- lrt_t *lrt;
263
- VALUE obj = Data_Make_Struct(cls, lrt_t, NULL, lrt_free, lrt);
264
-
265
- lrt->rtree = rtree;
266
-
267
- return obj;
262
+ return TypedData_Wrap_Struct(cls, &type, rtree);
268
263
  }
269
264
 
270
265
  /* serialisation */
@@ -281,9 +276,8 @@ static VALUE serialise(VALUE self, VALUE io_obj, serialise_t *f)
281
276
  rb_io_check_writable(io);
282
277
  FILE *fp = rb_io_stdio_file(io);
283
278
 
284
- lrt_t *lrt;
285
- Data_Get_Struct(self, lrt_t, lrt);
286
- rtree_t *rtree = lrt->rtree;
279
+ rtree_t *rtree;
280
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
287
281
 
288
282
  int err = f(rtree, fp);
289
283
  if (err != 0)
@@ -304,12 +298,10 @@ static VALUE lrt_bsrt_write(VALUE self, VALUE io_obj)
304
298
 
305
299
  static VALUE lrt_identical(VALUE self, VALUE other)
306
300
  {
307
- lrt_t *lrt_self, *lrt_other;
308
- Data_Get_Struct(self, lrt_t, lrt_self);
309
- Data_Get_Struct(other, lrt_t, lrt_other);
310
- rtree_t
311
- *rtree_self = lrt_self->rtree,
312
- *rtree_other = lrt_other->rtree;
301
+ rtree_t *rtree_self, *rtree_other;
302
+
303
+ TypedData_Get_Struct(self, rtree_t, &type, rtree_self);
304
+ TypedData_Get_Struct(other, rtree_t, &type, rtree_other);
313
305
 
314
306
  if (rtree_identical(rtree_self, rtree_other))
315
307
  return Qtrue;
@@ -319,12 +311,12 @@ static VALUE lrt_identical(VALUE self, VALUE other)
319
311
 
320
312
  static VALUE lrt_clone(VALUE self)
321
313
  {
322
- lrt_t *lrt;
323
- Data_Get_Struct(self, lrt_t, lrt);
324
314
  rtree_t *rtree;
315
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
325
316
 
317
+ rtree_t *clone;
326
318
  errno = 0;
327
- if ((rtree = rtree_clone(lrt->rtree)) == NULL)
319
+ if ((clone = rtree_clone(rtree)) == NULL)
328
320
  {
329
321
  if (errno)
330
322
  rb_sys_fail(__func__);
@@ -332,13 +324,73 @@ static VALUE lrt_clone(VALUE self)
332
324
  rb_raise(rb_eRuntimeError, "Failed clone");
333
325
  }
334
326
 
335
- lrt_t *lrt_cloned;
336
- VALUE cls = CLASS_OF(self);
337
- VALUE obj = Data_Make_Struct(cls, lrt_t, NULL, lrt_free, lrt_cloned);
327
+ return TypedData_Wrap_Struct(CLASS_OF(self), &type, clone);
328
+ }
329
+
330
+ static VALUE state_size_access(VALUE self, size_t (*f)(const state_t*))
331
+ {
332
+ rtree_t *rtree;
333
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
334
+ return INT2NUM(f(rtree->state));
335
+ }
336
+
337
+ static VALUE lrt_dim(VALUE self)
338
+ {
339
+ return state_size_access(self, state_dims);
340
+ }
341
+
342
+ static VALUE lrt_page_size(VALUE self)
343
+ {
344
+ return state_size_access(self, state_page_size);
345
+ }
346
+
347
+ static VALUE lrt_node_size(VALUE self)
348
+ {
349
+ return state_size_access(self, state_node_size);
350
+ }
338
351
 
339
- lrt_cloned->rtree = rtree;
352
+ static VALUE lrt_rect_size(VALUE self)
353
+ {
354
+ return state_size_access(self, state_rect_size);
355
+ }
356
+
357
+ static VALUE lrt_branch_size(VALUE self)
358
+ {
359
+ return state_size_access(self, state_branch_size);
360
+ }
361
+
362
+ static VALUE lrt_branching_factor(VALUE self)
363
+ {
364
+ return state_size_access(self, state_branching_factor);
365
+ }
340
366
 
341
- return obj;
367
+ static VALUE lrt_unit_sphere_volume(VALUE self)
368
+ {
369
+ rtree_t *rtree;
370
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
371
+ return DBL2NUM(state_unit_sphere_volume(rtree->state));
372
+ }
373
+
374
+ static VALUE lrt_size(VALUE self)
375
+ {
376
+ rtree_t *rtree;
377
+ TypedData_Get_Struct(self, rtree_t, &type, rtree);
378
+ return INT2NUM(rtree_bytes(rtree));
379
+ }
380
+
381
+ static VALUE lrt_version(VALUE self)
382
+ {
383
+ return rb_str_new_cstr(rtree_package_version);
384
+ }
385
+
386
+ static VALUE lrt_bugreport(VALUE self)
387
+ {
388
+ return rb_str_new_cstr(rtree_package_bugreport);
389
+ }
390
+
391
+ static VALUE lrt_url(VALUE self)
392
+ {
393
+ return rb_str_new_cstr(rtree_package_url);
342
394
  }
343
395
 
344
396
  void Init_rtree(void)
@@ -356,6 +408,17 @@ void Init_rtree(void)
356
408
  rb_define_method(cls, "json_write", lrt_json_write, 1);
357
409
  rb_define_method(cls, "bsrt_write", lrt_bsrt_write, 1);
358
410
  rb_define_method(cls, "eq?", lrt_identical, 1);
411
+ rb_define_method(cls, "dim", lrt_dim, 0);
412
+ rb_define_method(cls, "size", lrt_size, 0);
413
+ rb_define_method(cls, "page_size", lrt_page_size, 0);
414
+ rb_define_method(cls, "node_size", lrt_node_size, 0);
415
+ rb_define_method(cls, "rect_size", lrt_rect_size, 0);
416
+ rb_define_method(cls, "branch_size", lrt_branch_size, 0);
417
+ rb_define_method(cls, "branching_factor", lrt_branching_factor, 0);
418
+ rb_define_method(cls, "unit_sphere_volume", lrt_unit_sphere_volume, 0);
419
+ rb_define_singleton_method(cls, "version", lrt_version, 0);
420
+ rb_define_singleton_method(cls, "bugreport", lrt_bugreport, 0);
421
+ rb_define_singleton_method(cls, "url", lrt_url, 0);
359
422
  rb_define_singleton_method(cls, "json_read", lrt_json_read, 1);
360
423
  rb_define_singleton_method(cls, "bsrt_read", lrt_bsrt_read, 1);
361
424
  rb_define_singleton_method(cls, "csv_read", lrt_csv_read, 3);
data/lib/rtree.rb CHANGED
@@ -1,4 +1,4 @@
1
- # The C extension
1
+ # The Ruby/C interface, which is not documented in YARD.
2
2
  class RTreeC ; end
3
3
 
4
4
  # @author RTree J. J. Green
@@ -7,6 +7,12 @@ class RTreeC ; end
7
7
  # {http://soliton.vm.bytemark.co.uk/pub/jjg/en/code/librtree librtree}
8
8
  # implementing the R-tree spatial index of Guttman-Green.
9
9
  #
10
+ # Use
11
+ #
12
+ # require 'rtree'
13
+ #
14
+ # to make the {RTree} class available.
15
+ #
10
16
  # Given a set or rectangles (or higher dimensional cuboids) and their
11
17
  # associated ids, one can build an {RTree} using the {.csv_read} class
12
18
  # method or repeated calls to the {#add_rect} instance method. The
@@ -43,7 +49,7 @@ class RTreeC ; end
43
49
  # it as payload. In particular, the value may be non-unique and may be zero.
44
50
  # One should note that the id type used internally by the library is
45
51
  # determined at compile-time (with the RTREE_ID_TYPE variable) and by
46
- # default this is a 32-bit unsigned integer.
52
+ # default this is a 64-bit unsigned integer.
47
53
  #
48
54
  class RTree < RTreeC
49
55
 
@@ -93,6 +99,11 @@ class RTree < RTreeC
93
99
  # @param split [:linear, :quadratic] See {#initialize}
94
100
  # @param node_page [Integer] See {#initialize}
95
101
  # @return [RTree] the newly built RTree
102
+ # @note The CSV file (without header) should have the id in the
103
+ # first column, then twice as many floats as the dimension.
104
+ # Extra columns may be present and will be ignored (this
105
+ # useful feature is the reason that the dimension is a required
106
+ # argument).
96
107
  def csv_read(io, dim, split: :quadratic, node_page: 0)
97
108
  flags = split_flag(split) | node_page_flag(node_page)
98
109
  super(io, dim, flags)
@@ -109,6 +120,21 @@ class RTree < RTreeC
109
120
  end
110
121
  end
111
122
 
123
+ # @return [Array<Integer>] version of librtree
124
+ def version
125
+ @version ||= super.split('.').map(&:to_i)
126
+ end
127
+
128
+ # @return [String] email address for librtree bug reports
129
+ def bugreport
130
+ super
131
+ end
132
+
133
+ # @return [String] librtree homepage
134
+ def url
135
+ super
136
+ end
137
+
112
138
  # @!visibility private
113
139
  def split_flag(split)
114
140
  case split
@@ -222,7 +248,7 @@ class RTree < RTreeC
222
248
  # is much faster than rebuilding the R-tree; in this Ruby interface
223
249
  # the callback must convert C floats to Ruby, yield them to the
224
250
  # block and then convert the returned Ruby Floats to C; so we would
225
- # expect that it loses much of its competetive advantage when
251
+ # expect that it loses much of its competitive advantage when
226
252
  # compared to an R-tree rebuild.
227
253
  def update!
228
254
  super
@@ -241,7 +267,7 @@ class RTree < RTreeC
241
267
  end
242
268
 
243
269
  # Serialise to JSON stream
244
- # @param io [IO] a writeable stream
270
+ # @param io [IO] a writable stream
245
271
  # @return [self]
246
272
  # @see .json_read
247
273
  # @example Write to file
@@ -251,7 +277,7 @@ class RTree < RTreeC
251
277
  end
252
278
 
253
279
  # Serialise to BSRT (binary serialised R-tree) stream
254
- # @param io [IO] a writeable stream
280
+ # @param io [IO] a writable stream
255
281
  # @return [self]
256
282
  # @see .bsrt_read
257
283
  # @example Write to file
@@ -281,7 +307,7 @@ class RTree < RTreeC
281
307
  end
282
308
 
283
309
  # Equality of RTrees. This is a rather strict equality,
284
- # not only must the tree have the same rectangkes, they
310
+ # not only must the tree have the same rectangles, they
285
311
  # must be in the same order. Certainly {#clone} will produce
286
312
  # an instance which is equal in this sense.
287
313
  # @return [Boolean] true if the instances are identical
@@ -291,6 +317,52 @@ class RTree < RTreeC
291
317
 
292
318
  alias_method(:==, :eq?)
293
319
 
320
+ # @return [Integer] the dimension of the R-tree
321
+ def dim
322
+ super
323
+ end
324
+
325
+ # @return [Integer] the total bytes allocated for the instance
326
+ # @note This method traverses the entire tree summing the
327
+ # contributions for each node (rather than maintaining a
328
+ # running count). Performance-minded users may wish to
329
+ # cache this value (invalidating the cache when calling
330
+ # {#add_rect} of course).
331
+ def size
332
+ super
333
+ end
334
+
335
+ # @return [Integer] the bytes in a page of memory
336
+ def page_size
337
+ super
338
+ end
339
+
340
+ # @return [Integer] the size in bytes of a node
341
+ def node_size
342
+ super
343
+ end
344
+
345
+ # @return [Integer] the size in bytes of a rectangle
346
+ def rect_size
347
+ super
348
+ end
349
+
350
+ # @return [Integer] the size in bytes of a branch
351
+ def branch_size
352
+ super
353
+ end
354
+
355
+ # @return [Integer] the number of branches from each node
356
+ def branching_factor
357
+ super
358
+ end
359
+
360
+ # @return [Float] the volume of the unit sphere in the R-tree's
361
+ # dimension
362
+ def unit_sphere_volume
363
+ super
364
+ end
365
+
294
366
  private
295
367
 
296
368
  attr_reader :split, :node_page
@@ -323,6 +395,7 @@ class RTree < RTreeC
323
395
  result
324
396
  end
325
397
 
398
+
326
399
  end
327
400
 
328
401
  require 'rtree/rtree'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: librtree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - J.J. Green
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-17 00:00:00.000000000 Z
11
+ date: 2021-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -95,8 +95,8 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1'
97
97
  description: |
98
- A Ruby native extension for librtree implementing the R-tree
99
- spatial-index of Guttman-Green.
98
+ A Ruby extension implementing the R-tree spatial-index of
99
+ Guttman-Green.
100
100
  email: j.j.green@gmx.co.uk
101
101
  executables: []
102
102
  extensions:
@@ -119,14 +119,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
119
  requirements:
120
120
  - - ">="
121
121
  - !ruby/object:Gem::Version
122
- version: '0'
122
+ version: '2.0'
123
123
  required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  requirements:
125
125
  - - ">="
126
126
  - !ruby/object:Gem::Version
127
127
  version: '0'
128
128
  requirements:
129
- - The librtree library
129
+ - The librtree library (1.0.5 or later)
130
130
  rubygems_version: 3.1.2
131
131
  signing_key:
132
132
  specification_version: 4