rbtree-pure 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -0,0 +1,67 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rbtree-pure}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{Victor Costan}]
12
+ s.date = %q{2011-07-27}
13
+ s.description = %q{This is a pure-ruby implementation of the rbtree gem.}
14
+ s.email = %q{victor@costan.us}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".project",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/rbtree.rb",
29
+ "lib/rbtree/guard_node.rb",
30
+ "lib/rbtree/multi_rb_tree.rb",
31
+ "lib/rbtree/node.rb",
32
+ "lib/rbtree/rb_tree.rb",
33
+ "lib/rbtree/tree.rb",
34
+ "lib/rbtree/tree_cmp.rb",
35
+ "rbtree-pure.gemspec",
36
+ "test/helper.rb",
37
+ "test/multi_rbtree_test.rb",
38
+ "test/rbtree_test.rb"
39
+ ]
40
+ s.homepage = %q{http://github.com/pwnall/rbtree-pure}
41
+ s.licenses = [%q{MIT}]
42
+ s.require_paths = [%q{lib}]
43
+ s.rubygems_version = %q{1.8.5}
44
+ s.summary = %q{Pure-ruby implementation of red-black trees.}
45
+
46
+ if s.respond_to? :specification_version then
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
51
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
52
+ s.add_development_dependency(%q<rcov>, [">= 0"])
53
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
54
+ else
55
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
56
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
57
+ s.add_dependency(%q<rcov>, [">= 0"])
58
+ s.add_dependency(%q<rdoc>, [">= 0"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
62
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
63
+ s.add_dependency(%q<rcov>, [">= 0"])
64
+ s.add_dependency(%q<rdoc>, [">= 0"])
65
+ end
66
+ end
67
+
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbtree-pure
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Victor Costan
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-09 00:00:00 Z
18
+ date: 2011-07-27 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  version_requirements: &id001 !ruby/object:Gem::Requirement
@@ -102,9 +102,7 @@ files:
102
102
  - lib/rbtree/rb_tree.rb
103
103
  - lib/rbtree/tree.rb
104
104
  - lib/rbtree/tree_cmp.rb
105
- - old_ext/dict.c
106
- - old_ext/dict.h
107
- - old_ext/rbtree.c
105
+ - rbtree-pure.gemspec
108
106
  - test/helper.rb
109
107
  - test/multi_rbtree_test.rb
110
108
  - test/rbtree_test.rb
@@ -1,1216 +0,0 @@
1
- /*
2
- * Dictionary Abstract Data Type
3
- * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
4
- *
5
- * Free Software License:
6
- *
7
- * All rights are reserved by the author, with the following exceptions:
8
- * Permission is granted to freely reproduce and distribute this software,
9
- * possibly in exchange for a fee, provided that this copyright notice appears
10
- * intact. Permission is also granted to adapt this software to produce
11
- * derivative works, as long as the modified versions carry this copyright
12
- * notice and additional notices stating that the work has been modified.
13
- * This source code may be translated into executable form and incorporated
14
- * into proprietary software; there is no requirement for such software to
15
- * contain a copyright notice related to this source.
16
- *
17
- * $Id: dict.c,v 1.15 2005/10/06 05:16:35 kuma Exp $
18
- * $Name: $
19
- */
20
-
21
- /*
22
- * Modified for Ruby/RBTree by OZAWA Takuma.
23
- */
24
-
25
- #include <stdlib.h>
26
- #include <stddef.h>
27
- #include <assert.h>
28
- #include "dict.h"
29
-
30
- #include <ruby.h>
31
-
32
- #ifdef KAZLIB_RCSID
33
- static const char rcsid[] = "$Id: dict.c,v 1.15 2005/10/06 05:16:35 kuma Exp $";
34
- #endif
35
-
36
- /*
37
- * These macros provide short convenient names for structure members,
38
- * which are embellished with dict_ prefixes so that they are
39
- * properly confined to the documented namespace. It's legal for a
40
- * program which uses dict to define, for instance, a macro called ``parent''.
41
- * Such a macro would interfere with the dnode_t struct definition.
42
- * In general, highly portable and reusable C modules which expose their
43
- * structures need to confine structure member names to well-defined spaces.
44
- * The resulting identifiers aren't necessarily convenient to use, nor
45
- * readable, in the implementation, however!
46
- */
47
-
48
- #define left dict_left
49
- #define right dict_right
50
- #define parent dict_parent
51
- #define color dict_color
52
- #define key dict_key
53
- #define data dict_data
54
-
55
- #define nilnode dict_nilnode
56
- #define nodecount dict_nodecount
57
- #define compare dict_compare
58
- #define allocnode dict_allocnode
59
- #define freenode dict_freenode
60
- #define context dict_context
61
- #define dupes dict_dupes
62
-
63
- #define dictptr dict_dictptr
64
-
65
- #define dict_root(D) ((D)->nilnode.left)
66
- #define dict_nil(D) (&(D)->nilnode)
67
- #define DICT_DEPTH_MAX 64
68
-
69
- #define COMPARE(dict, key1, key2) dict->compare(key1, key2, dict->context)
70
-
71
- static dnode_t *dnode_alloc(void *context);
72
- static void dnode_free(dnode_t *node, void *context);
73
-
74
- /*
75
- * Perform a ``left rotation'' adjustment on the tree. The given node P and
76
- * its right child C are rearranged so that the P instead becomes the left
77
- * child of C. The left subtree of C is inherited as the new right subtree
78
- * for P. The ordering of the keys within the tree is thus preserved.
79
- */
80
-
81
- static void rotate_left(dnode_t *upper)
82
- {
83
- dnode_t *lower, *lowleft, *upparent;
84
-
85
- lower = upper->right;
86
- upper->right = lowleft = lower->left;
87
- lowleft->parent = upper;
88
-
89
- lower->parent = upparent = upper->parent;
90
-
91
- /* don't need to check for root node here because root->parent is
92
- the sentinel nil node, and root->parent->left points back to root */
93
-
94
- if (upper == upparent->left) {
95
- upparent->left = lower;
96
- } else {
97
- assert (upper == upparent->right);
98
- upparent->right = lower;
99
- }
100
-
101
- lower->left = upper;
102
- upper->parent = lower;
103
- }
104
-
105
- /*
106
- * This operation is the ``mirror'' image of rotate_left. It is
107
- * the same procedure, but with left and right interchanged.
108
- */
109
-
110
- static void rotate_right(dnode_t *upper)
111
- {
112
- dnode_t *lower, *lowright, *upparent;
113
-
114
- lower = upper->left;
115
- upper->left = lowright = lower->right;
116
- lowright->parent = upper;
117
-
118
- lower->parent = upparent = upper->parent;
119
-
120
- if (upper == upparent->right) {
121
- upparent->right = lower;
122
- } else {
123
- assert (upper == upparent->left);
124
- upparent->left = lower;
125
- }
126
-
127
- lower->right = upper;
128
- upper->parent = lower;
129
- }
130
-
131
- /*
132
- * Do a postorder traversal of the tree rooted at the specified
133
- * node and free everything under it. Used by dict_free().
134
- */
135
-
136
- static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
137
- {
138
- if (node == nil)
139
- return;
140
- free_nodes(dict, node->left, nil);
141
- free_nodes(dict, node->right, nil);
142
- dict->freenode(node, dict->context);
143
- }
144
-
145
- /*
146
- * This procedure performs a verification that the given subtree is a binary
147
- * search tree. It performs an inorder traversal of the tree using the
148
- * dict_next() successor function, verifying that the key of each node is
149
- * strictly lower than that of its successor, if duplicates are not allowed,
150
- * or lower or equal if duplicates are allowed. This function is used for
151
- * debugging purposes.
152
- */
153
-
154
- static int verify_bintree(dict_t *dict)
155
- {
156
- dnode_t *first, *next;
157
-
158
- first = dict_first(dict);
159
-
160
- if (dict->dupes) {
161
- while (first && (next = dict_next(dict, first))) {
162
- if (COMPARE(dict, first->key, next->key) > 0)
163
- return 0;
164
- first = next;
165
- }
166
- } else {
167
- while (first && (next = dict_next(dict, first))) {
168
- if (COMPARE(dict, first->key, next->key) >= 0)
169
- return 0;
170
- first = next;
171
- }
172
- }
173
- return 1;
174
- }
175
-
176
-
177
- /*
178
- * This function recursively verifies that the given binary subtree satisfies
179
- * three of the red black properties. It checks that every red node has only
180
- * black children. It makes sure that each node is either red or black. And it
181
- * checks that every path has the same count of black nodes from root to leaf.
182
- * It returns the blackheight of the given subtree; this allows blackheights to
183
- * be computed recursively and compared for left and right siblings for
184
- * mismatches. It does not check for every nil node being black, because there
185
- * is only one sentinel nil node. The return value of this function is the
186
- * black height of the subtree rooted at the node ``root'', or zero if the
187
- * subtree is not red-black.
188
- */
189
-
190
- static unsigned int verify_redblack(dnode_t *nil, dnode_t *root)
191
- {
192
- unsigned height_left, height_right;
193
-
194
- if (root != nil) {
195
- height_left = verify_redblack(nil, root->left);
196
- height_right = verify_redblack(nil, root->right);
197
- if (height_left == 0 || height_right == 0)
198
- return 0;
199
- if (height_left != height_right)
200
- return 0;
201
- if (root->color == dnode_red) {
202
- if (root->left->color != dnode_black)
203
- return 0;
204
- if (root->right->color != dnode_black)
205
- return 0;
206
- return height_left;
207
- }
208
- if (root->color != dnode_black)
209
- return 0;
210
- return height_left + 1;
211
- }
212
- return 1;
213
- }
214
-
215
- /*
216
- * Compute the actual count of nodes by traversing the tree and
217
- * return it. This could be compared against the stored count to
218
- * detect a mismatch.
219
- */
220
-
221
- static dictcount_t verify_node_count(dnode_t *nil, dnode_t *root)
222
- {
223
- if (root == nil)
224
- return 0;
225
- else
226
- return 1 + verify_node_count(nil, root->left)
227
- + verify_node_count(nil, root->right);
228
- }
229
-
230
- /*
231
- * Verify that the tree contains the given node. This is done by
232
- * traversing all of the nodes and comparing their pointers to the
233
- * given pointer. Returns 1 if the node is found, otherwise
234
- * returns zero. It is intended for debugging purposes.
235
- */
236
-
237
- static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
238
- {
239
- if (root != nil) {
240
- return root == node
241
- || verify_dict_has_node(nil, root->left, node)
242
- || verify_dict_has_node(nil, root->right, node);
243
- }
244
- return 0;
245
- }
246
-
247
-
248
- /*
249
- * Dynamically allocate and initialize a dictionary object.
250
- */
251
-
252
- dict_t *dict_create(dict_comp_t comp)
253
- {
254
- dict_t* new = ALLOC(dict_t);
255
-
256
- if (new) {
257
- new->compare = comp;
258
- new->allocnode = dnode_alloc;
259
- new->freenode = dnode_free;
260
- new->context = NULL;
261
- new->nodecount = 0;
262
- new->nilnode.left = &new->nilnode;
263
- new->nilnode.right = &new->nilnode;
264
- new->nilnode.parent = &new->nilnode;
265
- new->nilnode.color = dnode_black;
266
- new->dupes = 0;
267
- }
268
- return new;
269
- }
270
-
271
- /*
272
- * Select a different set of node allocator routines.
273
- */
274
-
275
- void dict_set_allocator(dict_t *dict, dnode_alloc_t al,
276
- dnode_free_t fr, void *context)
277
- {
278
- assert (dict_count(dict) == 0);
279
- assert ((al == NULL && fr == NULL) || (al != NULL && fr != NULL));
280
-
281
- dict->allocnode = al ? al : dnode_alloc;
282
- dict->freenode = fr ? fr : dnode_free;
283
- dict->context = context;
284
- }
285
-
286
- /*
287
- * Free a dynamically allocated dictionary object. Removing the nodes
288
- * from the tree before deleting it is required.
289
- */
290
-
291
- void dict_destroy(dict_t *dict)
292
- {
293
- assert (dict_isempty(dict));
294
- xfree(dict);
295
- }
296
-
297
- /*
298
- * Free all the nodes in the dictionary by using the dictionary's
299
- * installed free routine. The dictionary is emptied.
300
- */
301
-
302
- void dict_free_nodes(dict_t *dict)
303
- {
304
- dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
305
- free_nodes(dict, root, nil);
306
- dict->nodecount = 0;
307
- dict->nilnode.left = &dict->nilnode;
308
- dict->nilnode.right = &dict->nilnode;
309
- dict->nilnode.parent = &dict->nilnode;
310
- }
311
-
312
- /*
313
- * Obsolescent function, equivalent to dict_free_nodes
314
- */
315
-
316
- void dict_free(dict_t *dict)
317
- {
318
- #ifdef KAZLIB_OBSOLESCENT_DEBUG
319
- assert ("call to obsolescent function dict_free()" && 0);
320
- #endif
321
- dict_free_nodes(dict);
322
- }
323
-
324
- /*
325
- * Initialize a user-supplied dictionary object.
326
- */
327
-
328
- dict_t *dict_init(dict_t *dict, dict_comp_t comp)
329
- {
330
- dict->compare = comp;
331
- dict->allocnode = dnode_alloc;
332
- dict->freenode = dnode_free;
333
- dict->context = NULL;
334
- dict->nodecount = 0;
335
- dict->nilnode.left = &dict->nilnode;
336
- dict->nilnode.right = &dict->nilnode;
337
- dict->nilnode.parent = &dict->nilnode;
338
- dict->nilnode.color = dnode_black;
339
- dict->dupes = 0;
340
- return dict;
341
- }
342
-
343
- /*
344
- * Initialize a dictionary in the likeness of another dictionary
345
- */
346
-
347
- void dict_init_like(dict_t *dict, const dict_t *template)
348
- {
349
- dict->compare = template->compare;
350
- dict->allocnode = template->allocnode;
351
- dict->freenode = template->freenode;
352
- dict->context = template->context;
353
- dict->nodecount = 0;
354
- dict->nilnode.left = &dict->nilnode;
355
- dict->nilnode.right = &dict->nilnode;
356
- dict->nilnode.parent = &dict->nilnode;
357
- dict->nilnode.color = dnode_black;
358
- dict->dupes = template->dupes;
359
-
360
- assert (dict_similar(dict, template));
361
- }
362
-
363
- /*
364
- * Remove all nodes from the dictionary (without freeing them in any way).
365
- */
366
-
367
- static void dict_clear(dict_t *dict)
368
- {
369
- dict->nodecount = 0;
370
- dict->nilnode.left = &dict->nilnode;
371
- dict->nilnode.right = &dict->nilnode;
372
- dict->nilnode.parent = &dict->nilnode;
373
- assert (dict->nilnode.color == dnode_black);
374
- }
375
-
376
- /*
377
- * Verify the integrity of the dictionary structure. This is provided for
378
- * debugging purposes, and should be placed in assert statements. Just because
379
- * this function succeeds doesn't mean that the tree is not corrupt. Certain
380
- * corruptions in the tree may simply cause undefined behavior.
381
- */
382
-
383
- int dict_verify(dict_t *dict)
384
- {
385
- dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
386
-
387
- /* check that the sentinel node and root node are black */
388
- if (root->color != dnode_black)
389
- return 0;
390
- if (nil->color != dnode_black)
391
- return 0;
392
- if (nil->right != nil)
393
- return 0;
394
- /* nil->left is the root node; check that its parent pointer is nil */
395
- if (nil->left->parent != nil)
396
- return 0;
397
- /* perform a weak test that the tree is a binary search tree */
398
- if (!verify_bintree(dict))
399
- return 0;
400
- /* verify that the tree is a red-black tree */
401
- if (!verify_redblack(nil, root))
402
- return 0;
403
- if (verify_node_count(nil, root) != dict_count(dict))
404
- return 0;
405
- return 1;
406
- }
407
-
408
- /*
409
- * Determine whether two dictionaries are similar: have the same comparison and
410
- * allocator functions, and same status as to whether duplicates are allowed.
411
- */
412
-
413
- int dict_similar(const dict_t *left, const dict_t *right)
414
- {
415
- if (left->compare != right->compare)
416
- return 0;
417
-
418
- if (left->allocnode != right->allocnode)
419
- return 0;
420
-
421
- if (left->freenode != right->freenode)
422
- return 0;
423
-
424
- if (left->context != right->context)
425
- return 0;
426
-
427
- /* if (left->dupes != right->dupes) */
428
- /* return 0; */
429
-
430
- return 1;
431
- }
432
-
433
- /*
434
- * Locate a node in the dictionary having the given key.
435
- * If the node is not found, a null a pointer is returned (rather than
436
- * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
437
- * located node is returned.
438
- */
439
-
440
- dnode_t *dict_lookup(dict_t *dict, const void *key)
441
- {
442
- dnode_t *root = dict_root(dict);
443
- dnode_t *nil = dict_nil(dict);
444
- dnode_t *saved;
445
- int result;
446
-
447
- /* simple binary search adapted for trees that contain duplicate keys */
448
-
449
- while (root != nil) {
450
- result = COMPARE(dict, key, root->key);
451
- if (result < 0)
452
- root = root->left;
453
- else if (result > 0)
454
- root = root->right;
455
- else {
456
- if (!dict->dupes) { /* no duplicates, return match */
457
- return root;
458
- } else { /* could be dupes, find leftmost one */
459
- do {
460
- saved = root;
461
- root = root->left;
462
- while (root != nil && COMPARE(dict, key, root->key))
463
- root = root->right;
464
- } while (root != nil);
465
- return saved;
466
- }
467
- }
468
- }
469
-
470
- return NULL;
471
- }
472
-
473
- /*
474
- * Look for the node corresponding to the lowest key that is equal to or
475
- * greater than the given key. If there is no such node, return null.
476
- */
477
-
478
- dnode_t *dict_lower_bound(dict_t *dict, const void *key)
479
- {
480
- dnode_t *root = dict_root(dict);
481
- dnode_t *nil = dict_nil(dict);
482
- dnode_t *tentative = 0;
483
-
484
- while (root != nil) {
485
- int result = COMPARE(dict, key, root->key);
486
-
487
- if (result > 0) {
488
- root = root->right;
489
- } else if (result < 0) {
490
- tentative = root;
491
- root = root->left;
492
- } else {
493
- if (!dict->dupes) {
494
- return root;
495
- } else {
496
- tentative = root;
497
- root = root->left;
498
- }
499
- }
500
- }
501
-
502
- return tentative;
503
- }
504
-
505
- /*
506
- * Look for the node corresponding to the greatest key that is equal to or
507
- * lower than the given key. If there is no such node, return null.
508
- */
509
-
510
- dnode_t *dict_upper_bound(dict_t *dict, const void *key)
511
- {
512
- dnode_t *root = dict_root(dict);
513
- dnode_t *nil = dict_nil(dict);
514
- dnode_t *tentative = 0;
515
-
516
- while (root != nil) {
517
- int result = COMPARE(dict, key, root->key);
518
-
519
- if (result < 0) {
520
- root = root->left;
521
- } else if (result > 0) {
522
- tentative = root;
523
- root = root->right;
524
- } else {
525
- if (!dict->dupes) {
526
- return root;
527
- } else {
528
- tentative = root;
529
- root = root->right;
530
- }
531
- }
532
- }
533
-
534
- return tentative;
535
- }
536
-
537
- /*
538
- * Insert a node into the dictionary. The node should have been
539
- * initialized with a data field. All other fields are ignored.
540
- * The behavior is undefined if the user attempts to insert into
541
- * a dictionary that is already full (for which the dict_isfull()
542
- * function returns true).
543
- */
544
-
545
- int dict_insert(dict_t *dict, dnode_t *node, const void *key)
546
- {
547
- dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
548
- dnode_t *parent = nil, *uncle, *grandpa;
549
- int result = -1;
550
-
551
- node->key = key;
552
-
553
- assert (!dict_isfull(dict));
554
- assert (!dict_contains(dict, node));
555
- assert (!dnode_is_in_a_dict(node));
556
-
557
- /* basic binary tree insert */
558
-
559
- while (where != nil) {
560
- parent = where;
561
- result = COMPARE(dict, key, where->key);
562
- /* trap attempts at duplicate key insertion unless it's explicitly allowed */
563
-
564
- if (!dict->dupes && result == 0) {
565
- where->data = node->data;
566
- return 0;
567
- } else if (result < 0) {
568
- where = where->left;
569
- } else {
570
- where = where->right;
571
- }
572
- }
573
-
574
- assert (where == nil);
575
-
576
- if (result < 0)
577
- parent->left = node;
578
- else
579
- parent->right = node;
580
-
581
- node->parent = parent;
582
- node->left = nil;
583
- node->right = nil;
584
-
585
- dict->nodecount++;
586
-
587
- /* red black adjustments */
588
-
589
- node->color = dnode_red;
590
-
591
- while (parent->color == dnode_red) {
592
- grandpa = parent->parent;
593
- if (parent == grandpa->left) {
594
- uncle = grandpa->right;
595
- if (uncle->color == dnode_red) { /* red parent, red uncle */
596
- parent->color = dnode_black;
597
- uncle->color = dnode_black;
598
- grandpa->color = dnode_red;
599
- node = grandpa;
600
- parent = grandpa->parent;
601
- } else { /* red parent, black uncle */
602
- if (node == parent->right) {
603
- rotate_left(parent);
604
- parent = node;
605
- assert (grandpa == parent->parent);
606
- /* rotation between parent and child preserves grandpa */
607
- }
608
- parent->color = dnode_black;
609
- grandpa->color = dnode_red;
610
- rotate_right(grandpa);
611
- break;
612
- }
613
- } else { /* symmetric cases: parent == parent->parent->right */
614
- uncle = grandpa->left;
615
- if (uncle->color == dnode_red) {
616
- parent->color = dnode_black;
617
- uncle->color = dnode_black;
618
- grandpa->color = dnode_red;
619
- node = grandpa;
620
- parent = grandpa->parent;
621
- } else {
622
- if (node == parent->left) {
623
- rotate_right(parent);
624
- parent = node;
625
- assert (grandpa == parent->parent);
626
- }
627
- parent->color = dnode_black;
628
- grandpa->color = dnode_red;
629
- rotate_left(grandpa);
630
- break;
631
- }
632
- }
633
- }
634
-
635
- dict_root(dict)->color = dnode_black;
636
-
637
- assert (dict_verify(dict));
638
- return 1;
639
- }
640
-
641
- /*
642
- * Delete the given node from the dictionary. If the given node does not belong
643
- * to the given dictionary, undefined behavior results. A pointer to the
644
- * deleted node is returned.
645
- */
646
-
647
- dnode_t *dict_delete(dict_t *dict, dnode_t *delete)
648
- {
649
- dnode_t *nil = dict_nil(dict), *child, *delparent = delete->parent;
650
-
651
- /* basic deletion */
652
-
653
- assert (!dict_isempty(dict));
654
- assert (dict_contains(dict, delete));
655
-
656
- /*
657
- * If the node being deleted has two children, then we replace it with its
658
- * successor (i.e. the leftmost node in the right subtree.) By doing this,
659
- * we avoid the traditional algorithm under which the successor's key and
660
- * value *only* move to the deleted node and the successor is spliced out
661
- * from the tree. We cannot use this approach because the user may hold
662
- * pointers to the successor, or nodes may be inextricably tied to some
663
- * other structures by way of embedding, etc. So we must splice out the
664
- * node we are given, not some other node, and must not move contents from
665
- * one node to another behind the user's back.
666
- */
667
-
668
- if (delete->left != nil && delete->right != nil) {
669
- dnode_t *next = dict_next(dict, delete);
670
- dnode_t *nextparent = next->parent;
671
- dnode_color_t nextcolor = next->color;
672
-
673
- assert (next != nil);
674
- assert (next->parent != nil);
675
- assert (next->left == nil);
676
-
677
- /*
678
- * First, splice out the successor from the tree completely, by
679
- * moving up its right child into its place.
680
- */
681
-
682
- child = next->right;
683
- child->parent = nextparent;
684
-
685
- if (nextparent->left == next) {
686
- nextparent->left = child;
687
- } else {
688
- assert (nextparent->right == next);
689
- nextparent->right = child;
690
- }
691
-
692
- /*
693
- * Now that the successor has been extricated from the tree, install it
694
- * in place of the node that we want deleted.
695
- */
696
-
697
- next->parent = delparent;
698
- next->left = delete->left;
699
- next->right = delete->right;
700
- next->left->parent = next;
701
- next->right->parent = next;
702
- next->color = delete->color;
703
- delete->color = nextcolor;
704
-
705
- if (delparent->left == delete) {
706
- delparent->left = next;
707
- } else {
708
- assert (delparent->right == delete);
709
- delparent->right = next;
710
- }
711
-
712
- } else {
713
- assert (delete != nil);
714
- assert (delete->left == nil || delete->right == nil);
715
-
716
- child = (delete->left != nil) ? delete->left : delete->right;
717
-
718
- child->parent = delparent = delete->parent;
719
-
720
- if (delete == delparent->left) {
721
- delparent->left = child;
722
- } else {
723
- assert (delete == delparent->right);
724
- delparent->right = child;
725
- }
726
- }
727
-
728
- delete->parent = NULL;
729
- delete->right = NULL;
730
- delete->left = NULL;
731
-
732
- dict->nodecount--;
733
-
734
- assert (verify_bintree(dict));
735
-
736
- /* red-black adjustments */
737
-
738
- if (delete->color == dnode_black) {
739
- dnode_t *parent, *sister;
740
-
741
- dict_root(dict)->color = dnode_red;
742
-
743
- while (child->color == dnode_black) {
744
- parent = child->parent;
745
- if (child == parent->left) {
746
- sister = parent->right;
747
- assert (sister != nil);
748
- if (sister->color == dnode_red) {
749
- sister->color = dnode_black;
750
- parent->color = dnode_red;
751
- rotate_left(parent);
752
- sister = parent->right;
753
- assert (sister != nil);
754
- }
755
- if (sister->left->color == dnode_black
756
- && sister->right->color == dnode_black) {
757
- sister->color = dnode_red;
758
- child = parent;
759
- } else {
760
- if (sister->right->color == dnode_black) {
761
- assert (sister->left->color == dnode_red);
762
- sister->left->color = dnode_black;
763
- sister->color = dnode_red;
764
- rotate_right(sister);
765
- sister = parent->right;
766
- assert (sister != nil);
767
- }
768
- sister->color = parent->color;
769
- sister->right->color = dnode_black;
770
- parent->color = dnode_black;
771
- rotate_left(parent);
772
- break;
773
- }
774
- } else { /* symmetric case: child == child->parent->right */
775
- assert (child == parent->right);
776
- sister = parent->left;
777
- assert (sister != nil);
778
- if (sister->color == dnode_red) {
779
- sister->color = dnode_black;
780
- parent->color = dnode_red;
781
- rotate_right(parent);
782
- sister = parent->left;
783
- assert (sister != nil);
784
- }
785
- if (sister->right->color == dnode_black
786
- && sister->left->color == dnode_black) {
787
- sister->color = dnode_red;
788
- child = parent;
789
- } else {
790
- if (sister->left->color == dnode_black) {
791
- assert (sister->right->color == dnode_red);
792
- sister->right->color = dnode_black;
793
- sister->color = dnode_red;
794
- rotate_left(sister);
795
- sister = parent->left;
796
- assert (sister != nil);
797
- }
798
- sister->color = parent->color;
799
- sister->left->color = dnode_black;
800
- parent->color = dnode_black;
801
- rotate_right(parent);
802
- break;
803
- }
804
- }
805
- }
806
-
807
- child->color = dnode_black;
808
- dict_root(dict)->color = dnode_black;
809
- }
810
-
811
- assert (dict_verify(dict));
812
-
813
- return delete;
814
- }
815
-
816
- /*
817
- * Allocate a node using the dictionary's allocator routine, give it
818
- * the data item.
819
- */
820
-
821
- int dict_alloc_insert(dict_t *dict, const void *key, void *data)
822
- {
823
- dnode_t *node = dict->allocnode(dict->context);
824
-
825
- if (node) {
826
- dnode_init(node, data);
827
- if (!dict_insert(dict, node, key))
828
- dict->freenode(node, dict->context);
829
- return 1;
830
- }
831
- return 0;
832
- }
833
-
834
- void dict_delete_free(dict_t *dict, dnode_t *node)
835
- {
836
- dict_delete(dict, node);
837
- dict->freenode(node, dict->context);
838
- }
839
-
840
- /*
841
- * Return the node with the lowest (leftmost) key. If the dictionary is empty
842
- * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
843
- */
844
-
845
- dnode_t *dict_first(dict_t *dict)
846
- {
847
- dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
848
-
849
- if (root != nil)
850
- while ((left = root->left) != nil)
851
- root = left;
852
-
853
- return (root == nil) ? NULL : root;
854
- }
855
-
856
- /*
857
- * Return the node with the highest (rightmost) key. If the dictionary is empty
858
- * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
859
- */
860
-
861
- dnode_t *dict_last(dict_t *dict)
862
- {
863
- dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *right;
864
-
865
- if (root != nil)
866
- while ((right = root->right) != nil)
867
- root = right;
868
-
869
- return (root == nil) ? NULL : root;
870
- }
871
-
872
- /*
873
- * Return the given node's successor node---the node which has the
874
- * next key in the the left to right ordering. If the node has
875
- * no successor, a null pointer is returned rather than a pointer to
876
- * the nil node.
877
- */
878
-
879
- dnode_t *dict_next(dict_t *dict, dnode_t *curr)
880
- {
881
- dnode_t *nil = dict_nil(dict), *parent, *left;
882
-
883
- if (curr->right != nil) {
884
- curr = curr->right;
885
- while ((left = curr->left) != nil)
886
- curr = left;
887
- return curr;
888
- }
889
-
890
- parent = curr->parent;
891
-
892
- while (parent != nil && curr == parent->right) {
893
- curr = parent;
894
- parent = curr->parent;
895
- }
896
-
897
- return (parent == nil) ? NULL : parent;
898
- }
899
-
900
- /*
901
- * Return the given node's predecessor, in the key order.
902
- * The nil sentinel node is returned if there is no predecessor.
903
- */
904
-
905
- dnode_t *dict_prev(dict_t *dict, dnode_t *curr)
906
- {
907
- dnode_t *nil = dict_nil(dict), *parent, *right;
908
-
909
- if (curr->left != nil) {
910
- curr = curr->left;
911
- while ((right = curr->right) != nil)
912
- curr = right;
913
- return curr;
914
- }
915
-
916
- parent = curr->parent;
917
-
918
- while (parent != nil && curr == parent->left) {
919
- curr = parent;
920
- parent = curr->parent;
921
- }
922
-
923
- return (parent == nil) ? NULL : parent;
924
- }
925
-
926
- void dict_allow_dupes(dict_t *dict)
927
- {
928
- dict->dupes = 1;
929
- }
930
-
931
- dictcount_t dict_count(dict_t *dict)
932
- {
933
- return dict->nodecount;
934
- }
935
-
936
- int dict_isempty(dict_t *dict)
937
- {
938
- return dict->nodecount == 0;
939
- }
940
-
941
- int dict_isfull(dict_t *dict)
942
- {
943
- return dict->nodecount == DICTCOUNT_T_MAX;
944
- }
945
-
946
- int dict_contains(dict_t *dict, dnode_t *node)
947
- {
948
- return verify_dict_has_node(dict_nil(dict), dict_root(dict), node);
949
- }
950
-
951
- static dnode_t *dnode_alloc(void *context)
952
- {
953
- return malloc(sizeof *dnode_alloc(NULL));
954
- }
955
-
956
- static void dnode_free(dnode_t *node, void *context)
957
- {
958
- free(node);
959
- }
960
-
961
- dnode_t *dnode_create(void *data)
962
- {
963
- dnode_t *new = malloc(sizeof *new);
964
- if (new) {
965
- new->data = data;
966
- new->parent = NULL;
967
- new->left = NULL;
968
- new->right = NULL;
969
- }
970
- return new;
971
- }
972
-
973
- dnode_t *dnode_init(dnode_t *dnode, void *data)
974
- {
975
- dnode->data = data;
976
- dnode->parent = NULL;
977
- dnode->left = NULL;
978
- dnode->right = NULL;
979
- return dnode;
980
- }
981
-
982
- void dnode_destroy(dnode_t *dnode)
983
- {
984
- assert (!dnode_is_in_a_dict(dnode));
985
- free(dnode);
986
- }
987
-
988
- void *dnode_get(dnode_t *dnode)
989
- {
990
- return dnode->data;
991
- }
992
-
993
- const void *dnode_getkey(dnode_t *dnode)
994
- {
995
- return dnode->key;
996
- }
997
-
998
- void dnode_put(dnode_t *dnode, void *data)
999
- {
1000
- dnode->data = data;
1001
- }
1002
-
1003
- int dnode_is_in_a_dict(dnode_t *dnode)
1004
- {
1005
- return (dnode->parent && dnode->left && dnode->right);
1006
- }
1007
-
1008
- void dict_process(dict_t *dict, void *context, dnode_process_t function)
1009
- {
1010
- dnode_t *node = dict_first(dict), *next;
1011
-
1012
- while (node != NULL) {
1013
- /* check for callback function deleting */
1014
- /* the next node from under us */
1015
- assert (dict_contains(dict, node));
1016
- next = dict_next(dict, node);
1017
- function(dict, node, context);
1018
- node = next;
1019
- }
1020
- }
1021
-
1022
- static void load_begin_internal(dict_load_t *load, dict_t *dict)
1023
- {
1024
- load->dictptr = dict;
1025
- load->nilnode.left = &load->nilnode;
1026
- load->nilnode.right = &load->nilnode;
1027
- }
1028
-
1029
- void dict_load_begin(dict_load_t *load, dict_t *dict)
1030
- {
1031
- assert (dict_isempty(dict));
1032
- load_begin_internal(load, dict);
1033
- }
1034
-
1035
- void dict_load_next(dict_load_t *load, dnode_t *newnode, const void *key)
1036
- {
1037
- dict_t *dict = load->dictptr;
1038
- dnode_t *nil = &load->nilnode;
1039
-
1040
- assert (!dnode_is_in_a_dict(newnode));
1041
- assert (dict->nodecount < DICTCOUNT_T_MAX);
1042
-
1043
- #ifndef NDEBUG
1044
- if (dict->nodecount > 0) {
1045
- if (dict->dupes)
1046
- assert (COMPARE(dict, nil->left->key, key) <= 0);
1047
- else
1048
- assert (COMPARE(dict, nil->left->key, key) < 0);
1049
- }
1050
- #endif
1051
-
1052
- newnode->key = key;
1053
- nil->right->left = newnode;
1054
- nil->right = newnode;
1055
- newnode->left = nil;
1056
- dict->nodecount++;
1057
- }
1058
-
1059
- void dict_load_end(dict_load_t *load)
1060
- {
1061
- dict_t *dict = load->dictptr;
1062
- dnode_t *tree[DICT_DEPTH_MAX] = { 0 };
1063
- dnode_t *curr, *dictnil = dict_nil(dict), *loadnil = &load->nilnode, *next;
1064
- dnode_t *complete = 0;
1065
- dictcount_t fullcount = DICTCOUNT_T_MAX, nodecount = dict->nodecount;
1066
- dictcount_t botrowcount;
1067
- unsigned baselevel = 0, level = 0, i;
1068
-
1069
- assert (dnode_red == 0 && dnode_black == 1);
1070
-
1071
- while (fullcount >= nodecount && fullcount)
1072
- fullcount >>= 1;
1073
-
1074
- botrowcount = nodecount - fullcount;
1075
-
1076
- for (curr = loadnil->left; curr != loadnil; curr = next) {
1077
- next = curr->left;
1078
-
1079
- if (complete == NULL && botrowcount-- == 0) {
1080
- assert (baselevel == 0);
1081
- assert (level == 0);
1082
- baselevel = level = 1;
1083
- complete = tree[0];
1084
-
1085
- if (complete != 0) {
1086
- tree[0] = 0;
1087
- complete->right = dictnil;
1088
- while (tree[level] != 0) {
1089
- tree[level]->right = complete;
1090
- complete->parent = tree[level];
1091
- complete = tree[level];
1092
- tree[level++] = 0;
1093
- }
1094
- }
1095
- }
1096
-
1097
- if (complete == NULL) {
1098
- curr->left = dictnil;
1099
- curr->right = dictnil;
1100
- curr->color = level % 2;
1101
- complete = curr;
1102
-
1103
- assert (level == baselevel);
1104
- while (tree[level] != 0) {
1105
- tree[level]->right = complete;
1106
- complete->parent = tree[level];
1107
- complete = tree[level];
1108
- tree[level++] = 0;
1109
- }
1110
- } else {
1111
- curr->left = complete;
1112
- curr->color = (level + 1) % 2;
1113
- complete->parent = curr;
1114
- tree[level] = curr;
1115
- complete = 0;
1116
- level = baselevel;
1117
- }
1118
- }
1119
-
1120
- if (complete == NULL)
1121
- complete = dictnil;
1122
-
1123
- for (i = 0; i < DICT_DEPTH_MAX; i++) {
1124
- if (tree[i] != 0) {
1125
- tree[i]->right = complete;
1126
- complete->parent = tree[i];
1127
- complete = tree[i];
1128
- }
1129
- }
1130
-
1131
- dictnil->color = dnode_black;
1132
- dictnil->right = dictnil;
1133
- complete->parent = dictnil;
1134
- complete->color = dnode_black;
1135
- dict_root(dict) = complete;
1136
-
1137
- assert (dict_verify(dict));
1138
- }
1139
-
1140
- void dict_merge(dict_t *dest, dict_t *source)
1141
- {
1142
- dict_load_t load;
1143
- dnode_t *leftnode = dict_first(dest), *rightnode = dict_first(source);
1144
-
1145
- assert (dict_similar(dest, source));
1146
-
1147
- if (source == dest)
1148
- return;
1149
-
1150
- dest->nodecount = 0;
1151
- load_begin_internal(&load, dest);
1152
-
1153
- for (;;) {
1154
- if (leftnode != NULL && rightnode != NULL) {
1155
- if (COMPARE(dest, leftnode->key, rightnode->key) < 0)
1156
- goto copyleft;
1157
- else
1158
- goto copyright;
1159
- } else if (leftnode != NULL) {
1160
- goto copyleft;
1161
- } else if (rightnode != NULL) {
1162
- goto copyright;
1163
- } else {
1164
- assert (leftnode == NULL && rightnode == NULL);
1165
- break;
1166
- }
1167
-
1168
- copyleft:
1169
- {
1170
- dnode_t *next = dict_next(dest, leftnode);
1171
- #ifndef NDEBUG
1172
- leftnode->left = NULL; /* suppress assertion in dict_load_next */
1173
- #endif
1174
- dict_load_next(&load, leftnode, leftnode->key);
1175
- leftnode = next;
1176
- continue;
1177
- }
1178
-
1179
- copyright:
1180
- {
1181
- dnode_t *next = dict_next(source, rightnode);
1182
- #ifndef NDEBUG
1183
- rightnode->left = NULL;
1184
- #endif
1185
- dict_load_next(&load, rightnode, rightnode->key);
1186
- rightnode = next;
1187
- continue;
1188
- }
1189
- }
1190
-
1191
- dict_clear(source);
1192
- dict_load_end(&load);
1193
- }
1194
-
1195
- int dict_equal(dict_t* dict1, dict_t* dict2,
1196
- dict_value_eql_t value_eql)
1197
- {
1198
- dnode_t* node1;
1199
- dnode_t* node2;
1200
-
1201
- if (dict_count(dict1) != dict_count(dict2))
1202
- return 0;
1203
- if (!dict_similar(dict1, dict2))
1204
- return 0;
1205
-
1206
- for (node1 = dict_first(dict1), node2 = dict_first(dict2);
1207
- node1 != NULL && node2 != NULL;
1208
- node1 = dict_next(dict1, node1), node2 = dict_next(dict2, node2)) {
1209
-
1210
- if (COMPARE(dict1, node1->key, node2->key) != 0)
1211
- return 0;
1212
- if (!value_eql(node1->data, node2->data))
1213
- return 0;
1214
- }
1215
- return 1;
1216
- }