Module Name: src Committed By: riz Date: Mon Jul 16 22:10:47 UTC 2012
Modified Files: src/common/lib/libc/gen [netbsd-6]: ptree.c src/sys/sys [netbsd-6]: ptree.h Log Message: Pull up following revision(s) (requested by rmind in ticket #420): common/lib/libc/gen/ptree.c: revision 1.7 common/lib/libc/gen/ptree.c: revision 1.8 common/lib/libc/gen/ptree.c: revision 1.9 sys/sys/ptree.h: revision 1.7 Don't bother testing 0 length keys since they can only have one possible value. Add code to protect the ptree from multiple insertions of the same node. ptree_find_filtered_node: make key argument const. To generate a diff of this commit: cvs rdiff -u -r1.5.8.1 -r1.5.8.2 src/common/lib/libc/gen/ptree.c cvs rdiff -u -r1.4.8.1 -r1.4.8.2 src/sys/sys/ptree.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/common/lib/libc/gen/ptree.c diff -u src/common/lib/libc/gen/ptree.c:1.5.8.1 src/common/lib/libc/gen/ptree.c:1.5.8.2 --- src/common/lib/libc/gen/ptree.c:1.5.8.1 Thu Jul 12 18:35:10 2012 +++ src/common/lib/libc/gen/ptree.c Mon Jul 16 22:10:46 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ptree.c,v 1.5.8.1 2012/07/12 18:35:10 riz Exp $ */ +/* $NetBSD: ptree.c,v 1.5.8.2 2012/07/16 22:10:46 riz Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -40,7 +40,7 @@ #include <sys/types.h> #include <sys/systm.h> #include <lib/libkern/libkern.h> -__KERNEL_RCSID(0, "$NetBSD: ptree.c,v 1.5.8.1 2012/07/12 18:35:10 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ptree.c,v 1.5.8.2 2012/07/16 22:10:46 riz Exp $"); #else #include <stddef.h> #include <stdint.h> @@ -53,7 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: ptree.c,v 1. #else #define KASSERT(e) do { } while (/*CONSTCOND*/ 0) #endif -__RCSID("$NetBSD: ptree.c,v 1.5.8.1 2012/07/12 18:35:10 riz Exp $"); +__RCSID("$NetBSD: ptree.c,v 1.5.8.2 2012/07/16 22:10:46 riz Exp $"); #endif /* _KERNEL || _STANDALONE */ #ifdef _LIBC @@ -67,7 +67,7 @@ __RCSID("$NetBSD: ptree.c,v 1.5.8.1 2012 #endif /* - * This is an implementation of a radix / PATRICIA tree. As in a traditional + * This is an implementation of a radix / PATRICIA tree. As in a traditional * patricia tree, all the data is at the leaves of the tree. An N-value * tree would have N leaves, N-1 branching nodes, and a root pointer. Each * branching node would have left(0) and right(1) pointers that either point @@ -76,15 +76,15 @@ __RCSID("$NetBSD: ptree.c,v 1.5.8.1 2012 * have no need for pointers. * * However, allocation for these branching nodes is problematic since the - * allocation could fail. This would cause insertions to fail for reasons - * beyond the users control. So to prevent this, in this implementation + * allocation could fail. This would cause insertions to fail for reasons + * beyond the user's control. So to prevent this, in this implementation * each node has two identities: its leaf identity and its branch identity. * Each is separate from the other. Every branch is tagged as to whether * it points to a leaf or a branch. This is not an attribute of the object * but of the pointer to the object. The low bit of the pointer is used as * the tag to determine whether it points to a leaf or branch identity, with * branch identities having the low bit set. - * + * * A node's branch identity has one rule: when traversing the tree from the * root to the node's leaf identity, one of the branches traversed will be via * the node's branch identity. Of course, that has an exception: since to @@ -93,7 +93,7 @@ __RCSID("$NetBSD: ptree.c,v 1.5.8.1 2012 * * Branching nodes also has a bit offset and a bit length which determines * which branch slot is used. The bit length can be zero resulting in a - * one-way branch. This is happens in two special cases: the root and + * one-way branch. This happens in two special cases: the root and * interior mask nodes. * * To support longest match first lookups, when a mask node (one that only @@ -134,7 +134,7 @@ ptree_testnode(const pt_tree_t *pt, cons { const pt_bitlen_t bitlen = PTN_BRANCH_BITLEN(ptn); if (bitlen == 0) - return PT_SLOT_ROOT; + return PT_SLOT_ROOT; /* mask or root, doesn't matter */ return (*pt->pt_ops->ptto_testnode)(NODETOKEY(pt, target), PTN_BRANCH_BITOFF(ptn), bitlen, pt->pt_context); } @@ -150,6 +150,9 @@ ptree_matchkey(const pt_tree_t *pt, cons static inline pt_slot_t ptree_testkey(const pt_tree_t *pt, const void *key, const pt_node_t *ptn) { + const pt_bitlen_t bitlen = PTN_BRANCH_BITLEN(ptn); + if (bitlen == 0) + return PT_SLOT_ROOT; /* mask or root, doesn't matter */ return (*pt->pt_ops->ptto_testkey)(key, PTN_BRANCH_BITOFF(ptn), PTN_BRANCH_BITLEN(ptn), pt->pt_context); } @@ -456,6 +459,12 @@ ptree_insert_node_common(pt_tree_t *pt, pt_insertdata_t id; /* + * If this node already exists in the tree, return failure. + */ + if (target == PT_NODE(pt->pt_root)) + return false; + + /* * We need a leaf so we can match against. Until we get a leaf * we having nothing to test against. */ @@ -477,6 +486,12 @@ ptree_insert_node_common(pt_tree_t *pt, id.id_node = *id.id_insertp; /* + * If this node already exists in the tree, return failure. + */ + if (target == ptn) + return false; + + /* * If we hit a leaf, try to insert target at leaf. We could * have inlined ptree_insert_leaf here but that would have * made this routine much harder to understand. Trust the @@ -613,7 +628,7 @@ ptree_insert_mask_node(pt_tree_t *pt, vo #endif /* !PTNOMASH */ void * -ptree_find_filtered_node(pt_tree_t *pt, void *key, pt_filter_t filter, +ptree_find_filtered_node(pt_tree_t *pt, const void *key, pt_filter_t filter, void *filter_arg) { #ifndef PTNOMASK Index: src/sys/sys/ptree.h diff -u src/sys/sys/ptree.h:1.4.8.1 src/sys/sys/ptree.h:1.4.8.2 --- src/sys/sys/ptree.h:1.4.8.1 Thu Jul 12 18:35:10 2012 +++ src/sys/sys/ptree.h Mon Jul 16 22:10:47 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ptree.h,v 1.4.8.1 2012/07/12 18:35:10 riz Exp $ */ +/* $NetBSD: ptree.h,v 1.4.8.2 2012/07/16 22:10:47 riz Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -184,7 +184,7 @@ typedef bool (*pt_filter_t)(void *, cons void ptree_init(pt_tree_t *, const pt_tree_ops_t *, void *, size_t, size_t); bool ptree_insert_node(pt_tree_t *, void *); bool ptree_insert_mask_node(pt_tree_t *, void *, pt_bitlen_t); -void * ptree_find_filtered_node(pt_tree_t *, void *, pt_filter_t, void *); +void * ptree_find_filtered_node(pt_tree_t *, const void *, pt_filter_t, void *); #define ptree_find_node(pt,key) \ ptree_find_filtered_node((pt), (key), NULL, NULL) void ptree_remove_node(pt_tree_t *, void *);