librtree 0.9.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -0
  3. data/COPYING +21 -0
  4. data/README.md +86 -0
  5. data/ext/rtree/extconf.rb +37 -19
  6. data/ext/rtree/lib/bindex.c +157 -0
  7. data/ext/rtree/lib/bindex.h +31 -0
  8. data/ext/rtree/lib/bounds.h +21 -0
  9. data/ext/rtree/lib/branch.c +51 -0
  10. data/ext/rtree/lib/branches.c +17 -0
  11. data/ext/rtree/lib/bsrt.c +704 -0
  12. data/ext/rtree/lib/bsrt.h +16 -0
  13. data/ext/rtree/lib/constants.h +19 -0
  14. data/ext/rtree/lib/csv.c +81 -0
  15. data/ext/rtree/lib/csv.h +16 -0
  16. data/ext/rtree/lib/endianness.h +83 -0
  17. data/ext/rtree/lib/error.c +47 -0
  18. data/ext/rtree/lib/json.c +491 -0
  19. data/ext/rtree/lib/json.h +16 -0
  20. data/ext/rtree/lib/mk/Hdr.mk +3 -0
  21. data/ext/rtree/lib/mk/MakeDepend +25 -0
  22. data/ext/rtree/lib/mk/Obj.mk +3 -0
  23. data/ext/rtree/lib/node.c +708 -0
  24. data/ext/rtree/lib/package.c +11 -0
  25. data/ext/rtree/lib/page.c +47 -0
  26. data/ext/rtree/lib/page.h +13 -0
  27. data/ext/rtree/lib/postscript.c +543 -0
  28. data/ext/rtree/lib/rect.c +139 -0
  29. data/ext/rtree/lib/rectf.c +219 -0
  30. data/ext/rtree/lib/rtree/branch.h +105 -0
  31. data/ext/rtree/lib/rtree/branches.h +38 -0
  32. data/ext/rtree/lib/rtree/error.h +42 -0
  33. data/ext/rtree/lib/rtree/extent.h +20 -0
  34. data/ext/rtree/lib/rtree/node.h +92 -0
  35. data/ext/rtree/lib/rtree/package.h +14 -0
  36. data/ext/rtree/lib/rtree/postscript.h +66 -0
  37. data/ext/rtree/lib/rtree/rect.h +38 -0
  38. data/ext/rtree/lib/rtree/rectf.h +34 -0
  39. data/ext/rtree/lib/rtree/search.h +27 -0
  40. data/ext/rtree/lib/rtree/state.h +113 -0
  41. data/ext/rtree/lib/rtree/types.h +14 -0
  42. data/ext/rtree/lib/rtree-base.c +190 -0
  43. data/ext/rtree/lib/rtree.h +61 -0
  44. data/ext/rtree/lib/search.c +54 -0
  45. data/ext/rtree/lib/split.c +710 -0
  46. data/ext/rtree/lib/split.h +15 -0
  47. data/ext/rtree/lib/spvol.c +48 -0
  48. data/ext/rtree/lib/spvol.h +13 -0
  49. data/ext/rtree/lib/state.c +169 -0
  50. metadata +50 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ea7105c3090ca70b99cec081b01ed6f46490208e79ee6ecdaf9045b827280ca
4
- data.tar.gz: 7071f07e2e9ced00f34d48764e229057a9b69cec6e57b003babc27b5577e5372
3
+ metadata.gz: f4cc8665ba0560f3258c4857556efa67195cc699915adc9d2297a78d0f41c3cc
4
+ data.tar.gz: 1b20b6f067a37c4f3265c9f9d7084d4736a8367aa05613e075a4589ba1dc0259
5
5
  SHA512:
