librtree 0.9.1 → 1.0.1

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +80 -0
  3. data/COPYING +21 -0
  4. data/README.md +87 -0
  5. data/ext/rtree/extconf.rb +37 -19
  6. data/ext/rtree/lib/README.md +9 -0
  7. data/ext/rtree/lib/bindex.c +157 -0
  8. data/ext/rtree/lib/bindex.h +31 -0
  9. data/ext/rtree/lib/bounds.h +21 -0
  10. data/ext/rtree/lib/branch.c +51 -0
  11. data/ext/rtree/lib/branches.c +17 -0
  12. data/ext/rtree/lib/bsrt.c +704 -0
  13. data/ext/rtree/lib/bsrt.h +16 -0
  14. data/ext/rtree/lib/constants.h +19 -0
  15. data/ext/rtree/lib/csv.c +81 -0
  16. data/ext/rtree/lib/csv.h +16 -0
  17. data/ext/rtree/lib/endianness.h +83 -0
  18. data/ext/rtree/lib/error.c +47 -0
  19. data/ext/rtree/lib/json.c +491 -0
  20. data/ext/rtree/lib/json.h +16 -0
  21. data/ext/rtree/lib/mk/Hdr.mk +3 -0
  22. data/ext/rtree/lib/mk/MakeDepend +25 -0
  23. data/ext/rtree/lib/mk/Obj.mk +3 -0
  24. data/ext/rtree/lib/node.c +736 -0
  25. data/ext/rtree/lib/package.c +11 -0
  26. data/ext/rtree/lib/page.c +47 -0
  27. data/ext/rtree/lib/page.h +13 -0
  28. data/ext/rtree/lib/postscript.c +543 -0
  29. data/ext/rtree/lib/rect.c +139 -0
  30. data/ext/rtree/lib/rectf.c +219 -0
  31. data/ext/rtree/lib/rtree/branch.h +105 -0
  32. data/ext/rtree/lib/rtree/branches.h +38 -0
  33. data/ext/rtree/lib/rtree/error.h +42 -0
  34. data/ext/rtree/lib/rtree/extent.h +20 -0
  35. data/ext/rtree/lib/rtree/node.h +96 -0
  36. data/ext/rtree/lib/rtree/package.h +14 -0
  37. data/ext/rtree/lib/rtree/postscript.h +66 -0
  38. data/ext/rtree/lib/rtree/rect.h +38 -0
  39. data/ext/rtree/lib/rtree/rectf.h +34 -0
  40. data/ext/rtree/lib/rtree/search.h +27 -0
  41. data/ext/rtree/lib/rtree/state.h +113 -0
  42. data/ext/rtree/lib/rtree/types.h +14 -0
  43. data/ext/rtree/lib/rtree-base.c +197 -0
  44. data/ext/rtree/lib/rtree.h +62 -0
  45. data/ext/rtree/lib/search.c +54 -0
  46. data/ext/rtree/lib/split.c +710 -0
  47. data/ext/rtree/lib/split.h +15 -0
  48. data/ext/rtree/lib/spvol.c +48 -0
  49. data/ext/rtree/lib/spvol.h +13 -0
  50. data/ext/rtree/lib/state.c +169 -0
  51. data/ext/rtree/rtree.c +11 -0
  52. data/lib/rtree.rb +4 -4
  53. metadata +65 -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: 7dbcdf3078b84e506da1a5afb4e0f31db7490ef8b57860c3d670dae5422bb283
4
+ data.tar.gz: 9c63a1227bbf656f12360acda82a0f7a7c369d27a25ae1352c906af769f5c2d3
5
5
  SHA512:
