ebb 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,12 @@
1
1
  require 'mkmf'
2
2
 
3
- unless pkg_config('glib-2.0')
4
- abort "Ebb requires glib-2.0 and pkg_config"
3
+ flags = []
4
+
5
+ if pkg_config("gnutls")
6
+ flags << '-DHAVE_GNUTLS'
5
7
  end
6
8
 
7
- flags = []
9
+ flags << '-DEV_USE_MONOTONIC=0'
8
10
 
9
11
  if have_header('sys/select.h')
10
12
  flags << '-DEV_USE_SELECT'
@@ -33,12 +35,14 @@ end
33
35
  dir = File.dirname(__FILE__)
34
36
  libev_dir = File.expand_path(dir + '/../libev')
35
37
 
36
- $LDFLAGS << " -lpthread "
38
+ #$LDFLAGS << " -lefence "
37
39
  $CFLAGS << " -I#{libev_dir} " << flags.join(' ')
38
40
  $defs << "-DRUBY_VERSION_CODE=#{RUBY_VERSION.gsub(/\D/, '')}"
39
41
 
40
- $srcs = ['ebb.c', 'ebb_ruby.c', 'parser.c']
41
- $objs = ['ebb.o', 'ebb_ruby.o', 'parser.o']
42
+ $srcs = ['ebb_ffi.c', "ebb.c", "ebb_request_parser.c", "rbtree.c"]
43
+ $objs = ['ebb_ffi.o', "ebb.o", "ebb_request_parser.o", "rbtree.o"]
44
+
45
+ CONFIG['warnflags'] = ""
42
46
 