6
- metadata.gz: f96d9eb0c8d21ef03a8d716f544ec34d84dabe4f598e606af99184e7cfb951c5a80f55e058b0d20ebafd4d2f173bae76bf230fac8489d8e71cbbe2a57c5170fa
7
- data.tar.gz: cd2d89976e36b6c0aadf7b0d95c823c4f39869d480886746aa8e1f2a402bdaf7e9f7e0b87695beacd75aad7655bfeaa8b65bca11fed80e9a15464de854da3a94
6
+ metadata.gz: c0ae30faf7cba617f9ab96be3d9ec5325505a9b97b9591fc64bcbd8e2de327def4bca47386992c80f6c1d6021211cdd660ca10cfa1ed8f75d82b67cc6a33f1a0
7
+ data.tar.gz: d561ecb375d69cb78a1f2681c43e430692c4f191bc9555cd317e8b0b76d726740154aa2befb6bdc9f35aa56adf0686c5030593ac81fff9fc3ce167ecdd9eeef4
data/CHANGELOG.md ADDED
@@ -0,0 +1,72 @@
1
+ Changelog
2
+ ---------
3
+
4
+ ### 1.0.0, 24-02-2023
5
+
6
+ - The `librtree` library is no longer a requirement: the code
7
+ for the library is it is embedded in the gem itself
8
+
9
+ ### 0.9.1, 21-01-2023
10
+
11
+ - Tidying
12
+ - Fix warning "undefining the allocator of T_DATA class" on
13
+ Ruby 3,2
14
+ - No functional changes
15
+
16
+ ### 0.9.0, 07-11-2021
17
+
18
+ - Code reorganisation
19
+ - RuboCop style fixes
20
+ - No functional changes
21
+
22
+ ### 0.8.9, 24-08-2021
23
+
24
+ - Unset `O_NONBLOCK` on `IO.pipe` readers, to allow the gem to
25
+ work with Ruby 3
26
+
27
+ ### 0.8.8, 14-07-2021
28
+
29
+ - De-nest C base-class for neater documentation
30
+ - Adopt "standard" naming-convention for the benfit of Yard
31
+ introspection
32
+ - No functional changes
33
+
34
+ ### 0.8.7, 24-06-2021
35
+
36
+ - Added the `#postscript` method, for plotting
37
+
38
+ ### 0.8.6, 17-06-2021
39
+
40
+ - Support for the Greene-split of librtree 1.0.6
41
+
42
+ ### 0.8.5, 13-06-2021
43
+
44
+ - Removed check for `libcsv`, needs librtee version 1.0.5
45
+
46
+ ### 0.8.4, 24-05-2021
47
+
48
+ - Replace deprecated `Data_*_Struct` API functions
49
+ - Implement the `version`, `bugreport`, `url` class methods
50
+ - Add `dsize` to the base `rb_data_type_t` struct (using a call to
51
+ the C `rtree_bytes` function introduced in librtree 1.0.3)
52
+ - Add the `#size` methods using the same C function
53
+
54
+ ### 0.8.3, 23-05-2021
55
+
56
+ - Fix a memory leak
57
+ - C code uses `Data_Wrap_Struct` rather than `Data_Make_Struct`,
58
+ this needs librtree version at least 1.0.2
59
+
60
+ ### 0.8.2, 22-05-2021
61
+
62
+ - Added a number of read-accessors for the R-tree state
63
+
64
+ ### 0.8.1, 19-05-2021
65
+
66
+ - Added changelog
67
+ - Updated user documentation
68
+ - No code changes
69
+
70
+ ### 0.8.0, 17-05-2021
71
+
72
+ - First public release
data/COPYING ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 J.J. Green
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ librtree-ruby
2
+ -------------
3
+
4
+ A Ruby native extension for [librtree][3] implementing the R-tree
5
+ spatial index of Guttman-Green.
6
+
7
+
8
+ ### Installing dependencies
9
+
10
+ Just [jansson][1]: this common library may be in your operating-system's
11
+ repositories. On Debian, Ubuntu and derivatives:
12
+
13
+ apt-get install libjansson-dev
14
+
15
+ On RedHat, CentOS:
16
+
17
+ yum install jansson-devel
18
+
19
+ On OSX:
20
+
21
+ brew install jansson
22
+
23
+ One does not need to install `librtree` itself, the library-code is
24
+ embedded within the gem (as of version 1.0.0).
25
+
26
+
27
+ ### Install the Gem
28
+
29
+ Add
30
+
31
+ gem 'librtree'
32
+
33
+ to your project's `Gemfile` and run `bundle install`.
34
+
35
+
36
+ ### Use the RTree class
37
+
38
+ In your Ruby code
39
+
40
+ require 'rtree'
41
+
42
+ will import the **RTree** class, its usage is described [here][5].
43
+
44
+
45
+ ### Development setup
46
+
47
+ This is only needed if you want work on the extension, not for
48
+ a Gem install.
49
+
50
+ First install the dependencies and [librtree][3] as above. Then
51
+ clone the repository and install the extension's Ruby dependencies,
52
+ there are several ways to do this.
53
+
54
+ If using [rbenv][4], then first set a local version of Ruby to
55
+ use, then install the gems into your local cache
56
+
57
+ rbenv local 2.7.0
58
+ bundle install
59
+
60
+ The repository's `.gitignore` ignores **rbenv**'s `.ruby-version`
61
+ file, since we don't want to mandate a particular Ruby version
62
+ for the package.
63
+
64
+ If not using **rbenv** then just
65
+
66
+ bundle install
67
+
68
+ should attempt to install the gems into your system location, which
69
+ will typically require `sudo`. If you don't want to (or cannot) do
70
+ this, then
71
+
72
+ bundle install --path vendor/bundle
73
+
74
+ will install into `vendor` and set the location in `.bundle/config`,
75
+ both of these are ignored by the repository's Git configuration.
76
+
77
+ Finally, you should be in a position to compile the package and
78
+ run the tests:
79
+
80
+ bundle exec rake compile
81
+ bundle exec rake spec
82
+
83
+ [1]: http://www.digip.org/jansson/
84
+ [3]: http://soliton.vm.bytemark.co.uk/pub/jjg/en/code/librtree/
85
+ [4]: https://github.com/rbenv/rbenv
86
+ [5]: https://www.rubydoc.info/gems/librtree/RTree
data/ext/rtree/extconf.rb CHANGED
@@ -1,27 +1,45 @@
1
1
  require 'mkmf'