6
- metadata.gz: f96d9eb0c8d21ef03a8d716f544ec34d84dabe4f598e606af99184e7cfb951c5a80f55e058b0d20ebafd4d2f173bae76bf230fac8489d8e71cbbe2a57c5170fa
7
- data.tar.gz: cd2d89976e36b6c0aadf7b0d95c823c4f39869d480886746aa8e1f2a402bdaf7e9f7e0b87695beacd75aad7655bfeaa8b65bca11fed80e9a15464de854da3a94
6
+ metadata.gz: 6c54dae2e5b2e4601c6730fd7e3d50e7f87c5af3a067b7b9c2167c8f43c8c43d52429f7db18db17116cfc958f54587b7009ee92a69d59843048ca53b6b422878
7
+ data.tar.gz: 1c9aa746ba96bd5413add8a1629a2c84da513e0ed5467d553a10dcfe6f2c776b15d9dd45afac3ff2a33b6cef40633bc7937bffceb0f877c7c03f30ac34bdd8eb
data/CHANGELOG.md ADDED
@@ -0,0 +1,80 @@
1
+ Changelog
2
+ ---------
3
+
4
+ ### 1.0.1, 16-03-2023
5
+
6
+ - Update to 1.1.4 of embedded `librtree`
7
+ - The `#empty?` method uses faster `rtree_empty` of the latest
8
+ version of the embedded library
9
+ - Added the `simplecov` gem and configured (Ruby) coverage in
10
+ CI runs
11
+
12
+ ### 1.0.0, 24-02-2023
13
+
14
+ - The `librtree` library is no longer a requirement: the code
15
+ for the library is it is embedded in the gem itself
16
+
17
+ ### 0.9.1, 21-01-2023
18
+
19
+ - Tidying
20
+ - Fix warning "undefining the allocator of T_DATA class" on
21
+ Ruby 3,2
22
+ - No functional changes
23
+
24
+ ### 0.9.0, 07-11-2021
25
+
26
+ - Code reorganisation
27
+ - RuboCop style fixes
28
+ - No functional changes
29
+
30
+ ### 0.8.9, 24-08-2021
31
+
32
+ - Unset `O_NONBLOCK` on `IO.pipe` readers, to allow the gem to
33
+ work with Ruby 3
34
+
35
+ ### 0.8.8, 14-07-2021
36
+
37
+ - De-nest C base-class for neater documentation
38
+ - Adopt "standard" naming-convention for the benfit of Yard
39
+ introspection
40
+ - No functional changes
41
+
42
+ ### 0.8.7, 24-06-2021
43
+
44
+ - Added the `#postscript` method, for plotting
45
+
46
+ ### 0.8.6, 17-06-2021
47
+
48
+ - Support for the Greene-split of librtree 1.0.6
49
+
50
+ ### 0.8.5, 13-06-2021
51
+
52
+ - Removed check for `libcsv`, needs librtee version 1.0.5
53
+
54
+ ### 0.8.4, 24-05-2021
55
+
56
+ - Replace deprecated `Data_*_Struct` API functions
57
+ - Implement the `version`, `bugreport`, `url` class methods
58
+ - Add `dsize` to the base `rb_data_type_t` struct (using a call to
59
+ the C `rtree_bytes` function introduced in librtree 1.0.3)
60
+ - Add the `#size` methods using the same C function
61
+
62
+ ### 0.8.3, 23-05-2021
63
+
64
+ - Fix a memory leak
65
+ - C code uses `Data_Wrap_Struct` rather than `Data_Make_Struct`,
66
+ this needs librtree version at least 1.0.2
67
+
68
+ ### 0.8.2, 22-05-2021
69
+
70
+ - Added a number of read-accessors for the R-tree state
71
+
72
+ ### 0.8.1, 19-05-2021
73
+
74
+ - Added changelog
75
+ - Updated user documentation
76
+ - No code changes
77
+
78
+ ### 0.8.0, 17-05-2021
79
+
80
+ - 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,87 @@
1
+ librtree-ruby
2
+ -------------
3
+
4
+ A Ruby native extension implementing the R-tree spatial index of
5
+ Guttman-Green. The code is an embedded version of [librtree][3].
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 as above. Then clone the repository and
51
+ install the extension's Ruby dependencies, there are several ways to do
52
+ this.
53
+
54
+ If using [rbenv][4], then first set a local version of Ruby to use,
55
+ 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
+
84
+ [1]: http://www.digip.org/jansson/
85
+ [3]: http://soliton.vm.bytemark.co.uk/pub/jjg/en/code/librtree/
86
+ [4]: https://github.com/rbenv/rbenv
87
+ [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,9 @@
1
+ Embedded librtree
2
+ -----------------
3
+
4
+ The code in this directory is largely generated by the script
5
+ `bin/librtee-update`, one should not edit it directly, instead
6
+ make a clone of the [librtree][1] project, modify that and use
7
+ the update-script to copy the results here.
8
+
9
+ [1]: https://gitlab.com/jjg/librtree
@@ -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*);