| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ptree.c,v 1.4 2009/01/18 12:06:14 lukem Exp $ */ | | 1 | /* $NetBSD: ptree.c,v 1.5 2009/06/07 03:12:40 yamt Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Matt Thomas <matt@3am-software.com>. | | 8 | * by Matt Thomas <matt@3am-software.com>. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -30,40 +30,40 @@ | | | @@ -30,40 +30,40 @@ |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #define _PT_PRIVATE | | 32 | #define _PT_PRIVATE |
33 | | | 33 | |
34 | #if defined(PTCHECK) && !defined(PTDEBUG) | | 34 | #if defined(PTCHECK) && !defined(PTDEBUG) |
35 | #define PTDEBUG | | 35 | #define PTDEBUG |
36 | #endif | | 36 | #endif |
37 | | | 37 | |
38 | #if defined(_KERNEL) || defined(_STANDALONE) | | 38 | #if defined(_KERNEL) || defined(_STANDALONE) |
39 | #include <sys/param.h> | | 39 | #include <sys/param.h> |
40 | #include <sys/types.h> | | 40 | #include <sys/types.h> |
41 | #include <sys/systm.h> | | 41 | #include <sys/systm.h> |
42 | #include <lib/libkern/libkern.h> | | 42 | #include <lib/libkern/libkern.h> |
43 | __KERNEL_RCSID(0, "$NetBSD: ptree.c,v 1.4 2009/01/18 12:06:14 lukem Exp $"); | | 43 | __KERNEL_RCSID(0, "$NetBSD: ptree.c,v 1.5 2009/06/07 03:12:40 yamt Exp $"); |
44 | #else | | 44 | #else |
45 | #include <stddef.h> | | 45 | #include <stddef.h> |
46 | #include <stdint.h> | | 46 | #include <stdint.h> |
47 | #include <limits.h> | | 47 | #include <limits.h> |
48 | #include <stdbool.h> | | 48 | #include <stdbool.h> |
49 | #include <string.h> | | 49 | #include <string.h> |
50 | #ifdef PTDEBUG | | 50 | #ifdef PTDEBUG |
51 | #include <assert.h> | | 51 | #include <assert.h> |
52 | #define KASSERT(e) assert(e) | | 52 | #define KASSERT(e) assert(e) |
53 | #else | | 53 | #else |
54 | #define KASSERT(e) do { } while (/*CONSTCOND*/ 0) | | 54 | #define KASSERT(e) do { } while (/*CONSTCOND*/ 0) |
55 | #endif | | 55 | #endif |
56 | __RCSID("$NetBSD: ptree.c,v 1.4 2009/01/18 12:06:14 lukem Exp $"); | | 56 | __RCSID("$NetBSD: ptree.c,v 1.5 2009/06/07 03:12:40 yamt Exp $"); |
57 | #endif /* _KERNEL || _STANDALONE */ | | 57 | #endif /* _KERNEL || _STANDALONE */ |
58 | | | 58 | |
59 | #ifdef _LIBC | | 59 | #ifdef _LIBC |
60 | #include "namespace.h" | | 60 | #include "namespace.h" |
61 | #endif | | 61 | #endif |
62 | | | 62 | |
63 | #ifdef PTTEST | | 63 | #ifdef PTTEST |
64 | #include "ptree.h" | | 64 | #include "ptree.h" |
65 | #else | | 65 | #else |
66 | #include <sys/ptree.h> | | 66 | #include <sys/ptree.h> |
67 | #endif | | 67 | #endif |
68 | | | 68 | |
69 | /* | | 69 | /* |
| @@ -72,45 +72,45 @@ __RCSID("$NetBSD: ptree.c,v 1.4 2009/01/ | | | @@ -72,45 +72,45 @@ __RCSID("$NetBSD: ptree.c,v 1.4 2009/01/ |
72 | * tree would have N leaves, N-1 branching nodes, and a root pointer. Each | | 72 | * tree would have N leaves, N-1 branching nodes, and a root pointer. Each |
73 | * branching node would have left(0) and right(1) pointers that either point | | 73 | * branching node would have left(0) and right(1) pointers that either point |
74 | * to another branching node or a leaf node. The root pointer would also | | 74 | * to another branching node or a leaf node. The root pointer would also |
75 | * point to either the first branching node or a leaf node. Leaf nodes | | 75 | * point to either the first branching node or a leaf node. Leaf nodes |
76 | * have no need for pointers. | | 76 | * have no need for pointers. |
77 | * | | 77 | * |
78 | * However, allocation for these branching nodes is problematic since the | | 78 | * However, allocation for these branching nodes is problematic since the |
79 | * allocation could fail. This would cause insertions to fail for reasons | | 79 | * allocation could fail. This would cause insertions to fail for reasons |
80 | * beyond the users control. So to prevent this, in this implementation | | 80 | * beyond the users control. So to prevent this, in this implementation |
81 | * each node has two identities: its leaf identity and its branch identity. | | 81 | * each node has two identities: its leaf identity and its branch identity. |
82 | * Each is separate from the other. Every branch is tagged as to whether | | 82 | * Each is separate from the other. Every branch is tagged as to whether |
83 | * it points to a leaf or a branch. This is not an attribute of the object | | 83 | * it points to a leaf or a branch. This is not an attribute of the object |
84 | * but of the pointer to the object. The low bit of the pointer is used as | | 84 | * but of the pointer to the object. The low bit of the pointer is used as |
85 | * the tag to determine wether it points to a leaf or branch identity, with | | 85 | * the tag to determine whether it points to a leaf or branch identity, with |
86 | * branch identities having the low bit set. | | 86 | * branch identities having the low bit set. |
87 | * | | 87 | * |
88 | * A node's branch identity has one rule: when traversing the tree from the | | 88 | * A node's branch identity has one rule: when traversing the tree from the |
89 | * root to the node's leaf identity, one of the branches traversed will be via | | 89 | * root to the node's leaf identity, one of the branches traversed will be via |
90 | * the node's branch identity. Of course, that has an exception: since to | | 90 | * the node's branch identity. Of course, that has an exception: since to |
91 | * store N leaves, you need N-1 branches. That one node whose branch identity | | 91 | * store N leaves, you need N-1 branches. That one node whose branch identity |
92 | * isn't used is stored as "oddman"-out in the root. | | 92 | * isn't used is stored as "oddman"-out in the root. |
93 | * | | 93 | * |
94 | * Branching nodes also has a bit offset and a bit length which determines | | 94 | * Branching nodes also has a bit offset and a bit length which determines |
95 | * which branch slot is used. The bit length can be zero resulting in a | | 95 | * which branch slot is used. The bit length can be zero resulting in a |
96 | * one-way branch. This is happens in two special cases: the root and | | 96 | * one-way branch. This is happens in two special cases: the root and |
97 | * interior mask nodes. | | 97 | * interior mask nodes. |
98 | * | | 98 | * |
99 | * To support longest match first lookups, when a mask node (one that only | | 99 | * To support longest match first lookups, when a mask node (one that only |
100 | * match the first N bits) has children who first N bits match the mask nodes, | | 100 | * match the first N bits) has children who first N bits match the mask nodes, |
101 | * that mask node is converted from being a leaf node to being a one-way | | 101 | * that mask node is converted from being a leaf node to being a one-way |
102 | * branch-node. The mask becomes fixed in position in the tree. The mask | | 102 | * branch-node. The mask becomes fixed in position in the tree. The mask |
103 | * will alaways be the longest mask match for its descendants (unless they | | 103 | * will always be the longest mask match for its descendants (unless they |
104 | * traverse an even longer match). | | 104 | * traverse an even longer match). |
105 | */ | | 105 | */ |
106 | | | 106 | |
107 | #define NODETOITEM(pt, ptn) \ | | 107 | #define NODETOITEM(pt, ptn) \ |
108 | ((void *)((uintptr_t)(ptn) - (pt)->pt_node_offset)) | | 108 | ((void *)((uintptr_t)(ptn) - (pt)->pt_node_offset)) |
109 | #define NODETOKEY(pt, ptn) \ | | 109 | #define NODETOKEY(pt, ptn) \ |
110 | ((void *)((uintptr_t)(ptn) - (pt)->pt_node_offset + pt->pt_key_offset)) | | 110 | ((void *)((uintptr_t)(ptn) - (pt)->pt_node_offset + pt->pt_key_offset)) |
111 | #define ITEMTONODE(pt, ptn) \ | | 111 | #define ITEMTONODE(pt, ptn) \ |
112 | ((pt_node_t *)((uintptr_t)(ptn) + (pt)->pt_node_offset)) | | 112 | ((pt_node_t *)((uintptr_t)(ptn) + (pt)->pt_node_offset)) |
113 | | | 113 | |
114 | bool ptree_check(const pt_tree_t *); | | 114 | bool ptree_check(const pt_tree_t *); |
115 | #if PTCHECK > 1 | | 115 | #if PTCHECK > 1 |
116 | #define PTREE_CHECK(pt) ptree_check(pt) | | 116 | #define PTREE_CHECK(pt) ptree_check(pt) |