2
2
 
3
- $CFLAGS << ' -std=c99'
3
+ $VPATH << "$(srcdir)/lib"
4
+ $srcs =
5
+ Dir.glob("#{$srcdir}/{,lib/}*.c")
6
+ .map { |path| File.basename(path) }
7
+ .sort
4
8
 
5
- INCLUDEDIR = RbConfig::CONFIG['includedir']
6
- HEADER_DIRS = [
7
- '/usr/local/include',
8
- INCLUDEDIR,
9
- '/usr/include',
10
- ]
9
+ append_cppflags('-I$(srcdir)/lib')
10
+ append_cppflags('-DHAVE_CONFIG_H')
11
11
 
12
- LIBDIR = RbConfig::CONFIG['libdir']
13
- LIB_DIRS = [
14
- '/usr/local/lib',
15
- LIBDIR,
16
- '/usr/lib'
17
- ]
12
+ check_sizeof('rtree_coord_t', 'rtree/types.h')
13
+ check_sizeof('rtree_id_t', 'rtree/types.h')
18
14
 
19
- dir_config('librtree', HEADER_DIRS, LIB_DIRS)
15
+ if have_header('endian.h') ||
16
+ have_header('sys/endian.h') ||
17
+ have_header('libkern/OSByteOrder.h') ||
18
+ have_header('winsock2.h')
19
+ then
20
+ append_cflags("-DWITH_BSRT")
21
+ else
22
+ warn('cannot determine endianness, no BSRT support')
23
+ end
20
24
 
21
- abort 'missing jansson.h' unless find_header('jansson.h')
22
- abort 'missing rtree.h' unless find_header('rtree.h')
25
+ if have_header('jansson.h') &&
26
+ have_library('jansson', 'json_pack')
27
+ then
28
+ append_cflags("-DWITH_JSON")
29
+ else
30
+ warn('cannot find jansson, no JSON support')
31
+ end
23
32
 
24
- abort 'libjansson is missing' unless find_library('jansson', 'json_pack')
25
- abort 'librtree is missing' unless find_library('rtree', 'rtree_new')
33
+ unless have_header('unistd.h') &&
34
+ (
35
+ have_func('sysconf', 'unistd.h') ||
36
+ have_func('getpagesize', 'unistd.h')
37
+ )
38
+ then
39
+ warn('cannot find page-size functions, will guess')
40
+ end
26
41
 
