mongrel_experimental 1.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,55 @@
1
+ Mongrel Web Server (Mongrel) is copyrighted free software by Zed A. Shaw
2
+ <zedshaw at zedshaw dot com> and contributors. You can redistribute it
3
+ and/or modify it under either the terms of the GPL2 or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise make them
13
+ Freely Available, such as by posting said modifications to Usenet or an
14
+ equivalent medium, or by allowing the author to include your
15
+ modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) rename any non-standard executables so the names do not conflict with
21
+ standard executables, which must also be provided.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or executable
26
+ form, provided that you do at least ONE of the following:
27
+
28
+ a) distribute the executables and library files of the software,
29
+ together with instructions (in the manual page or equivalent) on where
30
+ to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of the
33
+ software.
34
+
35
+ c) give non-standard executables non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under this terms.
43
+
44
+ 5. The scripts and library files supplied as input to or produced as
45
+ output from the software do not automatically fall under the
46
+ copyright of the software, but belong to whomever generated them,
47
+ and may be sold commercially, and may be aggregated with this
48
+ software.
49
+
50
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
51
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
52
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53
+ PURPOSE.
54
+
55
+
@@ -0,0 +1,17 @@
1
+ CHANGELOG
2
+ COPYING
3
+ ext/uri_classifier/ext_help.h
4
+ ext/uri_classifier/extconf.rb
5
+ ext/uri_classifier/tst.h
6
+ ext/uri_classifier/tst_cleanup.c
7
+ ext/uri_classifier/tst_delete.c
8
+ ext/uri_classifier/tst_grow_node_free_list.c
9
+ ext/uri_classifier/tst_init.c
10
+ ext/uri_classifier/tst_insert.c
11
+ ext/uri_classifier/tst_search.c
12
+ ext/uri_classifier/uri_classifier.c
13
+ lib/mongrel_experimental.rb
14
+ LICENSE
15
+ Manifest
16
+ README
17
+ test/test_uriclassifier.rb
data/README ADDED
@@ -0,0 +1,3 @@
1
+ = Mongrel Experimental
2
+
3
+
@@ -0,0 +1,14 @@
1
+ #ifndef ext_help_h
2
+ #define ext_help_h
3
+
4
+ #define RAISE_NOT_NULL(T) if(T == NULL) rb_raise(rb_eArgError, "NULL found for " # T " when shouldn't be.");
5
+ #define DATA_GET(from,type,name) Data_Get_Struct(from,type,name); RAISE_NOT_NULL(name);
6
+ #define REQUIRE_TYPE(V, T) if(TYPE(V) != T) rb_raise(rb_eTypeError, "Wrong argument type for " # V " required " # T);
7
+
8
+ #ifdef DEBUG
9
+ #define TRACE() fprintf(stderr, "> %s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__)
10
+ #else
11
+ #define TRACE()
12
+ #endif
13
+
14
+ #endif
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ dir_config("uri_classifier")
4
+ have_library("c", "main")
5
+ create_makefile("uri_classifier")
@@ -0,0 +1,40 @@
1
+
2
+
3
+ struct node
4
+ {
5
+ unsigned char value;
6
+ struct node *left;
7
+ struct node *middle;
8
+ struct node *right;
9
+ };
10
+
11
+ struct tst
12
+ {
13
+ int node_line_width;
14
+ struct node_lines *node_lines;
15
+ struct node *free_list;
16
+ struct node *head[127];
17
+ };
18
+
19
+ struct node_lines
20
+ {
21
+ struct node *node_line;
22
+ struct node_lines *next;
23
+ };
24
+
25
+ enum tst_constants
26
+ {
27
+ TST_OK, TST_ERROR, TST_NULL_KEY, TST_DUPLICATE_KEY, TST_REPLACE, TST_LONGEST_MATCH
28
+ };
29
+
30
+ struct tst *tst_init(int node_line_width);
31
+
32
+ int tst_insert(unsigned char *key, void *data, struct tst *tst, int option, void **exist_ptr);
33
+
34
+ void *tst_search(const unsigned char *key, struct tst *tst, int option, unsigned int *match_len);
35
+
36
+ void *tst_delete(unsigned char *key, struct tst *tst);
37
+
38
+ void tst_cleanup(struct tst *tst);
39
+
40
+
@@ -0,0 +1,23 @@
1
+
2
+ #include "tst.h"
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+
6
+ void tst_cleanup(struct tst *tst)
7
+ {
8
+ struct node_lines *current_line;
9
+ struct node_lines *next_line;
10
+
11
+ next_line = tst->node_lines;
12
+
13
+ do
14
+ {
15
+ current_line = next_line;
16
+ next_line = current_line->next;
17
+ free(current_line->node_line);
18
+ free(current_line);
19
+ }
20
+ while(next_line != NULL);
21
+
22
+ free(tst);
23
+ }
@@ -0,0 +1,146 @@
1
+
2
+ #include "tst.h"
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+
6
+ void *tst_delete(unsigned char *key, struct tst *tst)
7
+ {
8
+ struct node *current_node;
9
+ struct node *current_node_parent;
10
+ struct node *last_branch;
11
+ struct node *last_branch_parent;
12
+ struct node *next_node;
13
+ struct node *last_branch_replacement;
14
+ struct node *last_branch_dangling_child;
15
+ int key_index;
16
+
17
+
18
+ if(key[0] == 0)
19
+ return NULL;
20
+ if(tst->head[(int)key[0]] == NULL)
21
+ return NULL;
22
+
23
+ last_branch = NULL;
24
+ last_branch_parent = NULL;
25
+ current_node = tst->head[(int)key[0]];
26
+ current_node_parent = NULL;
27
+ key_index = 1;
28
+ while(current_node != NULL)
29
+ {
30
+ if(key[key_index] == current_node->value)
31
+ {
32
+
33
+ if( (current_node->left != NULL) || (current_node->right != NULL) )
34
+ {
35
+ last_branch = current_node;
36
+ last_branch_parent = current_node_parent;
37
+ }
38
+ if(key[key_index] == 0)
39
+ break;
40
+ else
41
+ {
42
+ current_node_parent = current_node;
43
+ current_node = current_node->middle;
44
+ key_index++;
45
+ continue;
46
+ }
47
+ }
48
+ else if( ((current_node->value == 0) && (key[key_index] < 64)) ||
49
+ ((current_node->value != 0) && (key[key_index] <
50
+ current_node->value)) )
51
+ {
52
+ last_branch_parent = current_node;
53
+ current_node_parent = current_node;
54
+ current_node = current_node->left;
55
+ last_branch = current_node;
56
+ continue;
57
+ }
58
+ else
59
+ {
60
+ last_branch_parent = current_node;
61
+ current_node_parent = current_node;
62
+ current_node = current_node->right;
63
+ last_branch = current_node;
64
+ continue;
65
+ }
66
+
67
+ }
68
+ if(current_node == NULL)
69
+ return NULL;
70
+
71
+ if(last_branch == NULL)
72
+ {
73
+
74
+ next_node = tst->head[(int)key[0]];
75
+ tst->head[(int)key[0]] = NULL;
76
+ }
77
+ else if( (last_branch->left == NULL) && (last_branch->right == NULL) )
78
+ {
79
+
80
+ if(last_branch_parent->left == last_branch)
81
+ last_branch_parent->left = NULL;
82
+ else
83
+ last_branch_parent->right = NULL;
84
+
85
+ next_node = last_branch;
86
+ }
87
+ else
88
+ {
89
+
90
+ if( (last_branch->left != NULL) && (last_branch->right != NULL) )
91
+ {
92
+ last_branch_replacement = last_branch->right;
93
+ last_branch_dangling_child = last_branch->left;
94
+ }
95
+ else if(last_branch->right != NULL)
96
+ {
97
+ last_branch_replacement = last_branch->right;
98
+ last_branch_dangling_child = NULL;
99
+ }
100
+ else
101
+ {
102
+ last_branch_replacement = last_branch->left;
103
+ last_branch_dangling_child = NULL;
104
+ }
105
+
106
+ if(last_branch_parent == NULL)
107
+ tst->head[(int)key[0]]=last_branch_replacement;
108
+ else
109
+ {
110
+ if (last_branch_parent->left == last_branch)
111
+ last_branch_parent->left = last_branch_replacement;
112
+ else if (last_branch_parent->right == last_branch)
113
+ last_branch_parent->right = last_branch_replacement;
114
+ else
115
+ last_branch_parent->middle = last_branch_replacement;
116
+ }
117
+
118
+ if(last_branch_dangling_child != NULL)
119
+ {
120
+ current_node = last_branch_replacement;
121
+
122
+ while (current_node->left != NULL)
123
+ current_node = current_node->left;
124
+
125
+ current_node->left = last_branch_dangling_child;
126
+ }
127
+
128
+ next_node = last_branch;
129
+ }
130
+
131
+ do
132
+ {
133
+ current_node = next_node;
134
+ next_node = current_node->middle;
135
+
136
+ current_node->left = NULL;
137
+ current_node->right = NULL;
138
+ current_node->middle = tst->free_list;
139
+ tst->free_list = current_node;
140
+ }
141
+ while(current_node->value != 0);
142
+
143
+ return next_node;
144
+
145
+ }
146
+
@@ -0,0 +1,38 @@
1
+
2
+ #include "tst.h"
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+
6
+ int tst_grow_node_free_list(struct tst *tst)
7
+ {
8
+ struct node *current_node;
9
+ struct node_lines *new_line;
10
+ int i;
11
+
12
+
13
+ if((new_line = (struct node_lines *) malloc(sizeof(struct node_lines))) == NULL)
14
+ return TST_ERROR;
15
+
16
+ if((new_line->node_line = (struct node *)
17
+ calloc(tst->node_line_width, sizeof(struct node))) == NULL)
18
+ {
19
+ free(new_line);
20
+ return TST_ERROR;
21
+ }
22
+ else
23
+ {
24
+ new_line->next = tst->node_lines;
25
+ tst->node_lines = new_line;
26
+ }
27
+
28
+ current_node = tst->node_lines->node_line;
29
+ tst->free_list = current_node;
30
+ for (i = 1; i < tst->node_line_width; i++)
31
+ {
32
+ current_node->middle = &(tst->node_lines->node_line[i]);
33
+ current_node = current_node->middle;
34
+ }
35
+ current_node->middle = NULL;
36
+ return 1;
37
+ }
38
+
@@ -0,0 +1,41 @@
1
+
2
+ #include "tst.h"
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+
6
+ struct tst *tst_init(int width)
7
+ {
8
+ struct tst *tst;
9
+ struct node *current_node;
10
+ int i;
11
+
12
+
13
+ if((tst = (struct tst *) calloc(1, sizeof(struct tst))) == NULL)
14
+ return NULL;
15
+
16
+ if ((tst->node_lines = (struct node_lines *) calloc(1, sizeof(struct node_lines))) == NULL)
17
+ {
18
+ free(tst);
19
+ return NULL;
20
+ }
21
+
22
+ tst->node_line_width = width;
23
+ tst->node_lines->next = NULL;
24
+ if ((tst->node_lines->node_line = (struct node *) calloc(width, sizeof(struct node))) == NULL)
25
+ {
26
+ free(tst->node_lines);
27
+ free(tst);
28
+ return NULL;
29
+ }
30
+
31
+ current_node = tst->node_lines->node_line;
32
+ tst->free_list = current_node;
33
+ for (i = 1; i < width; i++)
34
+ {
35
+ current_node->middle = &(tst->node_lines->node_line[i]);
36
+ current_node = current_node->middle;
37
+ }
38
+ current_node->middle = NULL;
39
+ return tst;
40
+ }
41
+
@@ -0,0 +1,218 @@
1
+
2
+ #include "tst.h"
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+
7
+ int tst_grow_node_free_list(struct tst *tst);
8
+ int tst_insert(unsigned char *key, void *data, struct tst *tst, int option, void **exist_ptr)
9
+ {
10
+ struct node *current_node;
11
+ struct node *new_node_tree_begin = NULL;
12
+ struct node *new_node;
13
+ int key_index;
14
+ int perform_loop = 1;
15
+
16
+ if (key == NULL)
17
+ return TST_NULL_KEY;
18
+
19
+ if(key[0] == 0)
20
+ return TST_NULL_KEY;
21
+
22
+ if(tst->head[(int)key[0]] == NULL)
23
+ {
24
+
25
+ if(tst->free_list == NULL)
26
+ {
27
+ if(tst_grow_node_free_list(tst) != 1)
28
+ return TST_ERROR;
29
+ }
30
+ tst->head[(int)key[0]] = tst->free_list;
31
+
32
+ tst->free_list = tst->free_list->middle;
33
+ current_node = tst->head[(int)key[0]];
34
+ current_node->value = key[1];
35
+ if(key[1] == 0)
36
+ {
37
+ current_node->middle = data;
38
+ return TST_OK;
39
+ }
40
+ else
41
+ perform_loop = 0;
42
+ }
43
+
44
+ current_node = tst->head[(int)key[0]];
45
+ key_index = 1;
46
+ while(perform_loop == 1)
47
+ {
48
+ if(key[key_index] == current_node->value)
49
+ {
50
+
51
+ if(key[key_index] == 0)
52
+ {
53
+ if (option == TST_REPLACE)
54
+ {
55
+ if (exist_ptr != NULL)
56
+ *exist_ptr = current_node->middle;
57
+
58
+ current_node->middle = data;
59
+ return TST_OK;
60
+ }
61
+ else
62
+ {
63
+ if (exist_ptr != NULL)
64
+ *exist_ptr = current_node->middle;
65
+ return TST_DUPLICATE_KEY;
66
+ }
67
+ }
68
+ else
69
+ {
70
+ if(current_node->middle == NULL)
71
+ {
72
+
73
+ if(tst->free_list == NULL)
74
+ {
75
+ if(tst_grow_node_free_list(tst) != 1)
76
+ return TST_ERROR;
77
+ }
78
+ current_node->middle = tst->free_list;
79
+
80
+ tst->free_list = tst->free_list->middle;
81
+ new_node_tree_begin = current_node;
82
+ current_node = current_node->middle;
83
+ current_node->value = key[key_index];
84
+ break;
85
+ }
86
+ else
87
+ {
88
+ current_node = current_node->middle;
89
+ key_index++;
90
+ continue;
91
+ }
92
+ }
93
+ }
94
+ if(key[key_index] == 0)
95
+ {
96
+ if(tst->free_list == NULL)
97
+ {
98
+ if(tst_grow_node_free_list(tst) != 1)
99
+ return TST_ERROR;
100
+ }
101
+ new_node = tst->free_list;
102
+ tst->free_list = tst->free_list->middle;
103
+
104
+ memcpy((void*)new_node, (void*)current_node, sizeof(struct node));
105
+ current_node->value = 0;
106
+ if(new_node->value < 64)
107
+ {
108
+ current_node->left = new_node;
109
+ current_node->right = '\0';
110
+ }
111
+ else
112
+ {
113
+ current_node->left = '\0';
114
+ current_node->right = new_node;
115
+ }
116
+
117
+ current_node->middle = data;
118
+ return TST_OK;
119
+ }
120
+
121
+ if( ((current_node->value == 0) && (key[key_index] < 64)) ||
122
+ ((current_node->value != 0) && (key[key_index] <
123
+ current_node->value)) )
124
+ {
125
+
126
+ if (current_node->left == NULL)
127
+ {
128
+
129
+ if(tst->free_list == NULL)
130
+ {
131
+ if(tst_grow_node_free_list(tst) != 1)
132
+ return TST_ERROR;
133
+ }
134
+ current_node->left = tst->free_list;
135
+
136
+ tst->free_list = tst->free_list->middle;
137
+ new_node_tree_begin = current_node;
138
+ current_node = current_node->left;
139
+ current_node->value = key[key_index];
140
+ if(key[key_index] == 0)
141
+ {
142
+ current_node->middle = data;
143
+ return TST_OK;
144
+ }
145
+ else
146
+ break;
147
+ }
148
+ else
149
+ {
150
+ current_node = current_node->left;
151
+ continue;
152
+ }
153
+ }
154
+ else
155
+ {
156
+
157
+ if (current_node->right == NULL)
158
+ {
159
+
160
+ if(tst->free_list == NULL)
161
+ {
162
+ if(tst_grow_node_free_list(tst) != 1)
163
+ return TST_ERROR;
164
+ }
165
+ current_node->right = tst->free_list;
166
+
167
+ tst->free_list = tst->free_list->middle;
168
+ new_node_tree_begin = current_node;
169
+ current_node = current_node->right;
170
+ current_node->value = key[key_index];
171
+ break;
172
+ }
173
+ else
174
+ {
175
+ current_node = current_node->right;
176
+ continue;
177
+ }
178
+ }
179
+ }
180
+
181
+ do
182
+ {
183
+ key_index++;
184
+
185
+ if(tst->free_list == NULL)
186
+ {
187
+ if(tst_grow_node_free_list(tst) != 1)
188
+ {
189
+ current_node = new_node_tree_begin->middle;
190
+
191
+ while (current_node->middle != NULL)
192
+ current_node = current_node->middle;
193
+
194
+ current_node->middle = tst->free_list;
195
+ tst->free_list = new_node_tree_begin->middle;
196
+ new_node_tree_begin->middle = NULL;
197
+
198
+ return TST_ERROR;
199
+ }
200
+ }
201
+
202
+
203
+ if(tst->free_list == NULL)
204
+ {
205
+ if(tst_grow_node_free_list(tst) != 1)
206
+ return TST_ERROR;
207
+ }
208
+ current_node->middle = tst->free_list;
209
+
210
+ tst->free_list = tst->free_list->middle;
211
+ current_node = current_node->middle;
212
+ current_node->value = key[key_index];
213
+ } while(key[key_index] !=0);
214
+
215
+ current_node->middle = data;
216
+ return TST_OK;
217
+ }
218
+