rbtree-pure 0.1.0

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