27
- create_makefile 'rtree/rtree'
42
+ have_header('features.h')
43
+
44
+ create_header('config.h')
45
+ create_makefile("rtree")
@@ -0,0 +1,157 @@
1
+ /*
2
+ An array of binary values which are to be used as indexes
3
+ for an array; so we can store each value in a bit, but the
4
+ functions return size_t (since the array-index type)
5
+ */
6
+
7
+ #ifdef HAVE_CONFIG_H
8
+ #include "config.h"
9
+ #endif
10
+
11
+ #include "bindex.h"
12
+ #include "rtree/error.h"
13
+
14
+ #include <errno.h>
15
+ #include <stdlib.h>
16
+ #include <stdalign.h>
17
+ #include <string.h>
18
+
19
+ #define UL_BYTES sizeof(unsigned long)
20
+ #define UL_BITS (UL_BYTES << 3)
21
+
22
+ /* see note on branch_sizeof in branch.c */
23
+
24
+ static size_t bindex_sizeof(size_t n)
25
+ {
26
+ const size_t s = offsetof(bindex_t, word) + n * UL_BYTES;
27
+ return ((s - 1) / alignof(bindex_t) + 1) * alignof(bindex_t);
28
+ }
29
+
30
+ bindex_t* bindex_new(size_t n)
31
+ {
32
+ size_t k = n / UL_BITS + 1;
33
+ bindex_t *bindex;
34
+
35
+ if ((bindex = malloc(bindex_sizeof(k))) != NULL)
36
+ {
37
+ bindex->n = n;
38
+ memset(bindex->word, 0, k * UL_BYTES);
39
+ return bindex;
40
+ }
41
+
42
+ return NULL;
43
+ }
44
+
45
+ void bindex_destroy(bindex_t *bindex)
46
+ {
47
+ free(bindex);
48
+ }
49
+
50
+ static size_t first_unset(const unsigned long *words, size_t n_bits)
51
+ {
52
+ size_t n_words = n_bits / UL_BITS + 1;
53
+
54
+ for (size_t j = 0 ; j < n_words ; j++)
55
+ {
56
+ unsigned long word = ~words[j];
57
+
58
+ if (word)
59
+ {
60
+
61
+ #ifdef HAVE___BUILTIN_CTZL
62
+
63
+ return j * UL_BITS + __builtin_ctzl(word);
64
+
65
+ #else
66
+
67
+ for (size_t k = 0 ; k < UL_BITS ; k++)
68
+ {
69
+ if (1UL & (word >> k))
70
+ return j * UL_BITS + k;
71
+ }
72
+ #endif
73
+ }
74
+ }
75
+
76
+ return n_bits;
77
+ }
78
+
79
+ static size_t next_unset(const unsigned long *words, size_t n_bits, size_t i)
80
+ {
81
+ if (i < n_bits)
82
+ {
83
+ size_t
84
+ j0 = i / UL_BITS,
85
+ k0 = i % UL_BITS;
86
+ unsigned long word;
87
+
88
+ #ifdef HAVE___BUILTIN_CTZL
89
+
90
+ if ((word = ~words[j0] >> k0) != 0UL)
91
+ return j0 * UL_BITS + __builtin_ctzl(word) + k0;
92
+
93
+ #else
94
+
95
+ if ((word = ~words[j0]) != 0UL)
96
+ {
97
+ for (size_t k = k0 ; k < UL_BITS ; k++)
98
+ {
99
+ if (1UL & (word >> k))
100
+ return j0 * UL_BITS + k;
101
+ }
102
+ }
103
+
104
+ #endif
105
+
106
+ size_t j1 = j0 + 1;
107
+
108
+ return first_unset(words + j1, n_bits - j1 * UL_BITS) + j1 * UL_BITS;
109
+ }
110
+
111
+ return n_bits;
112
+ }
113
+
114
+ size_t bindex_first_unset(const bindex_t *bindex)
115
+ {
116
+ return first_unset(bindex->word, bindex->n);
117
+ }
118
+
119
+ size_t bindex_next_unset(const bindex_t *bindex, size_t i)
120
+ {
121
+ return next_unset(bindex->word, bindex->n, i);
122
+ }
123
+
124
+ size_t bindex_get(const bindex_t *bindex, size_t i)
125
+ {
126
+ if (i >= bindex->n)
127
+ {
128
+ errno = EDOM;
129
+ return 0;
130
+ }
131
+
132
+ size_t
133
+ j = i / UL_BITS,
134
+ k = i % UL_BITS;
135
+
136
+ return 1UL & (bindex->word[j] >> k);
137
+ }
138
+
139
+ int bindex_set(bindex_t *bindex, size_t i, size_t v)
140
+ {
141
+ if (v > 1)
142
+ return RTREE_ERR_INVAL;
143
+
144
+ if (i >= bindex->n)
145
+ return RTREE_ERR_DOM;
146
+
147
+ size_t
148
+ j = i / UL_BITS,
149
+ k = i % UL_BITS;
150
+
151
+ if (v)
152
+ bindex->word[j] |= (1UL << k);
153
+ else
154
+ bindex->word[j] &= ~(1UL << k);
155
+
156
+ return 0;
157
+ }
@@ -0,0 +1,31 @@
1
+ /*
2
+ bindex.h
3
+ Copyright (c) J.J. Green 2020
4
+ */
5
+
6
+ #ifndef BINDEX_H
7
+ #define BINDEX_H
8
+
9
+ #ifdef HAVE_CONFIG_H
10
+ #include "config.h"
11
+ #endif
12
+
13
+ #include <stddef.h>
14
+
15
+ typedef struct
16
+ {
17
+ size_t n;
18
+ unsigned long word[];
19
+ } bindex_t;
20
+
21
+ bindex_t* bindex_new(size_t);
22
+ void bindex_destroy(bindex_t*);
23
+
24
+ size_t bindex_get(const bindex_t*, size_t);
25
+ int bindex_set(bindex_t*, size_t, size_t);
26
+
27
+ size_t bindex_first_unset(const bindex_t*);
28
+ size_t bindex_next_unset(const bindex_t*, size_t);
29
+
30
+
31
+ #endif
@@ -0,0 +1,21 @@
1
+ /*
2
+ bounds.h
3
+ Copyright (c) J.J. Green 2022
4
+ */
5
+
6
+ #ifndef BOUNDS_H
7
+ #define BOUNDS_H
8
+
9
+ #ifndef RTREE_DIMS_MAX
10
+ #define RTREE_DIMS_MAX 256
11
+ #endif
12
+
13
+ #ifndef RTREE_LEVELS_MAX
14
+ #define RTREE_LEVELS_MAX 1024
15
+ #endif
16
+
17
+ #ifndef RTREE_BRANCHES_MAX
18
+ #define RTREE_BRANCHES_MAX 4096
19
+ #endif
20
+
21
+ #endif
@@ -0,0 +1,51 @@
1
+ #ifdef HAVE_CONFIG_H
2
+ #include "config.h"
3
+ #endif
4
+
5
+ #include "rtree/branch.h"
6
+
7
+ #include <stddef.h>
8
+ #include <stdalign.h>
9
+ #include <string.h>
10
+
11
+ /*
12
+ The size of branch_t with n rect elements, with padding taken into
13
+ account: kindly provided by Eric Postpischil in the stackoverflow
14
+ question https://stackoverflow.com/questions/59435697/
15
+
16
+ Atypically this takes the total number of rect elements (so 2 * dims)
17
+ rather than the state, this is because it is used in state_new().
18
+ */
19
+
20
+ size_t branch_sizeof(size_t n)
21
+ {
22
+ const size_t s = offsetof(branch_t, rect) + n * sizeof(rtree_coord_t);
23
+ return ((s - 1) / alignof(branch_t) + 1) * alignof(branch_t);
24
+ }
25
+
26
+ int branch_init(const state_t *state, branch_t *branch)
27
+ {
28
+ branch->child = NULL;
29
+ return rect_init(state, branch->rect);
30
+ }
31
+
32
+ branch_t* branch_copy(const state_t *state,
33
+ const branch_t *src, branch_t *dest)
34
+ {
35
+ const size_t branch_size = state_branch_size(state);
36
+ if ((dest = memcpy(dest, src, branch_size)) == NULL)
37
+ return NULL;
38
+ rect_copy(state, src->rect, dest->rect);
39
+ return dest;
40
+ }
41
+
42
+ /* inline accessors */
43
+
44
+ extern void branch_set_child(branch_t*, node_t*);
45
+ extern const node_t* branch_get_child(const branch_t*);
46
+ extern node_t* branch_get_child_mutable(branch_t*);
47
+ extern void branch_set_id(branch_t*, rtree_id_t);
48
+ extern rtree_id_t branch_get_id(const branch_t*);
49
+ extern void branch_set_rect(const state_t*, branch_t*, const rtree_coord_t*);
50
+ extern const rtree_coord_t* branch_get_rect(const branch_t*);
51
+ extern rtree_coord_t* branch_get_rect_mutable(branch_t*);
@@ -0,0 +1,17 @@
1
+ /*
2
+ The code here is to handle a void* buffer as an array of branch,
3
+ we can't actually create an array of branch since its size is
4
+ not known until runtime, so we have to perform those calculations
5
+ ourselves. Note that we just do the arithmatic here, no error
6
+ checking -- so a over-sized index to branches_get() will lead to
7
+ a memory error, the caller is epected to do this check themselves
8
+ */
9
+
10
+ #ifdef HAVE_CONFIG_H
11
+ #include "config.h"
12
+ #endif
13
+
14
+ #include "rtree/branches.h"
15
+
16
+ extern branch_t* branches_get(const state_t*, void*, size_t);
17
+ extern void branches_set(const state_t*, void*, size_t, const branch_t*);