| @@ -1,17 +1,17 @@ | | | @@ -1,17 +1,17 @@ |
1 | /* $NetBSD: radixtree.c,v 1.17.2.4 2012/08/01 21:09:27 yamt Exp $ */ | | 1 | /* $NetBSD: radixtree.c,v 1.17.2.5 2014/03/25 16:21:08 yamt Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c)2011,2012 YAMAMOTO Takashi, | | 4 | * Copyright (c)2011,2012,2013 YAMAMOTO Takashi, |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * | | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | | 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| @@ -34,78 +34,105 @@ | | | @@ -34,78 +34,105 @@ |
34 | * This is an implementation of radix tree, whose keys are uint64_t and leafs | | 34 | * This is an implementation of radix tree, whose keys are uint64_t and leafs |
35 | * are user provided pointers. | | 35 | * are user provided pointers. |
36 | * | | 36 | * |
37 | * Leaf nodes are just void * and this implementation doesn't care about | | 37 | * Leaf nodes are just void * and this implementation doesn't care about |
38 | * what they actually point to. However, this implementation has an assumption | | 38 | * what they actually point to. However, this implementation has an assumption |
39 | * about their alignment. Specifically, this implementation assumes that their | | 39 | * about their alignment. Specifically, this implementation assumes that their |
40 | * 2 LSBs are always zero and uses them for internal accounting. | | 40 | * 2 LSBs are always zero and uses them for internal accounting. |
41 | * | | 41 | * |
42 | * Intermediate nodes and memory allocation: | | 42 | * Intermediate nodes and memory allocation: |
43 | * | | 43 | * |
44 | * Intermediate nodes are automatically allocated and freed internally and | | 44 | * Intermediate nodes are automatically allocated and freed internally and |
45 | * basically users don't need to care about them. The allocation is done via | | 45 | * basically users don't need to care about them. The allocation is done via |
46 | * pool_cache_get(9) for _KERNEL, malloc(3) for userland, and alloc() for | | 46 | * pool_cache_get(9) for _KERNEL, malloc(3) for userland, and alloc() for |
47 | * _STANDALONE environment. Only radix_tree_insert_node function can allocatei | | 47 | * _STANDALONE environment. Only radix_tree_insert_node function can allocate |
48 | * memory for intermediate nodes and thus can fail for ENOMEM. | | 48 | * memory for intermediate nodes and thus can fail for ENOMEM. |
49 | * | | 49 | * |
50 | * Efficiency: | | 50 | * Memory Efficiency: |
51 | * | | 51 | * |
52 | * It's designed to work efficiently with dense index distribution. | | 52 | * It's designed to work efficiently with dense index distribution. |
53 | * The memory consumption (number of necessary intermediate nodes) heavily | | 53 | * The memory consumption (number of necessary intermediate nodes) heavily |
54 | * depends on the index distribution. Basically, more dense index distribution | | 54 | * depends on the index distribution. Basically, more dense index distribution |
55 | * consumes less nodes per item. Approximately, | | 55 | * consumes less nodes per item. Approximately, |
| | | 56 | * |
56 | * - the best case: about RADIX_TREE_PTR_PER_NODE items per intermediate node. | | 57 | * - the best case: about RADIX_TREE_PTR_PER_NODE items per intermediate node. |
| | | 58 | * it would look like the following. |
| | | 59 | * |
| | | 60 | * root (t_height=1) |
| | | 61 | * | |
| | | 62 | * v |
| | | 63 | * [ | | | ] (intermediate node. RADIX_TREE_PTR_PER_NODE=4 in this fig) |
| | | 64 | * | | | | |
| | | 65 | * v v v v |
| | | 66 | * p p p p (items) |
| | | 67 | * |
57 | * - the worst case: RADIX_TREE_MAX_HEIGHT intermediate nodes per item. | | 68 | * - the worst case: RADIX_TREE_MAX_HEIGHT intermediate nodes per item. |
| | | 69 | * it would look like the following if RADIX_TREE_MAX_HEIGHT=3. |
58 | * | | 70 | * |
59 | * The height of tree is dynamic. It's smaller if only small index values are | | 71 | * root (t_height=3) |
60 | * used. As an extreme case, if only index 0 is used, the corresponding value | | 72 | * | |
61 | * is directly stored in the root of the tree (struct radix_tree) without | | 73 | * v |
62 | * allocating any intermediate nodes. | | 74 | * [ | | | ] |
| | | 75 | * | |
| | | 76 | * v |
| | | 77 | * [ | | | ] |
| | | 78 | * | |
| | | 79 | * v |
| | | 80 | * [ | | | ] |
| | | 81 | * | |
| | | 82 | * v |
| | | 83 | * p |
| | | 84 | * |
| | | 85 | * The height of tree (t_height) is dynamic. It's smaller if only small |
| | | 86 | * index values are used. As an extreme case, if only index 0 is used, |
| | | 87 | * the corresponding value is directly stored in the root of the tree |
| | | 88 | * (struct radix_tree) without allocating any intermediate nodes. In that |
| | | 89 | * case, t_height=0. |
63 | * | | 90 | * |
64 | * Gang lookup: | | 91 | * Gang lookup: |
65 | * | | 92 | * |
66 | * This implementation provides a way to scan many nodes quickly via | | 93 | * This implementation provides a way to scan many nodes quickly via |
67 | * radix_tree_gang_lookup_node function and its varients. | | 94 | * radix_tree_gang_lookup_node function and its varients. |
68 | * | | 95 | * |
69 | * Tags: | | 96 | * Tags: |
70 | * | | 97 | * |
71 | * This implementation provides tagging functionality, which allows quick | | 98 | * This implementation provides tagging functionality, which allows quick |
72 | * scanning of a subset of leaf nodes. Leaf nodes are untagged when inserted | | 99 | * scanning of a subset of leaf nodes. Leaf nodes are untagged when inserted |
73 | * into the tree and can be tagged by radix_tree_set_tag function. | | 100 | * into the tree and can be tagged by radix_tree_set_tag function. |
74 | * radix_tree_gang_lookup_tagged_node function and its variants returns only | | 101 | * radix_tree_gang_lookup_tagged_node function and its variants returns only |
75 | * leaf nodes with the given tag. To reduce amount of nodes to visit for | | 102 | * leaf nodes with the given tag. To reduce amount of nodes to visit for |
76 | * these functions, this implementation keeps tagging information in internal | | 103 | * these functions, this implementation keeps tagging information in internal |
77 | * intermediate nodes and quickly skips uninterested parts of a tree. | | 104 | * intermediate nodes and quickly skips uninterested parts of a tree. |
78 | * | | 105 | * |
79 | * A tree has RADIX_TREE_TAG_ID_MAX independent tag spaces, each of which are | | 106 | * A tree has RADIX_TREE_TAG_ID_MAX independent tag spaces, each of which are |
80 | * identified by an zero-origin numbers, tagid. For the current implementation, | | 107 | * identified by an zero-origin numbers, tagid. For the current implementation, |
81 | * RADIX_TREE_TAG_ID_MAX is 2. A set of tags is described as a bitmask tagmask, | | 108 | * RADIX_TREE_TAG_ID_MAX is 2. A set of tags is described as a bitmask tagmask, |
82 | * which is a bitwise OR of (1 << tagid). | | 109 | * which is a bitwise OR of (1 << tagid). |
83 | */ | | 110 | */ |
84 | | | 111 | |
85 | #include <sys/cdefs.h> | | 112 | #include <sys/cdefs.h> |
86 | | | 113 | |
87 | #if defined(_KERNEL) || defined(_STANDALONE) | | 114 | #if defined(_KERNEL) || defined(_STANDALONE) |
88 | __KERNEL_RCSID(0, "$NetBSD: radixtree.c,v 1.17.2.4 2012/08/01 21:09:27 yamt Exp $"); | | 115 | __KERNEL_RCSID(0, "$NetBSD: radixtree.c,v 1.17.2.5 2014/03/25 16:21:08 yamt Exp $"); |
89 | #include <sys/param.h> | | 116 | #include <sys/param.h> |
90 | #include <sys/errno.h> | | 117 | #include <sys/errno.h> |
91 | #include <sys/pool.h> | | 118 | #include <sys/pool.h> |
92 | #include <sys/radixtree.h> | | 119 | #include <sys/radixtree.h> |
93 | #include <lib/libkern/libkern.h> | | 120 | #include <lib/libkern/libkern.h> |
94 | #if defined(_STANDALONE) | | 121 | #if defined(_STANDALONE) |
95 | #include <lib/libsa/stand.h> | | 122 | #include <lib/libsa/stand.h> |
96 | #endif /* defined(_STANDALONE) */ | | 123 | #endif /* defined(_STANDALONE) */ |
97 | #else /* defined(_KERNEL) || defined(_STANDALONE) */ | | 124 | #else /* defined(_KERNEL) || defined(_STANDALONE) */ |
98 | __RCSID("$NetBSD: radixtree.c,v 1.17.2.4 2012/08/01 21:09:27 yamt Exp $"); | | 125 | __RCSID("$NetBSD: radixtree.c,v 1.17.2.5 2014/03/25 16:21:08 yamt Exp $"); |
99 | #include <assert.h> | | 126 | #include <assert.h> |
100 | #include <errno.h> | | 127 | #include <errno.h> |
101 | #include <stdbool.h> | | 128 | #include <stdbool.h> |
102 | #include <stdlib.h> | | 129 | #include <stdlib.h> |
103 | #include <string.h> | | 130 | #include <string.h> |
104 | #if 1 | | 131 | #if 1 |
105 | #define KASSERT assert | | 132 | #define KASSERT assert |
106 | #else | | 133 | #else |
107 | #define KASSERT(a) /* nothing */ | | 134 | #define KASSERT(a) /* nothing */ |
108 | #endif | | 135 | #endif |
109 | #endif /* defined(_KERNEL) || defined(_STANDALONE) */ | | 136 | #endif /* defined(_KERNEL) || defined(_STANDALONE) */ |
110 | | | 137 | |
111 | #include <sys/radixtree.h> | | 138 | #include <sys/radixtree.h> |