algorithms 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,247 @@
1
+ #include "ruby.h"
2
+
3
+ typedef struct struct_bst_node {
4
+ VALUE key;
5
+ VALUE value;
6
+ struct struct_bst_node *left;
7
+ struct struct_bst_node *right;
8
+ struct struct_bst_node *parent;
9
+ } bst_node;
10
+
11
+ typedef struct struct_bst {
12
+ bst_node *root;
13
+ int (*compare_function)(VALUE key1, VALUE key2);
14
+ unsigned int size;
15
+ } bst;
16
+
17
+ static VALUE bst_initialize(VALUE self) {
18
+ return self;
19
+ }
20
+
21
+ static bst* get_bst_from_self(VALUE self) {
22
+ bst *tree;
23
+ Data_Get_Struct(self, bst, tree);
24
+ return tree;
25
+ }
26
+
27
+ static bst* bst_each_node(bst *tree, bst_node *node, void (*each)(bst *tree_, bst_node *node_, void* args), void* arguments) {
28
+ if (!node)
29
+ return NULL;
30
+
31
+ if (node->left)
32
+ bst_each_node(tree, node->left, each, arguments);
33
+
34
+ (*each)(tree, node, arguments);
35
+
36
+ if (node->right)
37
+ bst_each_node(tree, node->right, each, arguments);
38
+ return tree;
39
+ }
40
+
41
+ static bst* bst_each(bst *tree, void (*each)(bst *tree, bst_node *node, void *args), void* arguments) {
42
+ if (tree->root)
43
+ bst_each_node(tree, tree->root, each, arguments);
44
+ return tree;
45
+ }
46
+
47
+ static VALUE id_compare_operator;
48
+
49
+ static int bst_compare_function(VALUE a, VALUE b) {
50
+ if (a == b) return 0;
51
+ if (FIXNUM_P(a) && FIXNUM_P(b)) {
52
+ long x = FIX2LONG(a), y = FIX2LONG(b);
53
+ if (x == y) return 0;
54
+ if (x > y) return 1;
55
+ return -1;
56
+ }
57
+ if (TYPE(a) == T_STRING && rb_obj_is_kind_of(a, rb_cString) &&
58
+ TYPE(b) == T_STRING && rb_obj_is_kind_of(b, rb_cString)) {
59
+ return rb_str_cmp(a, b);
60
+ }
61
+ return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
62
+ }
63
+
64
+ static void insert_element(bst *tree, bst_node **t,bst_node *newElement) {
65
+ int cmp;
66
+ bst_node *y = NULL;
67
+ bst_node *x = *t;
68
+ while (x != NULL) {
69
+ y = x;
70
+ cmp = tree->compare_function(newElement->key, x->key);
71
+ if (cmp < 0) x = x->left;
72
+ else x = x->right;
73
+ }
74
+ newElement->parent = y;
75
+ if (y == NULL) *t = newElement;
76
+ else {
77
+ cmp = tree->compare_function(newElement->key, y->key);
78
+ if (cmp < 0)
79
+ y->left = newElement;
80
+ else
81
+ y->right = newElement;
82
+ }
83
+ }
84
+
85
+
86
+ static bst_node* create_node(VALUE key_value,VALUE value) {
87
+ bst_node *new_node = ALLOC(bst_node);
88
+ new_node->value = value;
89
+ new_node->key = key_value;
90
+ new_node->left = NULL;
91
+ new_node->right = NULL;
92
+ new_node->parent = NULL;
93
+ return new_node;
94
+ }
95
+
96
+ static bst_node* tree_minimum (bst_node *tree) {
97
+ bst_node *x = tree;
98
+ while (x->left) x = x->left;
99
+ return x;
100
+ }
101
+
102
+ static bst_node* tree_maximum (bst_node *tree) {
103
+ bst_node *x = tree;
104
+ while (x->right) x = x->right;
105
+ return x;
106
+ }
107
+
108
+ static bst_node* node_successor (bst_node *tree,bst_node *x) {
109
+ if (x->right) return tree_minimum(x->right);
110
+ bst_node *y = x->parent;
111
+ while (y && x == y->right) {
112
+ x = y;
113
+ y = x->parent;
114
+ }
115
+ return y;
116
+ }
117
+
118
+
119
+ static bst_node* delete_node (bst_node **tree,bst_node *tobeDeleted) {
120
+ bst_node *y,*x;
121
+
122
+ if ((tobeDeleted->left == NULL) || (tobeDeleted->right == NULL)) y = tobeDeleted;
123
+ else y = node_successor(*tree,tobeDeleted);
124
+
125
+ if (y->left) x = y->left;
126
+ else x = y->right;
127
+
128
+ if (x) x->parent = y->parent;
129
+
130
+ if (y->parent == NULL) {
131
+ *tree = x;
132
+ return y;
133
+ } else if (y == y->parent->left) {
134
+ y->parent->left = x;
135
+ } else {
136
+ y->parent->right = x;
137
+ }
138
+
139
+ if (tobeDeleted != y) tobeDeleted->key = y->key;
140
+ return y;
141
+ }
142
+
143
+ static bst_node* search_node(bst *tree, bst_node *node, VALUE key) {
144
+ bst_node *x = node;
145
+ int cmp;
146
+
147
+ while(x) {
148
+ cmp = tree->compare_function(key, x->key);
149
+ if (cmp == 0) return x;
150
+ else if (cmp < 0) { x = x->left; }
151
+ else { x = x->right; }
152
+ }
153
+ return NULL;
154
+ }
155
+
156
+ static void recursively_mark_nodes(bst_node *node) {
157
+ if(node) {
158
+ rb_gc_mark(node->key);
159
+ rb_gc_mark(node->value);
160
+ recursively_mark_nodes(node->left);
161
+ recursively_mark_nodes(node->right);
162
+ }
163
+ }
164
+
165
+ static void bst_mark(bst *tree) {
166
+ if (tree) {
167
+ recursively_mark_nodes(tree->root);
168
+ }
169
+ }
170
+
171
+ static void recursively_free_nodes(bst_node *node) {
172
+ if(node) {
173
+ recursively_free_nodes(node->left);
174
+ recursively_free_nodes(node->right);
175
+ xfree(node);
176
+ }
177
+ }
178
+
179
+ static void bst_free(bst *tree) {
180
+ if (tree) {
181
+ recursively_free_nodes(tree->root);
182
+ }
183
+ }
184
+
185
+ static bst* create_bst(int (*compare_function)(VALUE, VALUE)) {
186
+ bst *tree = ALLOC(bst);
187
+ tree->compare_function = compare_function;
188
+ tree->root = NULL;
189
+ tree->size = 0;
190
+ return tree;
191
+ }
192
+
193
+ static VALUE bst_alloc(VALUE klass) {
194
+ bst *tree = create_bst(&bst_compare_function);
195
+ return Data_Wrap_Struct(klass, bst_mark, bst_free, tree);
196
+ }
197
+
198
+ static VALUE rb_bst_push_value(VALUE self, VALUE key, VALUE value) {
199
+ bst *tree = get_bst_from_self(self);
200
+ insert_element(tree, &(tree->root), create_node(key,value));
201
+ tree->size++;
202
+ return self;
203
+ }
204
+
205
+ static void bst_each_helper(bst *tree, bst_node *node, void *args) {
206
+ rb_yield(rb_ary_new3(2, node->key, node->value));
207
+ };
208
+
209
+ static VALUE rb_bst_each(VALUE self) {
210
+ bst *tree = get_bst_from_self(self);
211
+ bst_each(tree, &bst_each_helper, NULL);
212
+ return self;
213
+ }
214
+
215
+ static VALUE rb_bst_delete(VALUE self, VALUE key) {
216
+ bst *tree = get_bst_from_self(self);
217
+ bst_node *tobeDeleted = search_node(tree, tree->root, key);
218
+ if(tobeDeleted) {
219
+ tree->size -= 1;
220
+ bst_node *deletedNode = delete_node(&(tree->root),tobeDeleted);
221
+ return deletedNode->value;
222
+ }
223
+ return Qnil;
224
+ }
225
+
226
+ static VALUE rb_bst_size(VALUE self) {
227
+ bst *tree;
228
+ Data_Get_Struct(self,bst,tree);
229
+ return INT2FIX(tree->size);
230
+ }
231
+
232
+ static VALUE CBst;
233
+ static VALUE mContainers;
234
+
235
+ void Init_CBst() {
236
+ id_compare_operator = rb_intern("<=>");
237
+
238
+ mContainers = rb_define_module("Containers");
239
+ CBst = rb_define_class_under(mContainers, "CBst", rb_cObject);
240
+ rb_define_alloc_func(CBst, bst_alloc);
241
+ rb_define_method(CBst, "initialize", bst_initialize, 0);
242
+ rb_define_method(CBst, "push", rb_bst_push_value, 2);
243
+ rb_define_alias(CBst, "[]=", "push");
244
+ rb_define_method(CBst, "each", rb_bst_each, 0);
245
+ rb_define_method(CBst, "delete", rb_bst_delete, 1);
246
+ rb_define_method(CBst, "size", rb_bst_size, 0);
247
+ }
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = "CBst"
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)
@@ -19,7 +19,7 @@ void free_nodes(deque_node *node) {
19
19
  deque_node *next;
20
20
  while(node) {
21
21
  next = node->right;
22
- free(node);
22
+ xfree(node);
23
23
  node = next;
24
24
  }
25
25
  return;
@@ -71,7 +71,7 @@ static void deque_free(void *ptr) {
71
71
  if (ptr) {
72
72
  deque *deque = ptr;
73
73
  free_nodes(deque->front);
74
- free(deque);
74
+ xfree(deque);
75
75
  }
76
76
  }
77
77
 
@@ -200,7 +200,7 @@ static VALUE deque_each_backward(VALUE self) {
200
200
 
201
201
  static VALUE deque_init(int argc, VALUE *argv, VALUE self)
202
202
  {
203
- int len, i;
203
+ long len, i;
204
204
  VALUE ary;
205
205
 
206
206
  if(argc == 0) {
@@ -22,11 +22,16 @@ typedef struct {
22
22
  rbtree_node *root;
23
23
  } rbtree;
24
24
 
25
+ typedef struct struct_ll_node {
26
+ rbtree_node *node;
27
+ struct struct_ll_node *next;
28
+ } ll_node;
29
+
25
30
  static void recursively_free_nodes(rbtree_node *node) {
26
31
  if(node) {
27
32
  recursively_free_nodes(node->left);
28
33
  recursively_free_nodes(node->right);
29
- free(node);
34
+ xfree(node);
30
35
  }
31
36
  return;
32
37
  }
@@ -193,7 +198,7 @@ static rbtree_node* delete_min(rbtree_node *h, VALUE *deleted_value) {
193
198
  if ( !h->left ) {
194
199
  if(deleted_value)
195
200
  *deleted_value = h->value;
196
- free(h);
201
+ xfree(h);
197
202
  return NULL;
198
203
  }
199
204
 
@@ -211,7 +216,7 @@ static rbtree_node* delete_max(rbtree_node *h, VALUE *deleted_value) {
211
216
 
212
217
  if ( !h->right ) {
213
218
  *deleted_value = h->value;
214
- free(h);
219
+ xfree(h);
215
220
  return NULL;
216
221
  }
217
222
 
@@ -240,7 +245,7 @@ static rbtree_node* delete(rbtree *tree, rbtree_node *node, VALUE key, VALUE *de
240
245
  cmp = tree->compare_function(key, node->key);
241
246
  if ( (cmp == 0) && !node->right ) {
242
247
  *deleted_value = node->value;
243
- free(node);
248
+ xfree(node);
244
249
  return NULL;
245
250
  }
246
251
 
@@ -282,7 +287,7 @@ static rbtree* rbt_each(rbtree *tree, void (*each)(rbtree *tree, rbtree_node *no
282
287
 
283
288
  // Methods to be called in Ruby
284
289
 
285
- static int id_compare_operator;
290
+ static VALUE id_compare_operator;
286
291
 
287
292
  static int rbtree_compare_function(VALUE a, VALUE b) {
288
293
  if (a == b) return 0;
@@ -292,8 +297,8 @@ static int rbtree_compare_function(VALUE a, VALUE b) {
292
297
  if (x > y) return 1;
293
298
  return -1;
294
299
  }
295
- if (TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString &&
296
- TYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString) {
300
+ if (TYPE(a) == T_STRING && rb_obj_is_kind_of(a, rb_cString) &&
301
+ TYPE(b) == T_STRING && rb_obj_is_kind_of(b, rb_cString)) {
297
302
  return rb_str_cmp(a, b);
298
303
  }
299
304
  return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
@@ -304,19 +309,39 @@ static VALUE rbtree_init(VALUE self)
304
309
  return self;
305
310
  }
306
311
 
307
- static void recursively_mark_nodes(rbtree_node *node) {
308
- if(node) {
309
- rb_gc_mark(node->key);
310
- rb_gc_mark(node->value);
311
- recursively_mark_nodes(node->left);
312
- recursively_mark_nodes(node->right);
313
- }
314
- }
315
-
316
312
  static void rbtree_mark(void *ptr) {
313
+ ll_node *current, *new, *last, *old;
317
314
  if (ptr) {
318
315
  rbtree *tree = ptr;
319
- recursively_mark_nodes(tree->root);
316
+
317
+ if (tree->root) {
318
+ current = ALLOC(ll_node);
319
+ last = current;
320
+ current->node = tree->root;
321
+ current->next = NULL;
322
+
323
+ while(current) {
324
+ rb_gc_mark(current->node->key);
325
+ rb_gc_mark(current->node->value);
326
+ if (current->node->left) {
327
+ new = ALLOC(ll_node);
328
+ new->node = current->node->left;
329
+ new->next = NULL;
330
+ last->next = new;
331
+ last = new;
332
+ }
333
+ if (current->node->right) {
334
+ new = ALLOC(ll_node);
335
+ new->node = current->node->right;
336
+ new->next = NULL;
337
+ last->next = new;
338
+ last = new;
339
+ }
340
+ old = current;
341
+ current = current->next;
342
+ xfree(old);
343
+ }
344
+ }
320
345
  }
321
346
  }
322
347
 
@@ -324,7 +349,7 @@ static void rbtree_free(void *ptr) {
324
349
  if (ptr) {
325
350
  rbtree *tree = ptr;
326
351
  recursively_free_nodes(tree->root);
327
- free(tree);
352
+ xfree(tree);
328
353
  }
329
354
  }
330
355
 
@@ -1,24 +1,34 @@
1
1
  #include "ruby.h"
2
2
 
3
+ #define node_size(x) (((x)==NULL) ? 0 : ((x)->size))
4
+
5
+ /* Using http://www.link.cs.cmu.edu/link/ftp-site/splaying/top-down-size-splay.c as reference,
6
+ written by D. Sleator <sleator@cs.cmu.edu>, January 1994.
7
+ */
8
+
3
9
  typedef struct struct_splaytree_node {
4
10
  VALUE key;
5
11
  VALUE value;
12
+ int size;
6
13
  struct struct_splaytree_node *left;
7
14
  struct struct_splaytree_node *right;
8
15
  } splaytree_node;
9
16
 
10
17
  typedef struct {
11
18
  int (*compare_function)(VALUE key1, VALUE key2);
12
- int size;
13
19
  splaytree_node *root;
14
- splaytree_node *header;
15
20
  } splaytree;
16
21
 
22
+ typedef struct struct_ll_node {
23
+ splaytree_node *node;
24
+ struct struct_ll_node *next;
25
+ } ll_node;
26
+
17
27
  static void recursively_free_nodes(splaytree_node *node) {
18
28
  if(node) {
19
29
  recursively_free_nodes(node->left);
20
30
  recursively_free_nodes(node->right);
21
- free(node);
31
+ xfree(node);
22
32
  }
23
33
  return;
24
34
  }
@@ -29,55 +39,75 @@ static splaytree* get_tree_from_self(VALUE self) {
29
39
  return tree;
30
40
  }
31
41
 
32
- static void splay(splaytree *tree, VALUE key) {
33
- int cmp, cmp2;
34
- splaytree_node *l, *r, *t, *y;
42
+ static splaytree_node* splay(splaytree *tree, splaytree_node *n, VALUE key) {
43
+ int cmp, cmp2, root_size, l_size, r_size;
44
+ splaytree_node N;
45
+ splaytree_node *l, *r, *y;
35
46
 
36
- l = tree->header;
37
- r = tree->header;
38
- t = tree->root;
47
+ if (!n) return n;
39
48
 
40
- tree->header->left = NULL;
41
- tree->header->right = NULL;
49
+ N.left = N.right = NULL;
50
+ l = r = &N;
51
+ root_size = node_size(n);
52
+ l_size = r_size = 0;
42
53
 
43
54
  while(1) {
44
- cmp = tree->compare_function(key, t->key);
55
+ cmp = tree->compare_function(key, n->key);
45
56
  if (cmp == -1) {
46
- if (!(t->left)) break;
47
- cmp2 = tree->compare_function(key, t->left->key);
57
+ if (!n->left) break;
58
+ cmp2 = tree->compare_function(key, n->left->key);
48
59
  if (cmp2 == -1) {
49
- y = t->left;
50
- t->left = y->right;
51
- y->right = t;
52
- t = y;
53
- if (!(t->left)) break;
60
+ y = n->left;
61
+ n->left = y->right;
62
+ y->right = n;
63
+ n->size = node_size(n->left) + node_size(n->right) + 1;
64
+ n = y;
65
+ if (!n->left) break;
54
66
  }
55
- r->left = t;
56
- r = t;
57
- t = t->left;
58
- }
59
- else if (cmp == 1) {
60
- if (!(t->right)) break;
61
- cmp2 = tree->compare_function(key, t->right->key);
67
+ r->left = n;
68
+ r = n;
69
+ n = n->left;
70
+ r_size += 1 + node_size(r->right);
71
+ } else if (cmp == 1) {
72
+ if (!n->right) break;
73
+ cmp2 = tree->compare_function(key, n->right->key);
62
74
  if (cmp2 == 1) {
63
- y = t->right;
64
- t->right = y->left;
65
- y->left = t;
66
- t = y;
67
- if (!(t->right)) break;
75
+ y = n->right;
76
+ n->right = y->left;
77
+ y->left = n;
78
+ n->size = node_size(n->left) + node_size(n->right) + 1;
79
+ n = y;
80
+ if (!n->right) break;
68
81
  }
69
- l->right = t;
70
- l = t;
71
- t = t->right;
82
+ l->right = n;
83
+ l = n;
84
+ n = n->right;
85
+ l_size += 1 + node_size(l->left);
72
86
  } else {
73
87
  break;
74
88
  }
75
89
  }
76
- l->right = t->left;
77
- r->left = t->right;
78
- t->left = tree->header->right;
79
- t->right = tree->header->left;
80
- tree->root = t;
90
+
91
+ l_size += node_size(n->left);
92
+ r_size += node_size(n->right);
93
+ n->size = l_size + r_size + 1;
94
+ l->right = r->left = NULL;
95
+
96
+ for (y = N.right; y != NULL; y = y->right) {
97
+ y->size = l_size;
98
+ l_size -= 1 + node_size(y->left);
99
+ }
100
+ for (y = N.left; y != NULL; y = y->left) {
101
+ y->size = r_size;
102
+ r_size -= 1 + node_size(y->right);
103
+ }
104
+
105
+ l->right = n->left;
106
+ r->left = n->right;
107
+ n->left = N.right;
108
+ n->right = N.left;
109
+
110
+ return n;
81
111
  }
82
112
 
83
113
  static int height(splaytree_node *h) {
@@ -95,8 +125,6 @@ static splaytree* create_splaytree(int (*compare_function)(VALUE, VALUE)) {
95
125
  splaytree *tree = ALLOC(splaytree);
96
126
  tree->compare_function = compare_function;
97
127
  tree->root = NULL;
98
- tree->size = 0;
99
- tree->header = ALLOC(splaytree_node);
100
128
  return tree;
101
129
  }
102
130
 
@@ -109,44 +137,46 @@ static splaytree_node* create_node(VALUE key, VALUE value) {
109
137
  return new_node;
110
138
  }
111
139
 
112
- static void insert(splaytree *tree, VALUE key, VALUE value) {
140
+ static splaytree_node* insert(splaytree *tree, splaytree_node *n, VALUE key, VALUE value) {
113
141
  int cmp;
114
142
  splaytree_node *new_node;
115
143
 
116
- if (!(tree->root)) {
117
- new_node = create_node(key, value);
118
- tree->root = new_node;
119
- tree->size += 1;
120
- return;
144
+ if (n) {
145
+ n = splay(tree, n, key);
146
+ cmp = tree->compare_function(key, n->key);
147
+ if (cmp == 0) {
148
+ n->value = value;
149
+ return n;
150
+ }
121
151
  }
122
-
123
- splay(tree, key);
124
- cmp = tree->compare_function(key, tree->root->key);
125
- if (cmp == 0) {
126
- tree->root->value = value;
127
- return;
152
+ new_node = create_node(key, value);
153
+ if (!n) {
154
+ new_node->left = new_node->right = NULL;
128
155
  } else {
129
- new_node = create_node(key, value);
130
- if (cmp == -1) {
131
- new_node->left = tree->root->left;
132
- new_node->right = tree->root;
133
- tree->root->left = NULL;
134
- } else { /* cmp == 1 */
135
- new_node->right = tree->root->right;
136
- new_node->left = tree->root;
137
- tree->root->right = NULL;
156
+ cmp = tree->compare_function(key, n->key);
157
+ if (cmp < 0) {
158
+ new_node->left = n->left;
159
+ new_node->right = n;
160
+ n->left = NULL;
161
+ n->size = 1 + node_size(n->right);
162
+ } else {
163
+ new_node->right = n->right;
164
+ new_node->left = n;
165
+ n->right = NULL;
166
+ n->size = 1 + node_size(n->left);
138
167
  }
139
- tree->root = new_node;
140
- tree->size += 1;
141
168
  }
169
+ new_node->size = 1 + node_size(new_node->left) + node_size(new_node->right);
170
+ return new_node;
142
171
  }
143
172
 
144
173
  static VALUE get(splaytree *tree, VALUE key) {
145
174
  int cmp;
175
+
146
176
  if (!tree->root)
147
177
  return Qnil;
148
-
149
- splay(tree, key);
178
+
179
+ tree->root = splay(tree, tree->root, key);
150
180
  cmp = tree->compare_function(key, tree->root->key);
151
181
  if (cmp == 0) {
152
182
  return tree->root->value;
@@ -154,29 +184,28 @@ static VALUE get(splaytree *tree, VALUE key) {
154
184
  return Qnil;
155
185
  }
156
186
 
157
- static VALUE delete(splaytree *tree, VALUE key) {
158
- int cmp;
159
- splaytree_node *x, *deleted_root;
160
- VALUE deleted;
161
-
162
- splay(tree, key);
163
- cmp = tree->compare_function(key, tree->root->key);
187
+ static splaytree_node* delete(splaytree *tree, splaytree_node *n, VALUE key, VALUE *deleted) {
188
+ int cmp, tsize;
189
+ splaytree_node *x;
190
+
191
+ tsize = n->size;
192
+ n = splay(tree, n, key);
193
+ cmp = tree->compare_function(key, n->key);
164
194
  if (cmp == 0) {
165
- deleted = tree->root->value;
166
- deleted_root = tree->root;
167
- if (!(tree->root->left)) {
168
- tree->root = tree->root->right;
195
+ *deleted = n->value;
196
+ if (!n->left) {
197
+ x = n->right;
169
198
  } else {
170
- x = tree->root->right;
171
- tree->root = tree->root->left;
172
- splay(tree, key);
173
- tree->root->right = x;
199
+ x = splay(tree, n->left, key);
200
+ x->right = n->right;
174
201
  }
175
- free(deleted_root);
176
- tree->size -= 1;
177
- return deleted;
202
+ xfree(n);
203
+ if (x) {
204
+ x->size = tsize-1;
205
+ }
206
+ return x;
178
207
  }
179
- return Qnil;
208
+ return n;
180
209
  }
181
210
 
182
211
  static splaytree* splaytree_each_node(splaytree *tree, splaytree_node *node, void (*each)(splaytree *tree_, splaytree_node *node_, void* args), void* arguments) {
@@ -201,7 +230,7 @@ static splaytree* splay_each(splaytree *tree, void (*each)(splaytree *tree, spla
201
230
 
202
231
  // Methods to be called in Ruby
203
232
 
204
- static int id_compare_operator;
233
+ static VALUE id_compare_operator;
205
234
 
206
235
  static int splaytree_compare_function(VALUE a, VALUE b) {
207
236
  if (a == b) return 0;
@@ -211,8 +240,8 @@ static int splaytree_compare_function(VALUE a, VALUE b) {
211
240
  if (x > y) return 1;
212
241
  return -1;
213
242
  }
214
- if (TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString &&
215
- TYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString) {
243
+ if (TYPE(a) == T_STRING && rb_obj_is_kind_of(a, rb_cString) &&
244
+ TYPE(b) == T_STRING && rb_obj_is_kind_of(b, rb_cString)) {
216
245
  return rb_str_cmp(a, b);
217
246
  }
218
247
  return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
@@ -223,19 +252,39 @@ static VALUE splaytree_init(VALUE self)
223
252
  return self;
224
253
  }
225
254
 
226
- static void recursively_mark_nodes(splaytree_node *node) {
227
- if(node) {
228
- rb_gc_mark(node->key);
229
- rb_gc_mark(node->value);
230
- recursively_mark_nodes(node->left);
231
- recursively_mark_nodes(node->right);
232
- }
233
- }
234
-
235
255
  static void splaytree_mark(void *ptr) {
256
+ ll_node *current, *new, *last, *old;
236
257
  if (ptr) {
237
258
  splaytree *tree = ptr;
238
- recursively_mark_nodes(tree->root);
259
+
260
+ if (tree->root) {
261
+ current = ALLOC(ll_node);
262
+ last = current;
263
+ current->node = tree->root;
264
+ current->next = NULL;
265
+
266
+ while(current) {
267
+ rb_gc_mark(current->node->key);
268
+ rb_gc_mark(current->node->value);
269
+ if (current->node->left) {
270
+ new = ALLOC(ll_node);
271
+ new->node = current->node->left;
272
+ new->next = NULL;
273
+ last->next = new;
274
+ last = new;
275
+ }
276
+ if (current->node->right) {
277
+ new = ALLOC(ll_node);
278
+ new->node = current->node->right;
279
+ new->next = NULL;
280
+ last->next = new;
281
+ last = new;
282
+ }
283
+ old = current;
284
+ current = current->next;
285
+ xfree(old);
286
+ }
287
+ }
239
288
  }
240
289
  }
241
290
 
@@ -243,8 +292,7 @@ static void splaytree_free(void *ptr) {
243
292
  if (ptr) {
244
293
  splaytree *tree = ptr;
245
294
  recursively_free_nodes(tree->root);
246
- free(tree->header);
247
- free(tree);
295
+ xfree(tree);
248
296
  }
249
297
  }
250
298
 
@@ -255,7 +303,7 @@ static VALUE splaytree_alloc(VALUE klass) {
255
303
 
256
304
  static VALUE splaytree_push(VALUE self, VALUE key, VALUE value) {
257
305
  splaytree *tree = get_tree_from_self(self);
258
- insert(tree, key, value);
306
+ tree->root = insert(tree, tree->root, key, value);
259
307
  return value;
260
308
  }
261
309
 
@@ -266,7 +314,8 @@ static VALUE splaytree_get(VALUE self, VALUE key) {
266
314
 
267
315
  static VALUE splaytree_size(VALUE self) {
268
316
  splaytree *tree = get_tree_from_self(self);
269
- return INT2NUM(tree->size);
317
+ if(!tree->root) { return INT2NUM(0); }
318
+ return INT2NUM(tree->root->size);
270
319
  }
271
320
 
272
321
  static VALUE splaytree_is_empty(VALUE self) {
@@ -317,19 +366,19 @@ static VALUE splaytree_max_key(VALUE self) {
317
366
  }
318
367
 
319
368
  static VALUE splaytree_delete(VALUE self, VALUE key) {
369
+ VALUE deleted = Qnil;
320
370
  splaytree *tree = get_tree_from_self(self);
321
371
  if(!tree->root)
322
372
  return Qnil;
323
373
 
324
- return delete(tree, key);
374
+ tree->root = delete(tree, tree->root, key, &deleted);
375
+ return deleted;
325
376
  }
326
377
 
327
378
  static VALUE splaytree_clear(VALUE self) {
328
379
  splaytree *tree = get_tree_from_self(self);
329
380
  recursively_free_nodes(tree->root);
330
381
  tree->root = NULL;
331
- tree->size = 0;
332
-
333
382
  return Qnil;
334
383
  }
335
384