43
- dir_config('ebb_ext')
44
- create_makefile('ebb_ext')
47
+ dir_config('ebb_ffi')
48
+ create_makefile('ebb_ffi')
@@ -0,0 +1,408 @@
1
+ /* Copyright (c) 2008 Derrick Coetzee
2
+ * http://en.literateprograms.org/Red-black_tree_(C)?oldid=7982
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a
5
+ * copy of this software and associated documentation files (the
6
+ * "Software"), to deal in the Software without restriction, including
7
+ * without limitation the rights to use, copy, modify, merge, publish,
8
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
9
+ * persons to whom the Software is furnished to do so, subject to the
10
+ * following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included
13
+ * in all copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
20
+ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ */
23
+
24
+ #include "rbtree.h"
25
+ #include <assert.h>
26
+
27
+ #ifndef NULL
28
+ # define NULL ((void*)0)
29
+ #endif
30
+
31
+
32
+ typedef rbtree_node node;
33
+ typedef enum rbtree_node_color color;
34
+
35
+
36
+ static node grandparent(node n);
37
+ static node sibling(node n);
38
+ static node uncle(node n);
39
+ static void verify_properties(rbtree t);
40
+ static void verify_property_1(node root);
41
+ static void verify_property_2(node root);
42
+ static color node_color(node n);
43
+ static void verify_property_4(node root);
44
+ static void verify_property_5(node root);
45
+ static void verify_property_5_helper(node n, int black_count, int* black_count_path);
46
+
47
+ static node lookup_node(rbtree t, void* key);
48
+ static void rotate_left(rbtree t, node n);
49
+ static void rotate_right(rbtree t, node n);
50
+
51
+ static void replace_node(rbtree t, node oldn, node newn);
52
+ static void insert_case1(rbtree t, node n);
53
+ static void insert_case2(rbtree t, node n);
54
+ static void insert_case3(rbtree t, node n);
55
+ static void insert_case4(rbtree t, node n);
56
+ static void insert_case5(rbtree t, node n);
57
+ static node maximum_node(node root);
58
+ static void delete_case1(rbtree t, node n);
59
+ static void delete_case2(rbtree t, node n);
60
+ static void delete_case3(rbtree t, node n);
61
+ static void delete_case4(rbtree t, node n);
62
+ static void delete_case5(rbtree t, node n);
63
+ static void delete_case6(rbtree t, node n);
64
+
65
+ node grandparent(node n) {
66
+ assert (n != NULL);
67
+ assert (n->parent != NULL); /* Not the root node */
68
+ assert (n->parent->parent != NULL); /* Not child of root */
69
+ return n->parent->parent;
70
+ }
71
+
72
+ node sibling(node n) {
73
+ assert (n != NULL);
74
+ assert (n->parent != NULL); /* Root node has no sibling */
75
+ if (n == n->parent->left)
76
+ return n->parent->right;
77
+ else
78
+ return n->parent->left;
79
+ }
80
+
81
+ node uncle(node n) {
82
+ assert (n != NULL);
83
+ assert (n->parent != NULL); /* Root node has no uncle */
84
+ assert (n->parent->parent != NULL); /* Children of root have no uncle */
85
+ return sibling(n->parent);
86
+ }
87
+
88
+ void verify_properties(rbtree t) {
89
+ #ifdef VERIFY_RBTREE
90
+ verify_property_1(t->root);
91
+ verify_property_2(t->root);
92
+ /* Property 3 is implicit */
93
+ verify_property_4(t->root);
94
+ verify_property_5(t->root);
95
+ #endif
96
+ }
97
+
98
+ void verify_property_1(node n) {
99
+ assert(node_color(n) == RED || node_color(n) == BLACK);
100
+ if (n == NULL) return;
101
+ verify_property_1(n->left);
102
+ verify_property_1(n->right);
103
+ }
104
+
105
+ void verify_property_2(node root) {
106
+ assert(node_color(root) == BLACK);
107
+ }
108
+
109
+ color node_color(node n) {
110
+ return n == NULL ? BLACK : n->color;
111
+ }
112
+
113
+ void verify_property_4(node n) {
114
+ if (node_color(n) == RED) {
115
+ assert (node_color(n->left) == BLACK);
116
+ assert (node_color(n->right) == BLACK);
117
+ assert (node_color(n->parent) == BLACK);
118
+ }
119
+ if (n == NULL) return;
120
+ verify_property_4(n->left);
121
+ verify_property_4(n->right);
122
+ }
123
+
124
+ void verify_property_5(node root) {
125
+ int black_count_path = -1;
126
+ verify_property_5_helper(root, 0, &black_count_path);
127
+ }
128
+
129
+ void verify_property_5_helper(node n, int black_count, int* path_black_count) {
130
+ if (node_color(n) == BLACK) {
131
+ black_count++;
132
+ }
133
+ if (n == NULL) {
134
+ if (*path_black_count == -1) {
135
+ *path_black_count = black_count;
136
+ } else {
137
+ assert (black_count == *path_black_count);
138
+ }
139
+ return;
140
+ }
141
+ verify_property_5_helper(n->left, black_count, path_black_count);
142
+ verify_property_5_helper(n->right, black_count, path_black_count);
143
+ }
144
+
145
+ void rbtree_init(rbtree t, rbtree_compare_func compare) {
146
+ t->root = NULL;
147
+ t->compare = compare;
148
+ verify_properties(t);
149
+ }
150
+
151
+ node lookup_node(rbtree t, void* key) {
152
+ node n = t->root;
153
+ while (n != NULL) {
154
+ int comp_result = t->compare(key, n->key);
155
+ if (comp_result == 0) {
156
+ return n;
157
+ } else if (comp_result < 0) {
158
+ n = n->left;
159
+ } else {
160
+ assert(comp_result > 0);
161
+ n = n->right;
162
+ }
163
+ }
164
+ return n;
165
+ }
166
+
167
+ void* rbtree_lookup(rbtree t, void* key) {
168
+ node n = lookup_node(t, key);
169
+ return n == NULL ? NULL : n->value;
170
+ }
171
+
172
+ void rotate_left(rbtree t, node n) {
173
+ node r = n->right;
174
+ replace_node(t, n, r);
175
+ n->right = r->left;
176
+ if (r->left != NULL) {
177
+ r->left->parent = n;
178
+ }
179
+ r->left = n;
180
+ n->parent = r;
181
+ }
182
+
183
+ void rotate_right(rbtree t, node n) {
184
+ node L = n->left;
185
+ replace_node(t, n, L);
186
+ n->left = L->right;
187
+ if (L->right != NULL) {
188
+ L->right->parent = n;
189
+ }
190
+ L->right = n;
191
+ n->parent = L;
192
+ }
193
+
194
+ void replace_node(rbtree t, node oldn, node newn) {
195
+ if (oldn->parent == NULL) {
196
+ t->root = newn;
197
+ } else {
198
+ if (oldn == oldn->parent->left)
199
+ oldn->parent->left = newn;
200
+ else
201
+ oldn->parent->right = newn;
202
+ }
203
+ if (newn != NULL) {
204
+ newn->parent = oldn->parent;
205
+ }
206
+ }
207
+
208
+ void rbtree_insert(rbtree t, rbtree_node inserted_node) {
209
+ inserted_node->color = RED;
210
+ inserted_node->left = NULL;
211
+ inserted_node->right = NULL;
212
+ inserted_node->parent = NULL;
213
+
214
+ if (t->root == NULL) {
215
+ t->root = inserted_node;
216
+ } else {
217
+ node n = t->root;
218
+ while (1) {
219
+ int comp_result = t->compare(inserted_node->key, n->key);
220
+ if (comp_result == 0) {
221
+ n->value = inserted_node->value;
222
+ return;
223
+ } else if (comp_result < 0) {
224
+ if (n->left == NULL) {
225
+ n->left = inserted_node;
226
+ break;
227
+ } else {
228
+ n = n->left;
229
+ }
230
+ } else {
231
+ assert (comp_result > 0);
232
+ if (n->right == NULL) {
233
+ n->right = inserted_node;
234
+ break;
235
+ } else {
236
+ n = n->right;
237
+ }
238
+ }
239
+ }
240
+ inserted_node->parent = n;
241
+ }
242
+ insert_case1(t, inserted_node);
243
+ verify_properties(t);
244
+ }
245
+
246
+ void insert_case1(rbtree t, node n) {
247
+ if (n->parent == NULL)
248
+ n->color = BLACK;
249
+ else
250
+ insert_case2(t, n);
251
+ }
252
+
253
+ void insert_case2(rbtree t, node n) {
254
+ if (node_color(n->parent) == BLACK)
255
+ return; /* Tree is still valid */
256
+ else
257
+ insert_case3(t, n);
258
+ }
259
+
260
+ void insert_case3(rbtree t, node n) {
261
+ if (node_color(uncle(n)) == RED) {
262
+ n->parent->color = BLACK;
263
+ uncle(n)->color = BLACK;
264
+ grandparent(n)->color = RED;
265
+ insert_case1(t, grandparent(n));
266
+ } else {
267
+ insert_case4(t, n);
268
+ }
269
+ }
270
+
271
+ void insert_case4(rbtree t, node n) {
272
+ if (n == n->parent->right && n->parent == grandparent(n)->left) {
273
+ rotate_left(t, n->parent);
274
+ n = n->left;
275
+ } else if (n == n->parent->left && n->parent == grandparent(n)->right) {
276
+ rotate_right(t, n->parent);
277
+ n = n->right;
278
+ }
279
+ insert_case5(t, n);
280
+ }
281
+
282
+ void insert_case5(rbtree t, node n) {
283
+ n->parent->color = BLACK;
284
+ grandparent(n)->color = RED;
285
+ if (n == n->parent->left && n->parent == grandparent(n)->left) {
286
+ rotate_right(t, grandparent(n));
287
+ } else {
288
+ assert (n == n->parent->right && n->parent == grandparent(n)->right);
289
+ rotate_left(t, grandparent(n));
290
+ }
291
+ }
292
+
293
+ rbtree_node rbtree_delete(rbtree t, void* key) {
294
+ node child;
295
+ node n = lookup_node(t, key);
296
+ if (n == NULL) return NULL; /* Key not found, do nothing */
297
+ if (n->left != NULL && n->right != NULL) {
298
+ /* Copy key/value from predecessor and then delete it instead */
299
+ node pred = maximum_node(n->left);
300
+ n->key = pred->key;
301
+ n->value = pred->value;
302
+ n = pred;
303
+ }
304
+
305
+ assert(n->left == NULL || n->right == NULL);
306
+ child = n->right == NULL ? n->left : n->right;
307
+ if (node_color(n) == BLACK) {
308
+ n->color = node_color(child);
309
+ delete_case1(t, n);
310
+ }
311
+ replace_node(t, n, child);
312
+
313
+ verify_properties(t);
314
+ return n;
315
+ }
316
+
317
+ static node maximum_node(node n) {
318
+ assert (n != NULL);
319
+ while (n->right != NULL) {
320
+ n = n->right;
321
+ }
322
+ return n;
323
+ }
324
+
325
+ void delete_case1(rbtree t, node n) {
326
+ if (n->parent == NULL)
327
+ return;
328
+ else
329
+ delete_case2(t, n);
330
+ }
331
+
332
+ void delete_case2(rbtree t, node n) {
333
+ if (node_color(sibling(n)) == RED) {
334
+ n->parent->color = RED;
335
+ sibling(n)->color = BLACK;
336
+ if (n == n->parent->left)
337
+ rotate_left(t, n->parent);
338
+ else
339
+ rotate_right(t, n->parent);
340
+ }
341
+ delete_case3(t, n);
342
+ }
343
+
344
+ void delete_case3(rbtree t, node n) {
345
+ if (node_color(n->parent) == BLACK &&
346
+ node_color(sibling(n)) == BLACK &&
347
+ node_color(sibling(n)->left) == BLACK &&
348
+ node_color(sibling(n)->right) == BLACK)
349
+ {
350
+ sibling(n)->color = RED;
351
+ delete_case1(t, n->parent);
352
+ }
353
+ else
354
+ delete_case4(t, n);
355
+ }
356
+
357
+ void delete_case4(rbtree t, node n) {
358
+ if (node_color(n->parent) == RED &&
359
+ node_color(sibling(n)) == BLACK &&
360
+ node_color(sibling(n)->left) == BLACK &&
361
+ node_color(sibling(n)->right) == BLACK)
362
+ {
363
+ sibling(n)->color = RED;
364
+ n->parent->color = BLACK;
365
+ }
366
+ else
367
+ delete_case5(t, n);
368
+ }
369
+
370
+ void delete_case5(rbtree t, node n) {
371
+ if (n == n->parent->left &&
372
+ node_color(sibling(n)) == BLACK &&
373
+ node_color(sibling(n)->left) == RED &&
374
+ node_color(sibling(n)->right) == BLACK)
375
+ {
376
+ sibling(n)->color = RED;
377
+ sibling(n)->left->color = BLACK;
378
+ rotate_right(t, sibling(n));
379
+ }
380
+ else if (n == n->parent->right &&
381
+ node_color(sibling(n)) == BLACK &&
382
+ node_color(sibling(n)->right) == RED &&
383
+ node_color(sibling(n)->left) == BLACK)
384
+ {
385
+ sibling(n)->color = RED;
386
+ sibling(n)->right->color = BLACK;
387
+ rotate_left(t, sibling(n));
388
+ }
389
+ delete_case6(t, n);
390
+ }
391
+
392
+ void delete_case6(rbtree t, node n) {
393
+ sibling(n)->color = node_color(n->parent);
394
+ n->parent->color = BLACK;
395
+ if (n == n->parent->left) {
396
+ assert (node_color(sibling(n)->right) == RED);
397
+ sibling(n)->right->color = BLACK;
398
+ rotate_left(t, n->parent);
399
+ }
400
+ else
401
+ {
402
+ assert (node_color(sibling(n)->left) == RED);
403
+ sibling(n)->left->color = BLACK;
404
+ rotate_right(t, n->parent);
405
+ }
406
+ }
407
+
408
+
@@ -0,0 +1,54 @@
1
+ /* Copyright (c) 2008 Derrick Coetzee
2
+ * http://en.literateprograms.org/Red-black_tree_(C)?oldid=7982
3
+ * Small changes by Ryah Dahl
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a
6
+ * copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
10
+ * persons to whom the Software is furnished to do so, subject to the
11
+ * following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included
14
+ * in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21
+ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+ #ifndef _RBTREE_H_
26
+ #define _RBTREE_H_
27
+
28
+ enum rbtree_node_color { RED, BLACK };
29
+
30
+ typedef int (*rbtree_compare_func)(void* left_key, void* right_key);
31
+
32
+ typedef struct rbtree_node_t {
33
+ struct rbtree_node_t* left; /* private */
34
+ struct rbtree_node_t* right; /* private */
35
+ struct rbtree_node_t* parent; /* private */
36
+ enum rbtree_node_color color; /* private */
37
+ void* key; /* public */
38
+ void* value; /* public */
39
+ } *rbtree_node;
40
+
41
+ typedef struct rbtree_t {
42
+ rbtree_node root; /* private */
43
+ rbtree_compare_func compare; /* private */
44
+ } *rbtree;
45
+
46
+
47
+ void rbtree_init(rbtree t, rbtree_compare_func);
48
+ void* rbtree_lookup(rbtree t, void* key);
49
+ void rbtree_insert(rbtree t, rbtree_node);
50
+ /* you must free the returned node */
51
+ rbtree_node rbtree_delete(rbtree t, void* key);
52
+
53
+ #endif
54
+