librtree 0.8.1 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
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