Mercurial > hg > nginx
comparison src/core/ngx_radix_tree.c @ 2369:12e8e0045096 radix_with_skip
add radix tree skip node
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 03 Dec 2008 13:26:02 +0000 |
parents | 62be1c4edfba |
children |
comparison
equal
deleted
inserted
replaced
2368:62be1c4edfba | 2369:12e8e0045096 |
---|---|
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 | 9 |
10 | 10 |
11 static ngx_int_t ngx_radix32tree_delete_node(ngx_radix_tree_t *tree, | 11 static ngx_int_t ngx_radix32tree_delete_node(ngx_radix_tree_t *tree, |
12 uint32_t key, uint32_t mask, ngx_radix_node_t **pnode, uint32_t bit); | 12 uint32_t key, uint32_t mask, ngx_radix_node_t **pnode, uint32_t bit); |
13 void ngx_radix32tree_compress_node(ngx_radix_tree_t *tree, | |
14 ngx_radix_node_t *node); | |
13 static void *ngx_radix_alloc(ngx_radix_tree_t *tree); | 15 static void *ngx_radix_alloc(ngx_radix_tree_t *tree); |
14 | 16 |
15 | 17 |
16 ngx_radix_tree_t * | 18 ngx_radix_tree_t * |
17 ngx_radix_tree_create(ngx_pool_t *pool, ngx_int_t preallocate) | 19 ngx_radix_tree_create(ngx_pool_t *pool, ngx_int_t preallocate) |
26 | 28 |
27 tree->pool = pool; | 29 tree->pool = pool; |
28 tree->free = NULL; | 30 tree->free = NULL; |
29 tree->start = NULL; | 31 tree->start = NULL; |
30 tree->size = 0; | 32 tree->size = 0; |
33 tree->count = 0; | |
31 | 34 |
32 tree->root = ngx_radix_alloc(tree); | 35 tree->root = ngx_radix_alloc(tree); |
33 if (tree->root == NULL) { | 36 if (tree->root == NULL) { |
34 return NULL; | 37 return NULL; |
35 } | 38 } |
203 return NGX_ERROR; | 206 return NGX_ERROR; |
204 | 207 |
205 } else { | 208 } else { |
206 node->right = tree->free; | 209 node->right = tree->free; |
207 tree->free = node; | 210 tree->free = node; |
211 tree->count--; | |
208 | 212 |
209 *pnode = NULL; | 213 *pnode = NULL; |
210 } | 214 } |
211 | 215 |
212 return NGX_OK; | 216 return NGX_OK; |
228 return NGX_OK; | 232 return NGX_OK; |
229 } | 233 } |
230 | 234 |
231 node->right = tree->free; | 235 node->right = tree->free; |
232 tree->free = node; | 236 tree->free = node; |
237 tree->count--; | |
233 | 238 |
234 *pnode = NULL; | 239 *pnode = NULL; |
235 | 240 |
236 return NGX_OK; | 241 return NGX_OK; |
242 } | |
243 | |
244 | |
245 void | |
246 ngx_radix32tree_compress(ngx_radix_tree_t *tree) | |
247 { | |
248 if (tree->root) { | |
249 ngx_radix32tree_compress_node(tree, tree->root); | |
250 } | |
251 } | |
252 | |
253 | |
254 void | |
255 ngx_radix32tree_compress_node(ngx_radix_tree_t *tree, ngx_radix_node_t *node) | |
256 { | |
257 uintptr_t skip; | |
258 ngx_radix_node_t *n; | |
259 | |
260 if (node->right) { | |
261 | |
262 skip = 0; | |
263 | |
264 for (n = node->right; | |
265 n->right && n->left == NULL && n->value == NGX_RADIX_NO_VALUE; | |
266 n = node->right) | |
267 { | |
268 node->right = n->right; | |
269 | |
270 n->right = tree->free; | |
271 tree->free = n; | |
272 tree->count--; | |
273 | |
274 skip++; | |
275 } | |
276 | |
277 node->right->skip = skip; | |
278 | |
279 ngx_radix32tree_compress_node(tree, node->right); | |
280 } | |
281 | |
282 if (node->left) { | |
283 | |
284 skip = 0; | |
285 | |
286 for (n = node->left; | |
287 n->left && n->right == NULL && n->value == NGX_RADIX_NO_VALUE; | |
288 n = node->left) | |
289 { | |
290 node->left = n->left; | |
291 | |
292 n->right = tree->free; | |
293 tree->free = n; | |
294 tree->count--; | |
295 | |
296 skip++; | |
297 } | |
298 | |
299 node->left->skip = skip; | |
300 | |
301 ngx_radix32tree_compress_node(tree, node->left); | |
302 } | |
237 } | 303 } |
238 | 304 |
239 | 305 |
240 uintptr_t | 306 uintptr_t |
241 ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key) | 307 ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key) |
242 { | 308 { |
243 uint32_t bit; | 309 uint32_t bit, test; |
244 uintptr_t value; | 310 uintptr_t value, skip; |
245 ngx_radix_node_t *node; | 311 ngx_radix_node_t *node; |
246 | 312 |
247 bit = 0x80000000; | |
248 value = NGX_RADIX_NO_VALUE; | 313 value = NGX_RADIX_NO_VALUE; |
249 node = tree->root; | 314 node = tree->root; |
250 | 315 |
251 while (node) { | 316 if (node == NULL) { |
317 return NGX_RADIX_NO_VALUE; | |
318 } | |
319 | |
320 bit = 0x80000000; | |
321 | |
322 for ( ;; ) { | |
323 | |
252 if (node->value != NGX_RADIX_NO_VALUE) { | 324 if (node->value != NGX_RADIX_NO_VALUE) { |
253 value = node->value; | 325 value = node->value; |
254 } | 326 } |
255 | 327 |
256 if (key & bit) { | 328 if (key & bit) { |
257 node = node->right; | 329 node = node->right; |
330 test = 0; | |
258 | 331 |
259 } else { | 332 } else { |
260 node = node->left; | 333 node = node->left; |
334 test = bit >> 1; | |
335 } | |
336 | |
337 if (node == NULL) { | |
338 return value; | |
261 } | 339 } |
262 | 340 |
263 bit >>= 1; | 341 bit >>= 1; |
264 } | 342 |
265 | 343 for (skip = node->skip; skip; skip--) { |
266 return value; | 344 |
345 if ((key & bit) == test) { | |
346 return value; | |
347 } | |
348 | |
349 bit >>= 1; | |
350 test >>= 1; | |
351 } | |
352 } | |
267 } | 353 } |
268 | 354 |
269 | 355 |
270 static void * | 356 static void * |
271 ngx_radix_alloc(ngx_radix_tree_t *tree) | 357 ngx_radix_alloc(ngx_radix_tree_t *tree) |
273 char *p; | 359 char *p; |
274 | 360 |
275 if (tree->free) { | 361 if (tree->free) { |
276 p = (char *) tree->free; | 362 p = (char *) tree->free; |
277 tree->free = tree->free->right; | 363 tree->free = tree->free->right; |
364 tree->count++; | |
278 return p; | 365 return p; |
279 } | 366 } |
280 | 367 |
281 if (tree->size < sizeof(ngx_radix_node_t)) { | 368 if (tree->size < sizeof(ngx_radix_node_t)) { |
282 tree->start = ngx_pmemalign(tree->pool, ngx_pagesize, ngx_pagesize); | 369 tree->start = ngx_pmemalign(tree->pool, ngx_pagesize, ngx_pagesize); |
288 } | 375 } |
289 | 376 |
290 p = tree->start; | 377 p = tree->start; |
291 tree->start += sizeof(ngx_radix_node_t); | 378 tree->start += sizeof(ngx_radix_node_t); |
292 tree->size -= sizeof(ngx_radix_node_t); | 379 tree->size -= sizeof(ngx_radix_node_t); |
380 tree->count++; | |
293 | 381 |
294 return p; | 382 return p; |
295 } | 383 } |