rbtree3 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (10) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +492 -0
  3. data/LICENSE +22 -0
  4. data/README +106 -0
  5. data/dict.c +1216 -0
  6. data/dict.h +123 -0
  7. data/extconf.rb +13 -0
  8. data/rbtree.c +1701 -0
  9. data/test.rb +950 -0
  10. metadata +64 -0
data/dict.h ADDED
@@ -0,0 +1,123 @@
1
+ /*
2
+ * Dictionary Abstract Data Type
3
+ * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
4
+ *
5
+ * Free Software License:
6
+ *
7
+ * All rights are reserved by the author, with the following exceptions:
8
+ * Permission is granted to freely reproduce and distribute this software,
9
+ * possibly in exchange for a fee, provided that this copyright notice appears
10
+ * intact. Permission is also granted to adapt this software to produce
11
+ * derivative works, as long as the modified versions carry this copyright
12
+ * notice and additional notices stating that the work has been modified.
13
+ * This source code may be translated into executable form and incorporated
14
+ * into proprietary software; there is no requirement for such software to
15
+ * contain a copyright notice related to this source.
16
+ *
17
+ * $Id: dict.h,v 1.9 2005/10/06 05:16:35 kuma Exp $
18
+ * $Name: $
19
+ */
20
+
21
+ /*
22
+ * Modified for Ruby/RBTree by OZAWA Takuma.
23
+ */
24
+
25
+ #ifndef DICT_H
26
+ #define DICT_H
27
+
28
+ #include <limits.h>
29
+
30
+ /*
31
+ * Blurb for inclusion into C++ translation units
32
+ */
33
+
34
+ #ifdef __cplusplus
35
+ extern "C" {
36
+ #endif
37
+
38
+ typedef unsigned long dictcount_t;
39
+ #define DICTCOUNT_T_MAX ULONG_MAX
40
+
41
+ /*
42
+ * The dictionary is implemented as a red-black tree
43
+ */
44
+
45
+ typedef enum { dnode_red, dnode_black } dnode_color_t;
46
+
47
+ typedef struct dnode_t {
48
+ struct dnode_t *dict_left;
49
+ struct dnode_t *dict_right;
50
+ struct dnode_t *dict_parent;
51
+ dnode_color_t dict_color;
52
+ const void *dict_key;
53
+ void *dict_data;
54
+ } dnode_t;
55
+
56
+ typedef int (*dict_comp_t)(const void *, const void *, void *);
57
+ typedef dnode_t *(*dnode_alloc_t)(void *);
58
+ typedef void (*dnode_free_t)(dnode_t *, void *);
59
+
60
+ typedef int (*dict_value_eql_t)(const void *, const void *);
61
+
62
+ typedef struct dict_t {
63
+ dnode_t dict_nilnode;
64
+ dictcount_t dict_nodecount;
65
+ dict_comp_t dict_compare;
66
+ dnode_alloc_t dict_allocnode;
67
+ dnode_free_t dict_freenode;
68
+ void *dict_context;
69
+ int dict_dupes;
70
+ } dict_t;
71
+
72
+ typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
73
+
74
+ typedef struct dict_load_t {
75
+ dict_t *dict_dictptr;
76
+ dnode_t dict_nilnode;
77
+ } dict_load_t;
78
+
79
+ extern dict_t *dict_create(dict_comp_t);
80
+ extern void dict_set_allocator(dict_t *, dnode_alloc_t, dnode_free_t, void *);
81
+ extern void dict_destroy(dict_t *);
82
+ extern void dict_free_nodes(dict_t *);
83
+ extern void dict_free(dict_t *);
84
+ extern dict_t *dict_init(dict_t *, dict_comp_t);
85
+ extern void dict_init_like(dict_t *, const dict_t *);
86
+ extern int dict_verify(dict_t *);
87
+ extern int dict_similar(const dict_t *, const dict_t *);
88
+ extern dnode_t *dict_lookup(dict_t *, const void *);
89
+ extern dnode_t *dict_lower_bound(dict_t *, const void *);
90
+ extern dnode_t *dict_upper_bound(dict_t *, const void *);
91
+ extern int dict_insert(dict_t *, dnode_t *, const void *);
92
+ extern dnode_t *dict_delete(dict_t *, dnode_t *);
93
+ extern int dict_alloc_insert(dict_t *, const void *, void *);
94
+ extern void dict_delete_free(dict_t *, dnode_t *);
95
+ extern dnode_t *dict_first(dict_t *);
96
+ extern dnode_t *dict_last(dict_t *);
97
+ extern dnode_t *dict_next(dict_t *, dnode_t *);
98
+ extern dnode_t *dict_prev(dict_t *, dnode_t *);
99
+ extern dictcount_t dict_count(dict_t *);
100
+ extern int dict_isempty(dict_t *);
101
+ extern int dict_isfull(dict_t *);
102
+ extern int dict_contains(dict_t *, dnode_t *);
103
+ extern void dict_allow_dupes(dict_t *);
104
+ extern int dnode_is_in_a_dict(dnode_t *);
105
+ extern dnode_t *dnode_create(void *);
106
+ extern dnode_t *dnode_init(dnode_t *, void *);
107
+ extern void dnode_destroy(dnode_t *);
108
+ extern void *dnode_get(dnode_t *);
109
+ extern const void *dnode_getkey(dnode_t *);
110
+ extern void dnode_put(dnode_t *, void *);
111
+ extern void dict_process(dict_t *, void *, dnode_process_t);
112
+ extern void dict_load_begin(dict_load_t *, dict_t *);
113
+ extern void dict_load_next(dict_load_t *, dnode_t *, const void *);
114
+ extern void dict_load_end(dict_load_t *);
115
+ extern void dict_merge(dict_t *, dict_t *);
116
+
117
+ int dict_equal(dict_t*, dict_t*, dict_value_eql_t);
118
+
119
+ #ifdef __cplusplus
120
+ }
121
+ #endif
122
+
123
+ #endif
@@ -0,0 +1,13 @@
1
+ require 'mkmf'
2
+
3
+ if $DEBUG
4
+ if CONFIG['GCC'] == 'yes'
5
+ $CFLAGS << ' -std=c89 -pedantic -Wno-long-long'
6
+ end
7
+ $defs << ' -Dinline=__inline'
8
+ else
9
+ $defs << '-DNDEBUG'
10
+ end
11
+
12
+ have_func('rb_exec_recursive', 'ruby.h')
13
+ create_makefile('rbtree')
@@ -0,0 +1,1701 @@
1
+ /*
2
+ * MIT License
3
+ * Copyright (c) 2002-2004, 2007, 2009 OZAWA Takuma
4
+ */
5
+ #include <ruby/ruby.h>
6
+ #include <ruby/version.h>
7
+ #include <ruby/st.h>
8
+ #include <stdarg.h>
9
+ #include "dict.h"
10
+
11
+ #define RBTREE_PROC_DEFAULT FL_USER2
12
+ #define HASH_PROC_DEFAULT FL_USER2
13
+
14
+ #ifndef RETURN_ENUMERATOR
15
+ #define RETURN_ENUMERATOR(obj, argc, argv) ((void)0)
16
+ #endif
17
+
18
+ VALUE RBTree;
19
+ VALUE MultiRBTree;
20
+
21
+ static ID id_bound;
22
+ static ID id_cmp;
23
+ static ID id_call;
24
+ static ID id_default;
25
+
26
+ typedef struct {
27
+ dict_t* dict;
28
+ VALUE ifnone;
29
+ int iter_lev;
30
+ } rbtree_t;
31
+
32
+ #define RBTREE(rbtree) DATA_PTR(rbtree)
33
+ #define DICT(rbtree) ((rbtree_t*)RBTREE(rbtree))->dict
34
+ #define IFNONE(rbtree) ((rbtree_t*)RBTREE(rbtree))->ifnone
35
+ #define ITER_LEV(rbtree) ((rbtree_t*)RBTREE(rbtree))->iter_lev
36
+ #define COMPARE(rbtree) DICT(rbtree)->dict_compare
37
+ #define CONTEXT(rbtree) DICT(rbtree)->dict_context
38
+
39
+ #define TO_KEY(arg) ((const void*)arg)
40
+ #define TO_VAL(arg) ((void*)arg)
41
+ #define GET_KEY(dnode) ((VALUE)dnode_getkey(dnode))
42
+ #define GET_VAL(dnode) ((VALUE)dnode_get(dnode))
43
+ #define ASSOC(dnode) rb_assoc_new(GET_KEY(dnode), GET_VAL(dnode))
44
+
45
+ /*********************************************************************/
46
+
47
+ static int
48
+ cmpint(VALUE i, VALUE a, VALUE b)
49
+ {
50
+ return rb_cmpint(i, a, b);
51
+ }
52
+
53
+ static void
54
+ rbtree_free(rbtree_t* rbtree)
55
+ {
56
+ dict_free_nodes(rbtree->dict);
57
+ dict_destroy(rbtree->dict);
58
+ xfree(rbtree);
59
+ }
60
+
61
+ static void
62
+ rbtree_mark(rbtree_t* rbtree)
63
+ {
64
+ if (rbtree == NULL) return;
65
+
66
+ if (rbtree->dict != NULL) {
67
+ dict_t* dict = rbtree->dict;
68
+ dnode_t* node;
69
+ for (node = dict_first(dict);
70
+ node != NULL;
71
+ node = dict_next(dict, node)) {
72
+
73
+ rb_gc_mark(GET_KEY(node));
74
+ rb_gc_mark(GET_VAL(node));
75
+ }
76
+ rb_gc_mark((VALUE)dict->dict_context);
77
+ }
78
+ rb_gc_mark(rbtree->ifnone);
79
+ }
80
+
81
+ static dnode_t*
82
+ rbtree_alloc_node(void* context)
83
+ {
84
+ return ALLOC(dnode_t);
85
+ }
86
+
87
+ static void
88
+ rbtree_free_node(dnode_t* node, void* context)
89
+ {
90
+ xfree(node);
91
+ }
92
+
93
+ static void
94
+ rbtree_argc_error()
95
+ {
96
+ rb_raise(rb_eArgError, "wrong number of arguments");
97
+ }
98
+
99
+ static int
100
+ rbtree_cmp(const void* key1, const void* key2, void* context)
101
+ {
102
+ VALUE ret;
103
+ if (TYPE(key1) == T_STRING && TYPE(key2) == T_STRING)
104
+ return rb_str_cmp((VALUE)key1, (VALUE)key2);
105
+ ret = rb_funcall((VALUE)key1, id_cmp, 1, (VALUE)key2);
106
+ return cmpint(ret, (VALUE)key1, (VALUE)key2);
107
+ }
108
+
109
+ static int
110
+ rbtree_user_cmp(const void* key1, const void* key2, void* cmp_proc)
111
+ {
112
+ VALUE ret = rb_funcall((VALUE)cmp_proc, id_call, 2,
113
+ (VALUE)key1, (VALUE)key2);
114
+ return cmpint(ret, (VALUE)key1, (VALUE)key2);
115
+ }
116
+
117
+ static void
118
+ rbtree_modify(VALUE self)
119
+ {
120
+ if (ITER_LEV(self) > 0)
121
+ rb_raise(rb_eTypeError, "can't modify rbtree in iteration");
122
+ if (OBJ_FROZEN(self))
123
+ rb_error_frozen("rbtree");
124
+ if (!OBJ_TAINTED(self) && rb_safe_level() >= 4)
125
+ rb_raise(rb_eSecurityError, "Insecure: can't modify rbtree");
126
+ }
127
+
128
+ static VALUE
129
+ rbtree_alloc(VALUE klass)
130
+ {
131
+ dict_t* dict;
132
+ VALUE rbtree = Data_Wrap_Struct(klass, rbtree_mark, rbtree_free, 0);
133
+ RBTREE(rbtree) = ALLOC(rbtree_t);
134
+ MEMZERO(RBTREE(rbtree), rbtree_t, 1);
135
+
136
+ dict = dict_create(rbtree_cmp);
137
+ dict_set_allocator(dict, rbtree_alloc_node, rbtree_free_node,
138
+ (void*)Qnil);
139
+ if (klass == MultiRBTree)
140
+ dict_allow_dupes(dict);
141
+
142
+ DICT(rbtree) = dict;
143
+ IFNONE(rbtree) = Qnil;
144
+ return rbtree;
145
+ }
146
+
147
+ VALUE rbtree_aset(VALUE, VALUE, VALUE);
148
+ VALUE rbtree_clear(VALUE);
149
+ VALUE rbtree_has_key(VALUE, VALUE);
150
+ VALUE rbtree_update(VALUE, VALUE);
151
+
152
+ /*********************************************************************/
153
+
154
+ static int
155
+ hash_to_rbtree_i(VALUE key, VALUE value, VALUE rbtree)
156
+ {
157
+ if (key != Qundef)
158
+ rbtree_aset(rbtree, key, value);
159
+ return ST_CONTINUE;
160
+ }
161
+
162
+ /*
163
+ *
164
+ */
165
+ VALUE
166
+ rbtree_s_create(int argc, VALUE* argv, VALUE klass)
167
+ {
168
+ long i;
169
+ VALUE rbtree;
170
+
171
+ if (argc == 1) {
172
+ VALUE tmp;
173
+
174
+ if (klass == RBTree && CLASS_OF(argv[0]) == MultiRBTree) {
175
+ rb_raise(rb_eTypeError, "can't convert MultiRBTree to RBTree");
176
+ }
177
+
178
+ if (rb_obj_is_kind_of(argv[0], klass)) {
179
+ rbtree = rbtree_alloc(klass);
180
+ rbtree_update(rbtree, argv[0]);
181
+ return rbtree;
182
+ }
183
+
184
+ tmp = rb_check_convert_type(argv[0], T_HASH, "Hash", "to_hash");
185
+ if (!NIL_P(tmp)) {
186
+ rbtree = rbtree_alloc(klass);
187
+ st_foreach(RHASH_TBL(tmp), hash_to_rbtree_i, rbtree);
188
+ return rbtree;
189
+ }
190
+
191
+ tmp = rb_check_array_type(argv[0]);
192
+ if (!NIL_P(tmp)) {
193
+ rbtree = rbtree_alloc(klass);
194
+ for (i = 0; i < RARRAY_LEN(tmp); i++) {
195
+ VALUE v = rb_check_array_type(RARRAY_PTR(tmp)[i]);
196
+ if (NIL_P(v)) {
197
+ continue;
198
+ }
199
+ switch(RARRAY_LEN(v)) {
200
+ case 1:
201
+ rbtree_aset(rbtree, RARRAY_PTR(v)[0], Qnil);
202
+ break;
203
+ case 2:
204
+ rbtree_aset(rbtree, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]);
205
+ break;
206
+ default:
207
+ continue;
208
+ }
209
+ }
210
+ return rbtree;
211
+ }
212
+ }
213
+
214
+ if (argc % 2 != 0)
215
+ rb_raise(rb_eArgError, "odd number of arguments for RBTree");
216
+
217
+ rbtree = rbtree_alloc(klass);
218
+ for (i = 0; i < argc; i += 2)
219
+ rbtree_aset(rbtree, argv[i], argv[i + 1]);
220
+ return rbtree;
221
+ }
222
+
223
+ /*
224
+ *
225
+ */
226
+ VALUE
227
+ rbtree_initialize(int argc, VALUE* argv, VALUE self)
228
+ {
229
+ rbtree_modify(self);
230
+
231
+ if (rb_block_given_p()) {
232
+ if (argc > 0)
233
+ rbtree_argc_error();
234
+ IFNONE(self) = rb_block_proc();
235
+ FL_SET(self, RBTREE_PROC_DEFAULT);
236
+ } else {
237
+ if (argc > 1)
238
+ rbtree_argc_error();
239
+ else if (argc == 1)
240
+ IFNONE(self) = argv[0];
241
+ }
242
+ return self;
243
+ }
244
+
245
+ /*********************************************************************/
246
+
247
+ typedef enum {
248
+ INITIAL_VALUE, NODE_NOT_FOUND, NODE_FOUND
249
+ } insert_node_ret_t;
250
+
251
+ typedef struct {
252
+ dict_t* dict;
253
+ dnode_t* node;
254
+ const void* key;
255
+ insert_node_ret_t ret;
256
+ } insert_node_t;
257
+
258
+ static VALUE
259
+ insert_node_body(insert_node_t* arg)
260
+ {
261
+ if (dict_insert(arg->dict, arg->node, arg->key))
262
+ arg->ret = NODE_NOT_FOUND;
263
+ else
264
+ arg->ret = NODE_FOUND;
265
+ return Qnil;
266
+ }
267
+
268
+ static VALUE
269
+ insert_node_ensure(insert_node_t* arg)
270
+ {
271
+ dict_t* dict = arg->dict;
272
+ dnode_t* node = arg->node;
273
+ switch (arg->ret) {
274
+ case INITIAL_VALUE:
275
+ dict->dict_freenode(node, dict->dict_context);
276
+ break;
277
+ case NODE_NOT_FOUND:
278
+ if (TYPE(arg->key) == T_STRING)
279
+ node->dict_key = TO_KEY(rb_str_new4(GET_KEY(node)));
280
+ break;
281
+ case NODE_FOUND:
282
+ dict->dict_freenode(node, dict->dict_context);
283
+ break;
284
+ }
285
+ return Qnil;
286
+ }
287
+
288
+ static void
289
+ rbtree_insert(VALUE self, VALUE key, VALUE value)
290
+ {
291
+ insert_node_t arg;
292
+ dict_t* dict = DICT(self);
293
+ dnode_t* node = dict->dict_allocnode(dict->dict_context);
294
+
295
+ dnode_init(node, TO_VAL(value));
296
+
297
+ arg.dict = dict;
298
+ arg.node = node;
299
+ arg.key = TO_KEY(key);
300
+ arg.ret = INITIAL_VALUE;
301
+
302
+ rb_ensure(insert_node_body, (VALUE)&arg,
303
+ insert_node_ensure, (VALUE)&arg);
304
+ }
305
+
306
+ /*********************************************************************/
307
+
308
+ /*
309
+ *
310
+ */
311
+ VALUE
312
+ rbtree_aset(VALUE self, VALUE key, VALUE value)
313
+ {
314
+ rbtree_modify(self);
315
+
316
+ if (dict_isfull(DICT(self))) {
317
+ dnode_t* node = dict_lookup(DICT(self), TO_KEY(key));
318
+ if (node == NULL)
319
+ rb_raise(rb_eIndexError, "rbtree full");
320
+ else
321
+ dnode_put(node, TO_VAL(value));
322
+ return value;
323
+ }
324
+ rbtree_insert(self, key, value);
325
+ return value;
326
+ }
327
+
328
+ /*
329
+ *
330
+ */
331
+ VALUE
332
+ rbtree_aref(VALUE self, VALUE key)
333
+ {
334
+ dnode_t* node = dict_lookup(DICT(self), TO_KEY(key));
335
+ if (node == NULL)
336
+ return rb_funcall(self, id_default, 1, key);
337
+ else
338
+ return GET_VAL(node);
339
+ }
340
+
341
+ /*
342
+ *
343
+ */
344
+ VALUE
345
+ rbtree_fetch(int argc, VALUE* argv, VALUE self)
346
+ {
347
+ dnode_t* node;
348
+ int block_given;
349
+
350
+ if (argc == 0 || argc > 2)
351
+ rbtree_argc_error();
352
+ block_given = rb_block_given_p();
353
+ if (block_given && argc == 2)
354
+ rb_warn("block supersedes default value argument");
355
+
356
+ node = dict_lookup(DICT(self), TO_KEY(argv[0]));
357
+ if (node != NULL)
358
+ return GET_VAL(node);
359
+
360
+ if (block_given)
361
+ return rb_yield(argv[0]);
362
+ if (argc == 1)
363
+ rb_raise(rb_eIndexError, "key not found");
364
+ return argv[1];
365
+ }
366
+
367
+ /*
368
+ *
369
+ */
370
+ VALUE
371
+ rbtree_size(VALUE self)
372
+ {
373
+ return ULONG2NUM(dict_count(DICT(self)));
374
+ }
375
+
376
+ /*
377
+ *
378
+ */
379
+ VALUE
380
+ rbtree_empty_p(VALUE self)
381
+ {
382
+ return dict_isempty(DICT(self)) ? Qtrue : Qfalse;
383
+ }
384
+
385
+ /*
386
+ *
387
+ */
388
+ VALUE
389
+ rbtree_default(int argc, VALUE* argv, VALUE self)
390
+ {
391
+ VALUE key = Qnil;
392
+ if (argc == 1)
393
+ key = argv[0];
394
+ else if (argc > 1)
395
+ rbtree_argc_error();
396
+
397
+ if (FL_TEST(self, RBTREE_PROC_DEFAULT)) {
398
+ if (argc == 0) return Qnil;
399
+ return rb_funcall(IFNONE(self), id_call, 2, self, key);
400
+ }
401
+ return IFNONE(self);
402
+ }
403
+
404
+ /*
405
+ *
406
+ */
407
+ VALUE
408
+ rbtree_set_default(VALUE self, VALUE ifnone)
409
+ {
410
+ rbtree_modify(self);
411
+ IFNONE(self) = ifnone;
412
+ FL_UNSET(self, RBTREE_PROC_DEFAULT);
413
+ return ifnone;
414
+ }
415
+
416
+ /*
417
+ *
418
+ */
419
+ VALUE
420
+ rbtree_default_proc(VALUE self)
421
+ {
422
+ if (FL_TEST(self, RBTREE_PROC_DEFAULT))
423
+ return IFNONE(self);
424
+ return Qnil;
425
+ }
426
+
427
+ static int
428
+ value_eq(const void* key1, const void* key2)
429
+ {
430
+ return rb_equal((VALUE)key1, (VALUE)key2) != 0;
431
+ }
432
+
433
+ /*
434
+ *
435
+ */
436
+ VALUE
437
+ rbtree_equal(VALUE self, VALUE other)
438
+ {
439
+ int ret;
440
+ if (self == other)
441
+ return Qtrue;
442
+ if (!rb_obj_is_kind_of(other, MultiRBTree))
443
+ return Qfalse;
444
+ ret = dict_equal(DICT(self), DICT(other), value_eq);
445
+ return ret ? Qtrue : Qfalse;
446
+ }
447
+
448
+ /*********************************************************************/
449
+
450
+ typedef enum {
451
+ EACH_NEXT, EACH_STOP
452
+ } each_return_t;
453
+
454
+ typedef each_return_t (*each_callback_func)(dnode_t*, void*);
455
+
456
+ typedef struct {
457
+ VALUE self;
458
+ each_callback_func func;
459
+ void* arg;
460
+ int reverse;
461
+ } rbtree_each_arg_t;
462
+
463
+ static VALUE
464
+ rbtree_each_ensure(VALUE self)
465
+ {
466
+ ITER_LEV(self)--;
467
+ return Qnil;
468
+ }
469
+
470
+ static VALUE
471
+ rbtree_each_body(rbtree_each_arg_t* arg)
472
+ {
473
+ VALUE self = arg->self;
474
+ dict_t* dict = DICT(self);
475
+ dnode_t* node;
476
+ dnode_t* first_node;
477
+ dnode_t* (*next_func)(dict_t*, dnode_t*);
478
+
479
+ if (arg->reverse) {
480
+ first_node = dict_last(dict);
481
+ next_func = dict_prev;
482
+ } else {
483
+ first_node = dict_first(dict);
484
+ next_func = dict_next;
485
+ }
486
+
487
+ ITER_LEV(self)++;
488
+ for (node = first_node;
489
+ node != NULL;
490
+ node = next_func(dict, node)) {
491
+
492
+ if (arg->func(node, arg->arg) == EACH_STOP)
493
+ break;
494
+ }
495
+ return self;
496
+ }
497
+
498
+ static VALUE
499
+ rbtree_for_each(VALUE self, each_callback_func func, void* arg)
500
+ {
501
+ rbtree_each_arg_t each_arg;
502
+ each_arg.self = self;
503
+ each_arg.func = func;
504
+ each_arg.arg = arg;
505
+ each_arg.reverse = 0;
506
+ return rb_ensure(rbtree_each_body, (VALUE)&each_arg,
507
+ rbtree_each_ensure, self);
508
+ }
509
+
510
+ static VALUE
511
+ rbtree_reverse_for_each(VALUE self, each_callback_func func, void* arg)
512
+ {
513
+ rbtree_each_arg_t each_arg;
514
+ each_arg.self = self;
515
+ each_arg.func = func;
516
+ each_arg.arg = arg;
517
+ each_arg.reverse = 1;
518
+ return rb_ensure(rbtree_each_body, (VALUE)&each_arg,
519
+ rbtree_each_ensure, self);
520
+ }
521
+
522
+ /*********************************************************************/
523
+
524
+ static each_return_t
525
+ each_i(dnode_t* node, void* arg)
526
+ {
527
+ rb_yield(ASSOC(node));
528
+ return EACH_NEXT;
529
+ }
530
+
531
+ /*
532
+ * call-seq:
533
+ * rbtree.each {|key, value| block} => rbtree
534
+ *
535
+ * Calls block once for each key in order, passing the key and value
536
+ * as a two-element array parameters.
537
+ */
538
+ VALUE
539
+ rbtree_each(VALUE self)
540
+ {
541
+ RETURN_ENUMERATOR(self, 0, NULL);
542
+ return rbtree_for_each(self, each_i, NULL);
543
+ }
544
+
545
+ static each_return_t
546
+ each_pair_i(dnode_t* node, void* arg)
547
+ {
548
+ rb_yield_values(2, GET_KEY(node), GET_VAL(node));
549
+ return EACH_NEXT;
550
+ }
551
+
552
+ /*
553
+ * call-seq:
554
+ * rbtree.each_pair {|key, value| block} => rbtree
555
+ *
556
+ * Calls block once for each key in order, passing the key and value
557
+ * as parameters.
558
+ */
559
+ VALUE
560
+ rbtree_each_pair(VALUE self)
561
+ {
562
+ RETURN_ENUMERATOR(self, 0, NULL);
563
+ return rbtree_for_each(self, each_pair_i, NULL);
564
+ }
565
+
566
+ static each_return_t
567
+ each_key_i(dnode_t* node, void* arg)
568
+ {
569
+ rb_yield(GET_KEY(node));
570
+ return EACH_NEXT;
571
+ }
572
+
573
+ /*
574
+ * call-seq:
575
+ * rbtree.each_key {|key| block} => rbtree
576
+ *
577
+ * Calls block once for each key in order, passing the key as
578
+ * parameters.
579
+ */
580
+ VALUE
581
+ rbtree_each_key(VALUE self)
582
+ {
583
+ RETURN_ENUMERATOR(self, 0, NULL);
584
+ return rbtree_for_each(self, each_key_i, NULL);
585
+ }
586
+
587
+ static each_return_t
588
+ each_value_i(dnode_t* node, void* arg)
589
+ {
590
+ rb_yield(GET_VAL(node));
591
+ return EACH_NEXT;
592
+ }
593
+
594
+ /*
595
+ * call-seq:
596
+ * rbtree.each_value {|value| block} => rbtree
597
+ *
598
+ * Calls block once for each key in order, passing the value as
599
+ * parameters.
600
+ */
601
+ VALUE
602
+ rbtree_each_value(VALUE self)
603
+ {
604
+ RETURN_ENUMERATOR(self, 0, NULL);
605
+ return rbtree_for_each(self, each_value_i, NULL);
606
+ }
607
+
608
+ /*
609
+ * call-seq:
610
+ * rbtree.reverse_each {|key, value| block} => rbtree
611
+ *
612
+ * Calls block once for each key in reverse order, passing the key and
613
+ * value as parameters.
614
+ */
615
+ VALUE
616
+ rbtree_reverse_each(VALUE self)
617
+ {
618
+ RETURN_ENUMERATOR(self, 0, NULL);
619
+ return rbtree_reverse_for_each(self, each_pair_i, NULL);
620
+ }
621
+
622
+ static each_return_t
623
+ aset_i(dnode_t* node, void* self)
624
+ {
625
+ rbtree_aset((VALUE)self, GET_KEY(node), GET_VAL(node));
626
+ return EACH_NEXT;
627
+ }
628
+
629
+ static void
630
+ copy_dict(VALUE src, VALUE dest, dict_comp_t cmp, void* context)
631
+ {
632
+ VALUE temp = rbtree_alloc(CLASS_OF(dest));
633
+ COMPARE(temp) = cmp;
634
+ CONTEXT(temp) = context;
635
+ rbtree_for_each(src, aset_i, (void*)temp);
636
+ {
637
+ dict_t* t = DICT(temp);
638
+ DICT(temp) = DICT(dest);
639
+ DICT(dest) = t;
640
+ }
641
+ rbtree_free(RBTREE(temp));
642
+ rb_gc_force_recycle(temp);
643
+ }
644
+
645
+ /*
646
+ *
647
+ */
648
+ VALUE
649
+ rbtree_initialize_copy(VALUE self, VALUE other)
650
+ {
651
+ if (self == other)
652
+ return self;
653
+ if (!rb_obj_is_kind_of(other, CLASS_OF(self))) {
654
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
655
+ rb_class2name(CLASS_OF(other)),
656
+ rb_class2name(CLASS_OF(self)));
657
+ }
658
+
659
+ copy_dict(other, self, COMPARE(other), CONTEXT(other));
660
+
661
+ IFNONE(self) = IFNONE(other);
662
+ if (FL_TEST(other, RBTREE_PROC_DEFAULT))
663
+ FL_SET(self, RBTREE_PROC_DEFAULT);
664
+ else
665
+ FL_UNSET(self, RBTREE_PROC_DEFAULT);
666
+ return self;
667
+ }
668
+
669
+ /*
670
+ *
671
+ */
672
+ VALUE
673
+ rbtree_values_at(int argc, VALUE* argv, VALUE self)
674
+ {
675
+ long i;
676
+ VALUE ary = rb_ary_new();
677
+
678
+ for (i = 0; i < argc; i++)
679
+ rb_ary_push(ary, rbtree_aref(self, argv[i]));
680
+ return ary;
681
+ }
682
+
683
+ static each_return_t
684
+ select_i(dnode_t* node, void* ary)
685
+ {
686
+ if (RTEST(rb_yield_values(2, GET_KEY(node), GET_VAL(node))))
687
+ rb_ary_push((VALUE)ary, ASSOC(node));
688
+ return EACH_NEXT;
689
+ }
690
+
691
+ /*
692
+ *
693
+ */
694
+ VALUE
695
+ rbtree_select(VALUE self)
696
+ {
697
+ VALUE ary;
698
+
699
+ RETURN_ENUMERATOR(self, 0, NULL);
700
+ ary = rb_ary_new();
701
+ rbtree_for_each(self, select_i, (void*)ary);
702
+ return ary;
703
+ }
704
+
705
+ static each_return_t
706
+ index_i(dnode_t* node, void* arg_)
707
+ {
708
+ VALUE* arg = (VALUE*)arg_;
709
+ if (rb_equal(GET_VAL(node), arg[1])) {
710
+ arg[0] = GET_KEY(node);
711
+ return EACH_STOP;
712
+ }
713
+ return EACH_NEXT;
714
+ }
715
+
716
+ /*
717
+ *
718
+ */
719
+ VALUE
720
+ rbtree_index(VALUE self, VALUE value)
721
+ {
722
+ VALUE arg[2];
723
+ arg[0] = Qnil;
724
+ arg[1] = value;
725
+ rbtree_for_each(self, index_i, (void*)&arg);
726
+ return arg[0];
727
+ }
728
+
729
+ /*
730
+ *
731
+ */
732
+ VALUE
733
+ rbtree_clear(VALUE self)
734
+ {
735
+ rbtree_modify(self);
736
+ dict_free_nodes(DICT(self));
737
+ return self;
738
+ }
739
+
740
+ /*
741
+ *
742
+ */
743
+ VALUE
744
+ rbtree_delete(VALUE self, VALUE key)
745
+ {
746
+ dict_t* dict = DICT(self);
747
+ dnode_t* node;
748
+ VALUE value;
749
+
750
+ rbtree_modify(self);
751
+ node = dict_lookup(dict, TO_KEY(key));
752
+ if (node == NULL)
753
+ return rb_block_given_p() ? rb_yield(key) : Qnil;
754
+ value = GET_VAL(node);
755
+ dict_delete_free(dict, node);
756
+ return value;
757
+ }
758
+
759
+ /*********************************************************************/
760
+
761
+ typedef struct dnode_list_t_ {
762
+ struct dnode_list_t_* prev;
763
+ dnode_t* node;
764
+ } dnode_list_t;
765
+
766
+ typedef struct {
767
+ VALUE self;
768
+ dnode_list_t* list;
769
+ int raised;
770
+ } rbtree_delete_if_arg_t;
771
+
772
+ static VALUE
773
+ rbtree_delete_if_ensure(rbtree_delete_if_arg_t* arg)
774
+ {
775
+ dict_t* dict = DICT(arg->self);
776
+ dnode_list_t* list = arg->list;
777
+
778
+ if (--ITER_LEV(arg->self) == 0) {
779
+ while (list != NULL) {
780
+ dnode_list_t* l = list;
781
+ if (!arg->raised)
782
+ dict_delete_free(dict, l->node);
783
+ list = l->prev;
784
+ xfree(l);
785
+ }
786
+ }
787
+ return Qnil;
788
+ }
789
+
790
+ static VALUE
791
+ rbtree_delete_if_body(rbtree_delete_if_arg_t* arg)
792
+ {
793
+ VALUE self = arg->self;
794
+ dict_t* dict = DICT(self);
795
+ dnode_t* node;
796
+
797
+ arg->raised = 1;
798
+ ITER_LEV(self)++;
799
+ for (node = dict_first(dict);
800
+ node != NULL;
801
+ node = dict_next(dict, node)) {
802
+
803
+ if (RTEST(rb_yield_values(2, GET_KEY(node), GET_VAL(node)))) {
804
+ dnode_list_t* l = ALLOC(dnode_list_t);
805
+ l->node = node;
806
+ l->prev = arg->list;
807
+ arg->list = l;
808
+ }
809
+ }
810
+ arg->raised = 0;
811
+ return self;
812
+ }
813
+
814
+ /*********************************************************************/
815
+
816
+ /*
817
+ *
818
+ */
819
+ VALUE
820
+ rbtree_delete_if(VALUE self)
821
+ {
822
+ rbtree_delete_if_arg_t arg;
823
+
824
+ RETURN_ENUMERATOR(self, 0, NULL);
825
+ rbtree_modify(self);
826
+ arg.self = self;
827
+ arg.list = NULL;
828
+ return rb_ensure(rbtree_delete_if_body, (VALUE)&arg,
829
+ rbtree_delete_if_ensure, (VALUE)&arg);
830
+ }
831
+
832
+ /*
833
+ *
834
+ */
835
+ VALUE
836
+ rbtree_reject_bang(VALUE self)
837
+ {
838
+ dictcount_t count;
839
+
840
+ RETURN_ENUMERATOR(self, 0, NULL);
841
+ count = dict_count(DICT(self));
842
+ rbtree_delete_if(self);
843
+ if (count == dict_count(DICT(self)))
844
+ return Qnil;
845
+ return self;
846
+ }
847
+
848
+ /*
849
+ *
850
+ */
851
+ VALUE
852
+ rbtree_reject(VALUE self)
853
+ {
854
+ return rbtree_reject_bang(rb_obj_dup(self));
855
+ }
856
+
857
+ static VALUE
858
+ rbtree_shift_pop(VALUE self, const int shift)
859
+ {
860
+ dict_t* dict = DICT(self);
861
+ dnode_t* node;
862
+ VALUE ret;
863
+
864
+ rbtree_modify(self);
865
+
866
+ if (dict_isempty(dict)) {
867
+ if (FL_TEST(self, RBTREE_PROC_DEFAULT)) {
868
+ return rb_funcall(IFNONE(self), id_call, 2, self, Qnil);
869
+ }
870
+ return IFNONE(self);
871
+ }
872
+
873
+ if (shift)
874
+ node = dict_last(dict);
875
+ else
876
+ node = dict_first(dict);
877
+ ret = ASSOC(node);
878
+ dict_delete_free(dict, node);
879
+ return ret;
880
+ }
881
+
882
+ /*
883
+ * call-seq:
884
+ * rbtree.shift => array or object
885
+ *
886
+ * Removes the first(that is, the smallest) key-value pair and returns
887
+ * it as a two-item array.
888
+ */
889
+ VALUE
890
+ rbtree_shift(VALUE self)
891
+ {
892
+ return rbtree_shift_pop(self, 0);
893
+ }
894
+
895
+ /*
896
+ * call-seq:
897
+ * rbtree.pop => array or object
898
+ *
899
+ * Removes the last(that is, the biggest) key-value pair and returns
900
+ * it as a two-item array.
901
+ */
902
+ VALUE
903
+ rbtree_pop(VALUE self)
904
+ {
905
+ return rbtree_shift_pop(self, 1);
906
+ }
907
+
908
+ static each_return_t
909
+ invert_i(dnode_t* node, void* rbtree)
910
+ {
911
+ rbtree_aset((VALUE)rbtree, GET_VAL(node), GET_KEY(node));
912
+ return EACH_NEXT;
913
+ }
914
+
915
+ /*
916
+ *
917
+ */
918
+ VALUE
919
+ rbtree_invert(VALUE self)
920
+ {
921
+ VALUE rbtree = rbtree_alloc(CLASS_OF(self));
922
+ rbtree_for_each(self, invert_i, (void*)rbtree);
923
+ return rbtree;
924
+ }
925
+
926
+ static each_return_t
927
+ update_block_i(dnode_t* node, void* self_)
928
+ {
929
+ VALUE self = (VALUE)self_;
930
+ VALUE key = GET_KEY(node);
931
+ VALUE value = GET_VAL(node);
932
+
933
+ if (rbtree_has_key(self, key))
934
+ value = rb_yield_values(3, key, rbtree_aref(self, key), value);
935
+ rbtree_aset(self, key, value);
936
+ return EACH_NEXT;
937
+ }
938
+
939
+ /*
940
+ *
941
+ */
942
+ VALUE
943
+ rbtree_update(VALUE self, VALUE other)
944
+ {
945
+ rbtree_modify(self);
946
+
947
+ if (self == other)
948
+ return self;
949
+ if (!rb_obj_is_kind_of(other, CLASS_OF(self))) {
950
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
951
+ rb_class2name(CLASS_OF(other)),
952
+ rb_class2name(CLASS_OF(self)));
953
+ }
954
+
955
+ if (rb_block_given_p())
956
+ rbtree_for_each(other, update_block_i, (void*)self);
957
+ else
958
+ rbtree_for_each(other, aset_i, (void*)self);
959
+ return self;
960
+ }
961
+
962
+ /*
963
+ *
964
+ */
965
+ VALUE
966
+ rbtree_merge(VALUE self, VALUE other)
967
+ {
968
+ return rbtree_update(rb_obj_dup(self), other);
969
+ }
970
+
971
+ /*
972
+ *
973
+ */
974
+ VALUE
975
+ rbtree_has_key(VALUE self, VALUE key)
976
+ {
977
+ return dict_lookup(DICT(self), TO_KEY(key)) == NULL ? Qfalse : Qtrue;
978
+ }
979
+
980
+ static each_return_t
981
+ has_value_i(dnode_t* node, void* arg_)
982
+ {
983
+ VALUE* arg = (VALUE*)arg_;
984
+ if (rb_equal(GET_VAL(node), arg[1])) {
985
+ arg[0] = Qtrue;
986
+ return EACH_STOP;
987
+ }
988
+ return EACH_NEXT;
989
+ }
990
+
991
+ /*
992
+ *
993
+ */
994
+ VALUE
995
+ rbtree_has_value(VALUE self, VALUE value)
996
+ {
997
+ VALUE arg[2];
998
+ arg[0] = Qfalse;
999
+ arg[1] = value;
1000
+ rbtree_for_each(self, has_value_i, (void*)&arg);
1001
+ return arg[0];
1002
+ }
1003
+
1004
+ static each_return_t
1005
+ keys_i(dnode_t* node, void* ary)
1006
+ {
1007
+ rb_ary_push((VALUE)ary, GET_KEY(node));
1008
+ return EACH_NEXT;
1009
+ }
1010
+
1011
+ /*
1012
+ *
1013
+ */
1014
+ VALUE
1015
+ rbtree_keys(VALUE self)
1016
+ {
1017
+ VALUE ary = rb_ary_new();
1018
+ rbtree_for_each(self, keys_i, (void*)ary);
1019
+ return ary;
1020
+ }
1021
+
1022
+ static each_return_t
1023
+ values_i(dnode_t* node, void* ary)
1024
+ {
1025
+ rb_ary_push((VALUE)ary, GET_VAL(node));
1026
+ return EACH_NEXT;
1027
+ }
1028
+
1029
+ /*
1030
+ *
1031
+ */
1032
+ VALUE
1033
+ rbtree_values(VALUE self)
1034
+ {
1035
+ VALUE ret = rb_ary_new();
1036
+ rbtree_for_each(self, values_i, (void*)ret);
1037
+ return ret;
1038
+ }
1039
+
1040
+ static each_return_t
1041
+ to_a_i(dnode_t* node, void* ary)
1042
+ {
1043
+ rb_ary_push((VALUE)ary, ASSOC(node));
1044
+ return EACH_NEXT;
1045
+ }
1046
+
1047
+ /*
1048
+ *
1049
+ */
1050
+ VALUE
1051
+ rbtree_to_a(VALUE self)
1052
+ {
1053
+ VALUE ary = rb_ary_new();
1054
+ rbtree_for_each(self, to_a_i, (void*)ary);
1055
+ OBJ_INFECT(ary, self);
1056
+ return ary;
1057
+ }
1058
+
1059
+ static each_return_t
1060
+ to_hash_i(dnode_t* node, void* hash)
1061
+ {
1062
+ st_insert(RHASH_TBL((long)hash), GET_KEY(node), GET_VAL(node));
1063
+ return EACH_NEXT;
1064
+ }
1065
+
1066
+ /*
1067
+ *
1068
+ */
1069
+ VALUE
1070
+ rbtree_to_hash(VALUE self)
1071
+ {
1072
+ VALUE hash;
1073
+ if (CLASS_OF(self) == MultiRBTree) {
1074
+ rb_raise(rb_eTypeError, "can't convert MultiRBTree to Hash");
1075
+ }
1076
+
1077
+ hash = rb_hash_new();
1078
+ rbtree_for_each(self, to_hash_i, (void*)hash);
1079
+ if (FL_TEST(self, RBTREE_PROC_DEFAULT))
1080
+ FL_SET(hash, HASH_PROC_DEFAULT);
1081
+ OBJ_INFECT(hash, self);
1082
+ return hash;
1083
+ }
1084
+
1085
+ /*
1086
+ *
1087
+ */
1088
+ VALUE
1089
+ rbtree_to_rbtree(VALUE self)
1090
+ {
1091
+ return self;
1092
+ }
1093
+
1094
+ static VALUE
1095
+ rbtree_begin_inspect(VALUE self)
1096
+ {
1097
+ const char* c = rb_class2name(CLASS_OF(self));
1098
+ VALUE rb_str = rb_str_new(0, strlen(c) + 4);
1099
+ sprintf(RSTRING_PTR(rb_str), "#<%s: ", c);
1100
+ return rb_str;
1101
+ }
1102
+
1103
+ static VALUE
1104
+ to_s_rbtree(VALUE self, VALUE nil)
1105
+ {
1106
+ return rb_ary_to_s(rbtree_to_a(self));
1107
+ }
1108
+
1109
+ #ifdef HAVE_RB_EXEC_RECURSIVE
1110
+ VALUE
1111
+ rbtree_to_s_recursive(VALUE self, VALUE arg, int recursive)
1112
+ {
1113
+ if (recursive)
1114
+ rb_str_cat2(rbtree_begin_inspect(self), "...>");
1115
+ return to_s_rbtree(self, Qnil);
1116
+ }
1117
+ #endif
1118
+
1119
+ /*
1120
+ *
1121
+ */
1122
+ VALUE
1123
+ rbtree_to_s(VALUE self)
1124
+ {
1125
+ #ifdef HAVE_RB_EXEC_RECURSIVE
1126
+ return rb_exec_recursive(rbtree_to_s_recursive, self, Qnil);
1127
+ #else
1128
+ if (rb_inspecting_p(self))
1129
+ return rb_str_cat2(rbtree_begin_inspect(self), "...>");
1130
+ return rb_protect_inspect(to_s_rbtree, self, Qnil);
1131
+ #endif
1132
+ }
1133
+
1134
+ static each_return_t
1135
+ inspect_i(dnode_t* node, void* ret_)
1136
+ {
1137
+ VALUE ret = (VALUE)ret_;
1138
+ VALUE str;
1139
+
1140
+ if (RSTRING_PTR(ret)[0] == '-')
1141
+ RSTRING_PTR(ret)[0] = '#';
1142
+ else
1143
+ rb_str_cat2(ret, ", ");
1144
+
1145
+ str = rb_inspect(GET_KEY(node));
1146
+ rb_str_append(ret, str);
1147
+ OBJ_INFECT(ret, str);
1148
+
1149
+ rb_str_cat2(ret, "=>");
1150
+
1151
+ str = rb_inspect(GET_VAL(node));
1152
+ rb_str_append(ret, str);
1153
+ OBJ_INFECT(ret, str);
1154
+
1155
+ return EACH_NEXT;
1156
+ }
1157
+
1158
+ static VALUE
1159
+ inspect_rbtree(VALUE self, VALUE ret)
1160
+ {
1161
+ VALUE str;
1162
+
1163
+ rb_str_cat2(ret, "{");
1164
+ RSTRING_PTR(ret)[0] = '-';
1165
+ rbtree_for_each(self, inspect_i, (void*)ret);
1166
+ RSTRING_PTR(ret)[0] = '#';
1167
+ rb_str_cat2(ret, "}");
1168
+
1169
+ str = rb_inspect(IFNONE(self));
1170
+ rb_str_cat2(ret, ", default=");
1171
+ rb_str_append(ret, str);
1172
+ OBJ_INFECT(ret, str);
1173
+
1174
+ str = rb_inspect((VALUE)CONTEXT(self));
1175
+ rb_str_cat2(ret, ", cmp_proc=");
1176
+ rb_str_append(ret, str);
1177
+ OBJ_INFECT(ret, str);
1178
+
1179
+ rb_str_cat2(ret, ">");
1180
+ OBJ_INFECT(ret, self);
1181
+ return ret;
1182
+ }
1183
+
1184
+ #ifdef HAVE_RB_EXEC_RECURSIVE
1185
+ VALUE
1186
+ rbtree_inspect_recursive(VALUE self, VALUE arg, int recursive)
1187
+ {
1188
+ VALUE str = rbtree_begin_inspect(self);
1189
+ if (recursive)
1190
+ return rb_str_cat2(str, "...>");
1191
+ return inspect_rbtree(self, str);
1192
+ }
1193
+ #endif
1194
+
1195
+ /*
1196
+ *
1197
+ */
1198
+ VALUE
1199
+ rbtree_inspect(VALUE self)
1200
+ {
1201
+ #ifdef HAVE_RB_EXEC_RECURSIVE
1202
+ return rb_exec_recursive(rbtree_inspect_recursive, self, Qnil);
1203
+ #else
1204
+ VALUE str = rbtree_begin_inspect(self);
1205
+ if (rb_inspecting_p(self))
1206
+ return rb_str_cat2(str, "...>");
1207
+ return rb_protect_inspect(inspect_rbtree, self, str);
1208
+ #endif
1209
+ }
1210
+
1211
+ /*
1212
+ * call-seq:
1213
+ * rbtree.lower_bound(key) => array
1214
+ *
1215
+ * Retruns key-value pair corresponding to the lowest key that is
1216
+ * equal to or greater than the given key(inside of lower
1217
+ * boundary). If there is no such key, returns nil.
1218
+ */
1219
+ VALUE
1220
+ rbtree_lower_bound(VALUE self, VALUE key)
1221
+ {
1222
+ dnode_t* node = dict_lower_bound(DICT(self), TO_KEY(key));
1223
+ if (node == NULL)
1224
+ return Qnil;
1225
+ return ASSOC(node);
1226
+ }
1227
+
1228
+ /*
1229
+ * call-seq:
1230
+ * rbtree.upper_bound(key) => array
1231
+ *
1232
+ * Retruns key-value pair corresponding to the greatest key that is
1233
+ * equal to or lower than the given key(inside of upper boundary). If
1234
+ * there is no such key, returns nil.
1235
+ */
1236
+ VALUE
1237
+ rbtree_upper_bound(VALUE self, VALUE key)
1238
+ {
1239
+ dnode_t* node = dict_upper_bound(DICT(self), TO_KEY(key));
1240
+ if (node == NULL)
1241
+ return Qnil;
1242
+ return ASSOC(node);
1243
+ }
1244
+
1245
+ /*********************************************************************/
1246
+
1247
+ typedef struct {
1248
+ VALUE self;
1249
+ dnode_t* lower_node;
1250
+ dnode_t* upper_node;
1251
+ VALUE ret;
1252
+ } rbtree_bound_arg_t;
1253
+
1254
+ static VALUE
1255
+ rbtree_bound_body(rbtree_bound_arg_t* arg)
1256
+ {
1257
+ VALUE self = arg->self;
1258
+ dict_t* dict = DICT(self);
1259
+ dnode_t* lower_node = arg->lower_node;
1260
+ dnode_t* upper_node = arg->upper_node;
1261
+ const int block_given = rb_block_given_p();
1262
+ VALUE ret = arg->ret;
1263
+ dnode_t* node;
1264
+
1265
+ ITER_LEV(self)++;
1266
+ for (node = lower_node;;
1267
+ node = dict_next(dict, node)) {
1268
+
1269
+ if (block_given)
1270
+ rb_yield_values(2, GET_KEY(node), GET_VAL(node));
1271
+ else
1272
+ rb_ary_push(ret, ASSOC(node));
1273
+ if (node == upper_node)
1274
+ break;
1275
+ }
1276
+ return ret;
1277
+ }
1278
+
1279
+ /*********************************************************************/
1280
+
1281
+ /*
1282
+ * call-seq:
1283
+ * rbtree.bound(key1, key2 = key1) => array
1284
+ * rbtree.bound(key1, key2 = key1) {|key, value| block} => rbtree
1285
+ *
1286
+ * Returns an array containing key-value pairs between the result of
1287
+ * MultiRBTree#lower_bound and MultiRBTree#upper_bound. If a block is
1288
+ * given it calls the block once for each pair.
1289
+ */
1290
+ VALUE
1291
+ rbtree_bound(int argc, VALUE* argv, VALUE self)
1292
+ {
1293
+ dict_t* dict = DICT(self);
1294
+ dnode_t* lower_node;
1295
+ dnode_t* upper_node;
1296
+ VALUE ret;
1297
+
1298
+ if (argc == 0 || argc > 2)
1299
+ rbtree_argc_error();
1300
+
1301
+ lower_node = dict_lower_bound(dict, TO_KEY(argv[0]));
1302
+ upper_node = dict_upper_bound(dict, TO_KEY(argv[argc - 1]));
1303
+ ret = rb_block_given_p() ? self : rb_ary_new();
1304
+
1305
+ if (lower_node == NULL || upper_node == NULL ||
1306
+ COMPARE(self)(dnode_getkey(lower_node),
1307
+ dnode_getkey(upper_node),
1308
+ CONTEXT(self)) > 0) {
1309
+ return ret;
1310
+ } else {
1311
+ rbtree_bound_arg_t arg;
1312
+ arg.self = self;
1313
+ arg.lower_node = lower_node;
1314
+ arg.upper_node = upper_node;
1315
+ arg.ret = ret;
1316
+
1317
+ return rb_ensure(rbtree_bound_body, (VALUE)&arg,
1318
+ rbtree_each_ensure, self);
1319
+ }
1320
+ }
1321
+
1322
+ static VALUE
1323
+ rbtree_first_last(VALUE self, const int first)
1324
+ {
1325
+ dict_t* dict = DICT(self);
1326
+ dnode_t* node;
1327
+
1328
+ if (dict_isempty(dict)) {
1329
+ if (FL_TEST(self, RBTREE_PROC_DEFAULT)) {
1330
+ return rb_funcall(IFNONE(self), id_call, 2, self, Qnil);
1331
+ }
1332
+ return IFNONE(self);
1333
+ }
1334
+
1335
+ if (first)
1336
+ node = dict_first(dict);
1337
+ else
1338
+ node = dict_last(dict);
1339
+ return ASSOC(node);
1340
+ }
1341
+
1342
+ /*
1343
+ * call-seq:
1344
+ * rbtree.first => array or object
1345
+ *
1346
+ * Returns the first(that is, the smallest) key-value pair.
1347
+ */
1348
+ VALUE
1349
+ rbtree_first(VALUE self)
1350
+ {
1351
+ return rbtree_first_last(self, 1);
1352
+ }
1353
+
1354
+ /*
1355
+ * call-seq:
1356
+ * rbtree.last => array of object
1357
+ *
1358
+ * Returns the last(that is, the biggest) key-value pair.
1359
+ */
1360
+ VALUE
1361
+ rbtree_last(VALUE self)
1362
+ {
1363
+ return rbtree_first_last(self, 0);
1364
+ }
1365
+
1366
+ /*
1367
+ * call-seq:
1368
+ * rbtree.readjust => rbtree
1369
+ * rbtree.readjust(nil) => rbtree
1370
+ * rbtree.readjust(proc) => rbtree
1371
+ * rbtree.readjust {|key1, key2| block} => rbtree
1372
+ *
1373
+ * Sets a proc to compare keys and readjusts elements using the given
1374
+ * block or a Proc object given as the argument. The block takes two
1375
+ * arguments of a key and returns negative, 0, or positive depending
1376
+ * on the first argument is less than, equal to, or greater than the
1377
+ * second one. If no block is given it just readjusts elements using
1378
+ * current comparison block. If nil is given as the argument it sets
1379
+ * default comparison block.
1380
+ */
1381
+ VALUE
1382
+ rbtree_readjust(int argc, VALUE* argv, VALUE self)
1383
+ {
1384
+ dict_comp_t cmp = NULL;
1385
+ void* context = NULL;
1386
+
1387
+ rbtree_modify(self);
1388
+
1389
+ if (argc == 0) {
1390
+ if (rb_block_given_p()) {
1391
+ cmp = rbtree_user_cmp;
1392
+ context = (void*)rb_block_proc();
1393
+ } else {
1394
+ cmp = COMPARE(self);
1395
+ context = CONTEXT(self);
1396
+ }
1397
+ } else if (argc == 1 && !rb_block_given_p()) {
1398
+ if (argv[0] == Qnil) {
1399
+ cmp = rbtree_cmp;
1400
+ context = (void*)Qnil;
1401
+ } else {
1402
+ if (CLASS_OF(argv[0]) != rb_cProc)
1403
+ rb_raise(rb_eTypeError,
1404
+ "wrong argument type %s (expected Proc)",
1405
+ rb_class2name(CLASS_OF(argv[0])));
1406
+ cmp = rbtree_user_cmp;
1407
+ context = (void*)argv[0];
1408
+ }
1409
+ } else {
1410
+ rbtree_argc_error();
1411
+ }
1412
+
1413
+ if (dict_isempty(DICT(self))) {
1414
+ COMPARE(self) = cmp;
1415
+ CONTEXT(self) = context;
1416
+ return self;
1417
+ }
1418
+ copy_dict(self, self, cmp, context);
1419
+ return self;
1420
+ }
1421
+
1422
+ /*
1423
+ * call-seq:
1424
+ * rbtree.cmp_proc => proc
1425
+ *
1426
+ * Returns the comparison block that is given by MultiRBTree#readjust.
1427
+ */
1428
+ VALUE
1429
+ rbtree_cmp_proc(VALUE self)
1430
+ {
1431
+ return (VALUE)(CONTEXT(self));
1432
+ }
1433
+
1434
+ /*********************************************************************/
1435
+
1436
+ static ID id_comma_breakable;
1437
+ static ID id_object_group;
1438
+ static ID id_pp;
1439
+ static ID id_pp_hash;
1440
+ static ID id_text;
1441
+
1442
+ typedef struct {
1443
+ VALUE rbtree;
1444
+ VALUE pp;
1445
+ } pp_arg_t;
1446
+
1447
+ static VALUE
1448
+ pp_object_group(VALUE arg_)
1449
+ {
1450
+ pp_arg_t* arg = (pp_arg_t*)arg_;
1451
+ return rb_funcall(arg->pp, id_object_group, 1, arg->rbtree);
1452
+ }
1453
+
1454
+ static VALUE
1455
+ pp_block(VALUE nil, pp_arg_t* arg)
1456
+ {
1457
+ VALUE pp = arg->pp;
1458
+ VALUE rbtree = arg->rbtree;
1459
+
1460
+ rb_funcall(pp, id_text, 1, rb_str_new2(": "));
1461
+ rb_funcall(pp, id_pp_hash, 1, rbtree);
1462
+ rb_funcall(pp, id_comma_breakable, 0);
1463
+ rb_funcall(pp, id_text, 1, rb_str_new2("default="));
1464
+ rb_funcall(pp, id_pp, 1, IFNONE(rbtree));
1465
+ rb_funcall(pp, id_comma_breakable, 0);
1466
+ rb_funcall(pp, id_text, 1, rb_str_new2("cmp_proc="));
1467
+ rb_funcall(pp, id_pp, 1, CONTEXT(rbtree));
1468
+ return pp;
1469
+ }
1470
+
1471
+ /*********************************************************************/
1472
+
1473
+ /*
1474
+ * Called by pretty printing function pp.
1475
+ */
1476
+ VALUE
1477
+ rbtree_pretty_print(VALUE self, VALUE pp)
1478
+ {
1479
+ pp_arg_t pp_arg;
1480
+ pp_arg.rbtree = self;
1481
+ pp_arg.pp = pp;
1482
+
1483
+ return rb_iterate(pp_object_group, (VALUE)&pp_arg,
1484
+ pp_block, (VALUE)&pp_arg);
1485
+ }
1486
+
1487
+ /*
1488
+ * Called by pretty printing function pp.
1489
+ */
1490
+ VALUE
1491
+ rbtree_pretty_print_cycle(VALUE self, VALUE pp)
1492
+ {
1493
+ #ifdef HAVE_RB_EXEC_RECURSIVE
1494
+ return rb_funcall(pp, id_pp, 1, rbtree_inspect_recursive(self, Qnil, 1));
1495
+ #else
1496
+ return rb_funcall(pp, id_pp, 1, rbtree_inspect(self));
1497
+ #endif
1498
+ }
1499
+
1500
+ /*********************************************************************/
1501
+
1502
+ static each_return_t
1503
+ to_flatten_ary_i(dnode_t* node, void* ary)
1504
+ {
1505
+ rb_ary_push((VALUE)ary, GET_KEY(node));
1506
+ rb_ary_push((VALUE)ary, GET_VAL(node));
1507
+ return EACH_NEXT;
1508
+ }
1509
+
1510
+ /*********************************************************************/
1511
+
1512
+ /*
1513
+ * Called by Marshal.dump.
1514
+ */
1515
+ VALUE
1516
+ rbtree_dump(VALUE self, VALUE _limit)
1517
+ {
1518
+ VALUE ary;
1519
+ VALUE ret;
1520
+
1521
+ if (FL_TEST(self, RBTREE_PROC_DEFAULT))
1522
+ rb_raise(rb_eTypeError, "cannot dump rbtree with default proc");
1523
+ if ((VALUE)CONTEXT(self) != Qnil)
1524
+ rb_raise(rb_eTypeError, "cannot dump rbtree with compare proc");
1525
+
1526
+ ary = rb_ary_new2(dict_count(DICT(self)) * 2 + 1);
1527
+ rbtree_for_each(self, to_flatten_ary_i, (void*)ary);
1528
+ rb_ary_push(ary, IFNONE(self));
1529
+
1530
+ ret = rb_marshal_dump(ary, Qnil);
1531
+ rb_ary_clear(ary);
1532
+ rb_gc_force_recycle(ary);
1533
+ return ret;
1534
+ }
1535
+
1536
+ /*
1537
+ * Called by Marshal.load.
1538
+ */
1539
+ VALUE
1540
+ rbtree_s_load(VALUE klass, VALUE str)
1541
+ {
1542
+ VALUE rbtree = rbtree_alloc(klass);
1543
+ VALUE ary = rb_marshal_load(str);
1544
+ VALUE* ptr = RARRAY_PTR(ary);
1545
+ long len = RARRAY_LEN(ary) - 1;
1546
+ long i;
1547
+
1548
+ for (i = 0; i < len; i += 2)
1549
+ rbtree_aset(rbtree, ptr[i], ptr[i + 1]);
1550
+ IFNONE(rbtree) = ptr[len];
1551
+
1552
+ rb_ary_clear(ary);
1553
+ rb_gc_force_recycle(ary);
1554
+ return rbtree;
1555
+ }
1556
+
1557
+ /*********************************************************************/
1558
+
1559
+ /*
1560
+ * RBTree is a sorted associative collection that is implemented with
1561
+ * Red-Black Tree. The elements of RBTree are ordered and its interface
1562
+ * is the almost same as Hash, so simply you can consider RBTree sorted
1563
+ * Hash.
1564
+ *
1565
+ * Red-Black Tree is a kind of binary tree that automatically balances
1566
+ * by itself when a node is inserted or deleted. Thus the complexity
1567
+ * for insert, search and delete is O(log N) in expected and worst
1568
+ * case. On the other hand the complexity of Hash is O(1). Because
1569
+ * Hash is unordered the data structure is more effective than
1570
+ * Red-Black Tree as an associative collection.
1571
+ *
1572
+ * The elements of RBTree are sorted with natural ordering (by <=>
1573
+ * method) of its keys or by a comparator(Proc) set by readjust
1574
+ * method. It means all keys in RBTree should be comparable with each
1575
+ * other. Or a comparator that takes two arguments of a key should return
1576
+ * negative, 0, or positive depending on the first argument is less than,
1577
+ * equal to, or greater than the second one.
1578
+ *
1579
+ * The interface of RBTree is the almost same as Hash and there are a
1580
+ * few methods to take advantage of the ordering:
1581
+ *
1582
+ * * lower_bound, upper_bound, bound
1583
+ * * first, last
1584
+ * * shift, pop
1585
+ * * reverse_each
1586
+ *
1587
+ * Note: while iterating RBTree (e.g. in a block of each method), it is
1588
+ * not modifiable, or TypeError is thrown.
1589
+ *
1590
+ * RBTree supoorts pretty printing using pp.
1591
+ *
1592
+ * This library contains two classes. One is RBTree and the other is
1593
+ * MultiRBTree that is a parent class of RBTree. RBTree does not allow
1594
+ * duplications of keys but MultiRBTree does.
1595
+ *
1596
+ * require "rbtree"
1597
+ *
1598
+ * rbtree = RBTree["c", 10, "a", 20]
1599
+ * rbtree["b"] = 30
1600
+ * p rbtree["b"] # => 30
1601
+ * rbtree.each do |k, v|
1602
+ * p [k, v]
1603
+ * end # => ["a", 20] ["b", 30] ["c", 10]
1604
+ *
1605
+ * mrbtree = MultiRBTree["c", 10, "a", 20, "e", 30, "a", 40]
1606
+ * p mrbtree.lower_bound("b") # => ["c", 10]
1607
+ * mrbtree.bound("a", "d") do |k, v|
1608
+ * p [k, v]
1609
+ * end # => ["a", 20] ["a", 40] ["c", 10]
1610
+ */
1611
+ void Init_rbtree()
1612
+ {
1613
+ MultiRBTree = rb_define_class("MultiRBTree", rb_cData);
1614
+ RBTree = rb_define_class("RBTree", MultiRBTree);
1615
+
1616
+ rb_include_module(MultiRBTree, rb_mEnumerable);
1617
+
1618
+ rb_define_alloc_func(MultiRBTree, rbtree_alloc);
1619
+
1620
+ rb_define_singleton_method(MultiRBTree, "[]", rbtree_s_create, -1);
1621
+
1622
+ rb_define_method(MultiRBTree, "initialize", rbtree_initialize, -1);
1623
+ rb_define_method(MultiRBTree, "initialize_copy", rbtree_initialize_copy, 1);
1624
+
1625
+ rb_define_method(MultiRBTree, "to_a", rbtree_to_a, 0);
1626
+ rb_define_method(MultiRBTree, "to_s", rbtree_to_s, 0);
1627
+ rb_define_method(MultiRBTree, "to_hash", rbtree_to_hash, 0);
1628
+ rb_define_method(MultiRBTree, "to_rbtree", rbtree_to_rbtree, 0);
1629
+ rb_define_method(MultiRBTree, "inspect", rbtree_inspect, 0);
1630
+
1631
+ rb_define_method(MultiRBTree, "==", rbtree_equal, 1);
1632
+ rb_define_method(MultiRBTree, "[]", rbtree_aref, 1);
1633
+ rb_define_method(MultiRBTree, "fetch", rbtree_fetch, -1);
1634
+ rb_define_method(MultiRBTree, "lower_bound", rbtree_lower_bound, 1);
1635
+ rb_define_method(MultiRBTree, "upper_bound", rbtree_upper_bound, 1);
1636
+ rb_define_method(MultiRBTree, "bound", rbtree_bound, -1);
1637
+ rb_define_method(MultiRBTree, "first", rbtree_first, 0);
1638
+ rb_define_method(MultiRBTree, "last", rbtree_last, 0);
1639
+ rb_define_method(MultiRBTree, "[]=", rbtree_aset, 2);
1640
+ rb_define_method(MultiRBTree, "store", rbtree_aset, 2);
1641
+ rb_define_method(MultiRBTree, "default", rbtree_default, -1);
1642
+ rb_define_method(MultiRBTree, "default=", rbtree_set_default, 1);
1643
+ rb_define_method(MultiRBTree, "default_proc", rbtree_default_proc, 0);
1644
+ rb_define_method(MultiRBTree, "index", rbtree_index, 1);
1645
+ rb_define_method(MultiRBTree, "empty?", rbtree_empty_p, 0);
1646
+ rb_define_method(MultiRBTree, "size", rbtree_size, 0);
1647
+ rb_define_method(MultiRBTree, "length", rbtree_size, 0);
1648
+
1649
+ rb_define_method(MultiRBTree, "each", rbtree_each, 0);
1650
+ rb_define_method(MultiRBTree, "each_value", rbtree_each_value, 0);
1651
+ rb_define_method(MultiRBTree, "each_key", rbtree_each_key, 0);
1652
+ rb_define_method(MultiRBTree, "each_pair", rbtree_each_pair, 0);
1653
+ rb_define_method(MultiRBTree, "reverse_each", rbtree_reverse_each, 0);
1654
+
1655
+ rb_define_method(MultiRBTree, "keys", rbtree_keys, 0);
1656
+ rb_define_method(MultiRBTree, "values", rbtree_values, 0);
1657
+ rb_define_method(MultiRBTree, "values_at", rbtree_values_at, -1);
1658
+
1659
+ rb_define_method(MultiRBTree, "shift", rbtree_shift, 0);
1660
+ rb_define_method(MultiRBTree, "pop", rbtree_pop, 0);
1661
+ rb_define_method(MultiRBTree, "delete", rbtree_delete, 1);
1662
+ rb_define_method(MultiRBTree, "delete_if", rbtree_delete_if, 0);
1663
+ rb_define_method(MultiRBTree, "select", rbtree_select, 0);
1664
+ rb_define_method(MultiRBTree, "reject", rbtree_reject, 0);
1665
+ rb_define_method(MultiRBTree, "reject!", rbtree_reject_bang, 0);
1666
+ rb_define_method(MultiRBTree, "clear", rbtree_clear, 0);
1667
+ rb_define_method(MultiRBTree, "invert", rbtree_invert, 0);
1668
+ rb_define_method(MultiRBTree, "update", rbtree_update, 1);
1669
+ rb_define_method(MultiRBTree, "merge!", rbtree_update, 1);
1670
+ rb_define_method(MultiRBTree, "merge", rbtree_merge, 1);
1671
+ rb_define_method(MultiRBTree, "replace", rbtree_initialize_copy, 1);
1672
+
1673
+ rb_define_method(MultiRBTree, "include?", rbtree_has_key, 1);
1674
+ rb_define_method(MultiRBTree, "member?", rbtree_has_key, 1);
1675
+ rb_define_method(MultiRBTree, "has_key?", rbtree_has_key, 1);
1676
+ rb_define_method(MultiRBTree, "has_value?", rbtree_has_value, 1);
1677
+ rb_define_method(MultiRBTree, "key?", rbtree_has_key, 1);
1678
+ rb_define_method(MultiRBTree, "value?", rbtree_has_value, 1);
1679
+
1680
+ rb_define_method(MultiRBTree, "readjust", rbtree_readjust, -1);
1681
+ rb_define_method(MultiRBTree, "cmp_proc", rbtree_cmp_proc, 0);
1682
+
1683
+ rb_define_method(MultiRBTree, "_dump", rbtree_dump, 1);
1684
+ rb_define_singleton_method(MultiRBTree, "_load", rbtree_s_load, 1);
1685
+
1686
+ id_bound = rb_intern("bound");
1687
+ id_cmp = rb_intern("<=>");
1688
+ id_call = rb_intern("call");
1689
+ id_default = rb_intern("default");
1690
+
1691
+
1692
+ rb_define_method(MultiRBTree, "pretty_print", rbtree_pretty_print, 1);
1693
+ rb_define_method(MultiRBTree,
1694
+ "pretty_print_cycle", rbtree_pretty_print_cycle, 1);
1695
+
1696
+ id_comma_breakable = rb_intern("comma_breakable");
1697
+ id_object_group = rb_intern("object_group");
1698
+ id_pp_hash = rb_intern("pp_hash");
1699
+ id_text = rb_intern("text");
1700
+ id_pp = rb_intern("pp");
1701
+ }