archipelago_rbtree 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ }