librtree 0.8.1 → 0.8.6

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: 126a8974cacf26f7c8603d161d4d7de0c121abdf5a0bc45b8244178156cbdca7
4
- data.tar.gz: 1dd3115fb8a2eb08dd5a8968ad201978b2a956dde48e210cf648027365d91fa9
3
+ metadata.gz: ad62e4e446f6fb4571d33f6498bf9df26d5b360a0325cde40ead187ebcb0be04
4
+ data.tar.gz: d462f690013c36933961206659026af7fe9b50ea6d23198f15a0965247390192
5
5
  SHA512:
6
- metadata.gz: 148bffff79b038c562620bd583f6437bced0426af7210a3a289023162634f681ef1579b523cab78a6ef057be07075868b3e49b06cc48bc4747fdedfd2d0380d8
7
- data.tar.gz: 375703fbd60f42cf8722188c6fd654bcbc7ceec5886b19705c5993140fb0973a7c68c14df89e8255cef467e13c586579e94691557847ad5b6168bbfb80075eb5
6
+ metadata.gz: 19e997efe8519f2db02e10f69f8d60af57c376e9a6de7f38bc8f3613cbd8287800e096816f1c37361c122c0a7c99e41bd97f7842ddebdf0357395e31a666739b
7
+ data.tar.gz: bf1911bade3fcba763aee1f4a451dd9638f8e9c3b06577482b09bc134942282d031538d8a436ee161ec4334c7f2dfdadfcf8ac1349dc3d32b053c69390e5eb7f
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,7 +408,21 @@ 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);
425
+ rb_define_const(cls, "SPLIT_QUADRATIC", INT2NUM(RTREE_SPLIT_QUADRATIC));
426
+ rb_define_const(cls, "SPLIT_LINEAR", INT2NUM(RTREE_SPLIT_LINEAR));
427
+ rb_define_const(cls, "SPLIT_GREENE", INT2NUM(RTREE_SPLIT_GREENE));
362
428
  }
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
@@ -96,7 +96,7 @@ class RTree < RTreeC
96
96
  # Build a new RTree instance from CSV stream
97
97
  # @param io [IO] a readable stream object
98
98
  # @param dim [Integer] the dimension of the tree
99
- # @param split [:linear, :quadratic] See {#initialize}
99
+ # @param split [:linear, :quadratic, :greene] See {#initialize}
100
100
  # @param node_page [Integer] See {#initialize}
101
101
  # @return [RTree] the newly built RTree
102
102
  # @note The CSV file (without header) should have the id in the
@@ -120,13 +120,30 @@ class RTree < RTreeC
120
120
  end
121
121
  end
122
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
+
123
138
  # @!visibility private
124
139
  def split_flag(split)
125
140
  case split
126
141
  when :quadratic
127
- 0
142
+ self::SPLIT_QUADRATIC
128
143
  when :linear
129
- 1
144
+ self::SPLIT_LINEAR
145
+ when :greene
146
+ self::SPLIT_GREENE
130
147
  else
131
148
  raise ArgumentError, "bad split value: #{split}"
132
149
  end
@@ -165,9 +182,10 @@ class RTree < RTreeC
165
182
 
166
183
  # Initialize a new (empty) RTree
167
184
  # @param dim [Integer] the dimension of the tree
168
- # @param split [:linear, :quadratic] determines the splitting strategy,
169
- # the linear strategy is faster to build, the quadratic produces a
170
- # better-quality R-tree which is faster to query.
185
+ # @param split [:linear, :quadratic, :greene] determines the splitting
186
+ # strategy, the linear strategy is faster to build, the quadratic
187
+ # and greene strategies produces a better-quality R-trees which is
188
+ # faster to query.
171
189
  # @param node_page [Integer] the nodes-per-page value. This value can
172
190
  # affect performance quite dramatically, particularly build time. A
173
191
  # value which is too large would result in an infeasible branching
@@ -233,7 +251,7 @@ class RTree < RTreeC
233
251
  # is much faster than rebuilding the R-tree; in this Ruby interface
234
252
  # the callback must convert C floats to Ruby, yield them to the
235
253
  # block and then convert the returned Ruby Floats to C; so we would
236
- # expect that it loses much of its competetive advantage when
254
+ # expect that it loses much of its competitive advantage when
237
255
  # compared to an R-tree rebuild.
238
256
  def update!
239
257
  super
@@ -252,7 +270,7 @@ class RTree < RTreeC
252
270
  end
253
271
 
254
272
  # Serialise to JSON stream
255
- # @param io [IO] a writeable stream
273
+ # @param io [IO] a writable stream
256
274
  # @return [self]
257
275
  # @see .json_read
258
276
  # @example Write to file
@@ -262,7 +280,7 @@ class RTree < RTreeC
262
280
  end
263
281
 
264
282
  # Serialise to BSRT (binary serialised R-tree) stream
265
- # @param io [IO] a writeable stream
283
+ # @param io [IO] a writable stream
266
284
  # @return [self]
267
285
  # @see .bsrt_read
268
286
  # @example Write to file
@@ -292,7 +310,7 @@ class RTree < RTreeC
292
310
  end
293
311
 
294
312
  # Equality of RTrees. This is a rather strict equality,
295
- # not only must the tree have the same rectangkes, they
313
+ # not only must the tree have the same rectangles, they
296
314
  # must be in the same order. Certainly {#clone} will produce
297
315
  # an instance which is equal in this sense.
298
316
  # @return [Boolean] true if the instances are identical
@@ -302,6 +320,52 @@ class RTree < RTreeC
302
320
 
303
321
  alias_method(:==, :eq?)
304
322
 
323
+ # @return [Integer] the dimension of the R-tree
324
+ def dim
325
+ super
326
+ end
327
+
328
+ # @return [Integer] the total bytes allocated for the instance
329
+ # @note This method traverses the entire tree summing the
330
+ # contributions for each node (rather than maintaining a
331
+ # running count). Performance-minded users may wish to
332
+ # cache this value (invalidating the cache when calling
333
+ # {#add_rect} of course).
334
+ def size
335
+ super
336
+ end
337
+
338
+ # @return [Integer] the bytes in a page of memory
339
+ def page_size
340
+ super
341
+ end
342
+
343
+ # @return [Integer] the size in bytes of a node
344
+ def node_size
345
+ super
346
+ end
347
+
348
+ # @return [Integer] the size in bytes of a rectangle
349
+ def rect_size
350
+ super
351
+ end
352
+
353
+ # @return [Integer] the size in bytes of a branch
354
+ def branch_size
355
+ super
356
+ end
357
+
358
+ # @return [Integer] the number of branches from each node
359
+ def branching_factor
360
+ super
361
+ end
362
+
363
+ # @return [Float] the volume of the unit sphere in the R-tree's
364
+ # dimension
365
+ def unit_sphere_volume
366
+ super
367
+ end
368
+
305
369
  private
306
370
 
307
371
  attr_reader :split, :node_page
@@ -334,6 +398,7 @@ class RTree < RTreeC
334
398
  result
335
399
  end
336
400
 
401
+
337
402
  end
338
403
 
339
404
  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.1
4
+ version: 0.8.6
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-19 00:00:00.000000000 Z
11
+ date: 2021-06-17 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 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.6 or later)
130
130
  rubygems_version: 3.1.2
131
131
  signing_key:
132
132
  specification_version: 4