rbtree-pure 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,123 +0,0 @@
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
@@ -1,1706 +0,0 @@
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
- }