archipelago_rbtree 0.2.6

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