rbtree3 0.5.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.
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
+ }