rbtree3 0.5.0 → 0.6.0
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 +5 -5
- data/ChangeLog +18 -0
- data/rbtree.c +64 -18
- data/test.rb +17 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3234cdc1ff704f6a3d32707f6b0fb740c5a946d42012453b56f186a2231157fc
|
4
|
+
data.tar.gz: 97eeab5707ad178f92fd2261e0209fc37262e9e95f0d75b18f49da1963b2a49d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0863e5d7883566ea6dd6da51e743d3606bdbc9f1dbce105e0f38bb2f60815bc4244691065bf4093cdd474d7b545b996dc25a3171ce114c471fa6108b7b21d2d5'
|
7
|
+
data.tar.gz: 745622af2491d5bdbcded3112c98e2183b1f3716c5a46204274fc0392ff2e5e79b863c03b7ff6f727f4207f13486d0ed82f81b508fad22d00c6b9a74ebb0948f
|
data/ChangeLog
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
2020-01-21 Brian Hawley
|
2
|
+
|
3
|
+
* version 0.6.0 released.
|
4
|
+
|
5
|
+
* test.rb: improved 1.8.7 compatibility
|
6
|
+
|
7
|
+
* rbtree.c: made RBTREE(rbtree) do the type conversion, like RARRAY and
|
8
|
+
such do
|
9
|
+
|
10
|
+
* rbtree.c: Used Data_Make_Struct instead of doing the same thing that
|
11
|
+
it used to do, in order to be compatible with MJIT and compaction GC.
|
12
|
+
|
13
|
+
* rbtree.c: restored to_hash default preservation removed in 0.5.0 and
|
14
|
+
made it compatible with newer Rubies
|
15
|
+
|
16
|
+
* rbtree.c: made code compatible with Ruby 2.7 and fixed warnings about
|
17
|
+
deprecated taint mechanism
|
18
|
+
|
1
19
|
2019-02-07 Kyrylo Silin
|
2
20
|
|
3
21
|
* version 0.5.0 released.
|
data/rbtree.c
CHANGED
@@ -2,9 +2,17 @@
|
|
2
2
|
* MIT License
|
3
3
|
* Copyright (c) 2002-2004, 2007, 2009 OZAWA Takuma
|
4
4
|
*/
|
5
|
-
#include <ruby
|
5
|
+
#include <ruby.h>
|
6
|
+
#ifdef HAVE_RUBY_VERSION_H
|
6
7
|
#include <ruby/version.h>
|
8
|
+
#else
|
9
|
+
#include <version.h>
|
10
|
+
#endif
|
11
|
+
#ifdef HAVE_RUBY_ST_H
|
7
12
|
#include <ruby/st.h>
|
13
|
+
#else
|
14
|
+
#include <st.h>
|
15
|
+
#endif
|
8
16
|
#include <stdarg.h>
|
9
17
|
#include "dict.h"
|
10
18
|
|
@@ -15,6 +23,19 @@
|
|
15
23
|
#define RETURN_ENUMERATOR(obj, argc, argv) ((void)0)
|
16
24
|
#endif
|
17
25
|
|
26
|
+
#ifndef RHASH_SET_IFNONE
|
27
|
+
#define RHASH_SET_IFNONE(h, ifnone) (RHASH_IFNONE(h) = ifnone)
|
28
|
+
#endif
|
29
|
+
|
30
|
+
#ifndef RB_BLOCK_CALL_FUNC_ARGLIST
|
31
|
+
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg) \
|
32
|
+
VALUE yielded_arg, VALUE callback_arg
|
33
|
+
#endif
|
34
|
+
|
35
|
+
#if !defined(RUBY_API_VERSION_CODE) || (RUBY_API_VERSION_CODE < 20700)
|
36
|
+
#define HAVE_TAINT
|
37
|
+
#endif
|
38
|
+
|
18
39
|
VALUE RBTree;
|
19
40
|
VALUE MultiRBTree;
|
20
41
|
|
@@ -29,10 +50,10 @@ typedef struct {
|
|
29
50
|
int iter_lev;
|
30
51
|
} rbtree_t;
|
31
52
|
|
32
|
-
#define RBTREE(rbtree) DATA_PTR(rbtree)
|
33
|
-
#define DICT(rbtree)
|
34
|
-
#define IFNONE(rbtree)
|
35
|
-
#define ITER_LEV(rbtree)
|
53
|
+
#define RBTREE(rbtree) ((rbtree_t*)DATA_PTR(rbtree))
|
54
|
+
#define DICT(rbtree) RBTREE(rbtree)->dict
|
55
|
+
#define IFNONE(rbtree) RBTREE(rbtree)->ifnone
|
56
|
+
#define ITER_LEV(rbtree) RBTREE(rbtree)->iter_lev
|
36
57
|
#define COMPARE(rbtree) DICT(rbtree)->dict_compare
|
37
58
|
#define CONTEXT(rbtree) DICT(rbtree)->dict_context
|
38
59
|
|
@@ -90,6 +111,7 @@ rbtree_free_node(dnode_t* node, void* context)
|
|
90
111
|
xfree(node);
|
91
112
|
}
|
92
113
|
|
114
|
+
NORETURN(static void rbtree_argc_error());
|
93
115
|
static void
|
94
116
|
rbtree_argc_error()
|
95
117
|
{
|
@@ -121,17 +143,19 @@ rbtree_modify(VALUE self)
|
|
121
143
|
rb_raise(rb_eTypeError, "can't modify rbtree in iteration");
|
122
144
|
if (OBJ_FROZEN(self))
|
123
145
|
rb_error_frozen("rbtree");
|
146
|
+
#ifdef HAVE_TAINT
|
124
147
|
if (!OBJ_TAINTED(self) && rb_safe_level() >= 4)
|
125
148
|
rb_raise(rb_eSecurityError, "Insecure: can't modify rbtree");
|
149
|
+
#endif
|
126
150
|
}
|
127
151
|
|
128
152
|
static VALUE
|
129
153
|
rbtree_alloc(VALUE klass)
|
130
154
|
{
|
131
155
|
dict_t* dict;
|
132
|
-
|
133
|
-
|
134
|
-
|
156
|
+
rbtree_t* rbtree_ptr;
|
157
|
+
VALUE rbtree = Data_Make_Struct(klass, rbtree_t, rbtree_mark, rbtree_free,
|
158
|
+
rbtree_ptr);
|
135
159
|
|
136
160
|
dict = dict_create(rbtree_cmp);
|
137
161
|
dict_set_allocator(dict, rbtree_alloc_node, rbtree_free_node,
|
@@ -139,8 +163,8 @@ rbtree_alloc(VALUE klass)
|
|
139
163
|
if (klass == MultiRBTree)
|
140
164
|
dict_allow_dupes(dict);
|
141
165
|
|
142
|
-
|
143
|
-
|
166
|
+
rbtree_ptr->dict = dict;
|
167
|
+
rbtree_ptr->ifnone = Qnil;
|
144
168
|
return rbtree;
|
145
169
|
}
|
146
170
|
|
@@ -256,8 +280,9 @@ typedef struct {
|
|
256
280
|
} insert_node_t;
|
257
281
|
|
258
282
|
static VALUE
|
259
|
-
insert_node_body(
|
283
|
+
insert_node_body(VALUE arg_)
|
260
284
|
{
|
285
|
+
insert_node_t* arg = (insert_node_t*)arg_;
|
261
286
|
if (dict_insert(arg->dict, arg->node, arg->key))
|
262
287
|
arg->ret = NODE_NOT_FOUND;
|
263
288
|
else
|
@@ -266,8 +291,9 @@ insert_node_body(insert_node_t* arg)
|
|
266
291
|
}
|
267
292
|
|
268
293
|
static VALUE
|
269
|
-
insert_node_ensure(
|
294
|
+
insert_node_ensure(VALUE arg_)
|
270
295
|
{
|
296
|
+
insert_node_t* arg = (insert_node_t*)arg_;
|
271
297
|
dict_t* dict = arg->dict;
|
272
298
|
dnode_t* node = arg->node;
|
273
299
|
switch (arg->ret) {
|
@@ -468,8 +494,9 @@ rbtree_each_ensure(VALUE self)
|
|
468
494
|
}
|
469
495
|
|
470
496
|
static VALUE
|
471
|
-
rbtree_each_body(
|
497
|
+
rbtree_each_body(VALUE arg_)
|
472
498
|
{
|
499
|
+
rbtree_each_arg_t* arg = (rbtree_each_arg_t*)arg_;
|
473
500
|
VALUE self = arg->self;
|
474
501
|
dict_t* dict = DICT(self);
|
475
502
|
dnode_t* node;
|
@@ -770,8 +797,9 @@ typedef struct {
|
|
770
797
|
} rbtree_delete_if_arg_t;
|
771
798
|
|
772
799
|
static VALUE
|
773
|
-
rbtree_delete_if_ensure(
|
800
|
+
rbtree_delete_if_ensure(VALUE arg_)
|
774
801
|
{
|
802
|
+
rbtree_delete_if_arg_t* arg = (rbtree_delete_if_arg_t*)arg_;
|
775
803
|
dict_t* dict = DICT(arg->self);
|
776
804
|
dnode_list_t* list = arg->list;
|
777
805
|
|
@@ -788,8 +816,9 @@ rbtree_delete_if_ensure(rbtree_delete_if_arg_t* arg)
|
|
788
816
|
}
|
789
817
|
|
790
818
|
static VALUE
|
791
|
-
rbtree_delete_if_body(
|
819
|
+
rbtree_delete_if_body(VALUE arg_)
|
792
820
|
{
|
821
|
+
rbtree_delete_if_arg_t* arg = (rbtree_delete_if_arg_t*)arg_;
|
793
822
|
VALUE self = arg->self;
|
794
823
|
dict_t* dict = DICT(self);
|
795
824
|
dnode_t* node;
|
@@ -1052,7 +1081,9 @@ rbtree_to_a(VALUE self)
|
|
1052
1081
|
{
|
1053
1082
|
VALUE ary = rb_ary_new();
|
1054
1083
|
rbtree_for_each(self, to_a_i, (void*)ary);
|
1084
|
+
#ifdef HAVE_TAINT
|
1055
1085
|
OBJ_INFECT(ary, self);
|
1086
|
+
#endif
|
1056
1087
|
return ary;
|
1057
1088
|
}
|
1058
1089
|
|
@@ -1076,9 +1107,12 @@ rbtree_to_hash(VALUE self)
|
|
1076
1107
|
|
1077
1108
|
hash = rb_hash_new();
|
1078
1109
|
rbtree_for_each(self, to_hash_i, (void*)hash);
|
1110
|
+
RHASH_SET_IFNONE(hash, IFNONE(self));
|
1079
1111
|
if (FL_TEST(self, RBTREE_PROC_DEFAULT))
|
1080
1112
|
FL_SET(hash, HASH_PROC_DEFAULT);
|
1113
|
+
#ifdef HAVE_TAINT
|
1081
1114
|
OBJ_INFECT(hash, self);
|
1115
|
+
#endif
|
1082
1116
|
return hash;
|
1083
1117
|
}
|
1084
1118
|
|
@@ -1144,13 +1178,17 @@ inspect_i(dnode_t* node, void* ret_)
|
|
1144
1178
|
|
1145
1179
|
str = rb_inspect(GET_KEY(node));
|
1146
1180
|
rb_str_append(ret, str);
|
1181
|
+
#ifdef HAVE_TAINT
|
1147
1182
|
OBJ_INFECT(ret, str);
|
1183
|
+
#endif
|
1148
1184
|
|
1149
1185
|
rb_str_cat2(ret, "=>");
|
1150
1186
|
|
1151
1187
|
str = rb_inspect(GET_VAL(node));
|
1152
1188
|
rb_str_append(ret, str);
|
1189
|
+
#ifdef HAVE_TAINT
|
1153
1190
|
OBJ_INFECT(ret, str);
|
1191
|
+
#endif
|
1154
1192
|
|
1155
1193
|
return EACH_NEXT;
|
1156
1194
|
}
|
@@ -1169,15 +1207,21 @@ inspect_rbtree(VALUE self, VALUE ret)
|
|
1169
1207
|
str = rb_inspect(IFNONE(self));
|
1170
1208
|
rb_str_cat2(ret, ", default=");
|
1171
1209
|
rb_str_append(ret, str);
|
1210
|
+
#ifdef HAVE_TAINT
|
1172
1211
|
OBJ_INFECT(ret, str);
|
1212
|
+
#endif
|
1173
1213
|
|
1174
1214
|
str = rb_inspect((VALUE)CONTEXT(self));
|
1175
1215
|
rb_str_cat2(ret, ", cmp_proc=");
|
1176
1216
|
rb_str_append(ret, str);
|
1217
|
+
#ifdef HAVE_TAINT
|
1177
1218
|
OBJ_INFECT(ret, str);
|
1219
|
+
#endif
|
1178
1220
|
|
1179
1221
|
rb_str_cat2(ret, ">");
|
1222
|
+
#ifdef HAVE_TAINT
|
1180
1223
|
OBJ_INFECT(ret, self);
|
1224
|
+
#endif
|
1181
1225
|
return ret;
|
1182
1226
|
}
|
1183
1227
|
|
@@ -1252,8 +1296,9 @@ typedef struct {
|
|
1252
1296
|
} rbtree_bound_arg_t;
|
1253
1297
|
|
1254
1298
|
static VALUE
|
1255
|
-
rbtree_bound_body(
|
1299
|
+
rbtree_bound_body(VALUE arg_)
|
1256
1300
|
{
|
1301
|
+
rbtree_bound_arg_t* arg = (rbtree_bound_arg_t*)arg_;
|
1257
1302
|
VALUE self = arg->self;
|
1258
1303
|
dict_t* dict = DICT(self);
|
1259
1304
|
dnode_t* lower_node = arg->lower_node;
|
@@ -1452,8 +1497,9 @@ pp_object_group(VALUE arg_)
|
|
1452
1497
|
}
|
1453
1498
|
|
1454
1499
|
static VALUE
|
1455
|
-
pp_block(
|
1500
|
+
pp_block(RB_BLOCK_CALL_FUNC_ARGLIST(nil, arg_))
|
1456
1501
|
{
|
1502
|
+
pp_arg_t* arg = (pp_arg_t*)arg_;
|
1457
1503
|
VALUE pp = arg->pp;
|
1458
1504
|
VALUE rbtree = arg->rbtree;
|
1459
1505
|
|
@@ -1464,7 +1510,7 @@ pp_block(VALUE nil, pp_arg_t* arg)
|
|
1464
1510
|
rb_funcall(pp, id_pp, 1, IFNONE(rbtree));
|
1465
1511
|
rb_funcall(pp, id_comma_breakable, 0);
|
1466
1512
|
rb_funcall(pp, id_text, 1, rb_str_new2("cmp_proc="));
|
1467
|
-
rb_funcall(pp, id_pp, 1, CONTEXT(rbtree));
|
1513
|
+
rb_funcall(pp, id_pp, 1, (VALUE)CONTEXT(rbtree));
|
1468
1514
|
return pp;
|
1469
1515
|
}
|
1470
1516
|
|
data/test.rb
CHANGED
@@ -517,7 +517,18 @@ class RBTreeTest < Test::Unit::TestCase
|
|
517
517
|
def test_to_hash
|
518
518
|
@rbtree.default = "e"
|
519
519
|
hash = @rbtree.to_hash
|
520
|
-
|
520
|
+
hash_a = hash.to_a
|
521
|
+
hash_a.sort! if RUBY_VERSION < "1.9" # Hash ordering isn't stable in < 1.9.
|
522
|
+
assert_equal(@rbtree.to_a.flatten, hash_a.flatten)
|
523
|
+
assert_equal("e", hash.default)
|
524
|
+
|
525
|
+
rbtree = RBTree.new { "e" }
|
526
|
+
hash = rbtree.to_hash
|
527
|
+
if (hash.respond_to?(:default_proc))
|
528
|
+
assert_equal(rbtree.default_proc, hash.default_proc)
|
529
|
+
else
|
530
|
+
assert_equal(rbtree.default_proc, hash.default)
|
531
|
+
end
|
521
532
|
end
|
522
533
|
|
523
534
|
def test_to_rbtree
|
@@ -534,7 +545,11 @@ class RBTreeTest < Test::Unit::TestCase
|
|
534
545
|
tree, default, cmp_proc = match.to_a[1..-1]
|
535
546
|
assert_equal(%({"a"=>"A", "b"=>"B", "c"=>"C", "d"=>"D"}), tree)
|
536
547
|
assert_equal(%("e"), default)
|
537
|
-
|
548
|
+
if @rbtree.cmp_proc.respond_to?("source_location")
|
549
|
+
assert_equal(File.basename(__FILE__), @rbtree.cmp_proc.source_location[0])
|
550
|
+
else
|
551
|
+
assert_match(/#<Proc:\w+(@#{__FILE__}:\d+)?>/o, cmp_proc)
|
552
|
+
end
|
538
553
|
|
539
554
|
rbtree = RBTree.new
|
540
555
|
assert_match(re, rbtree.inspect)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbtree3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyrylo Silin
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-01-21 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: |-
|
15
15
|
A RBTree is a sorted associative collection that is implemented with a Red-Black Tree. It maps keys to values like a Hash, but maintains its elements in ascending key order. The interface is the almost identical to that of Hash.
|
@@ -47,7 +47,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
47
47
|
requirements:
|
48
48
|
- - ">="
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: '
|
50
|
+
version: '1.8'
|
51
51
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - ">="
|
@@ -55,7 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
55
|
version: '0'
|
56
56
|
requirements: []
|
57
57
|
rubyforge_project:
|
58
|
-
rubygems_version: 2.6.
|
58
|
+
rubygems_version: 2.7.6.2
|
59
59
|
signing_key:
|
60
60
|
specification_version: 4
|
61
61
|
summary: A RBTree is a sorted associative collection that is implemented with a Red-Black
|