FreeBSD/sys/kern/subr_pctrie.c
/*
 * Look up the nearest entry at a position less than or equal to index.
 */
Look up the nearest entry at a position less than or equal to index.
Look up the nearest entry at a position less than or equal to index .
uint64_t *
pctrie_lookup_le(struct pctrie *ptree, uint64_t index)
{
	struct pctrie_node *stack[PCTRIE_LIMIT];
	uint64_t inc;
	uint64_t *m;
	struct pctrie_node *child, *node;
#ifdef INVARIANTS
	int loops = 0;
#endif
	int slot, tos;
	node = pctrie_getroot(ptree);
	if (node == NULL)
		return (NULL);
	else if (pctrie_isleaf(node)) {
		m = pctrie_toval(node);
		if (*m <= index)
			return (m);
		else
			return (NULL);
	}
	tos = 0;
	for (;;) {
		if (pctrie_keybarr(node, index)) {
			if (index > node->pn_owner) {
				index = node->pn_owner + PCTRIE_COUNT *
				    PCTRIE_UNITLEVEL(node->pn_clev);
			} else {
ascend:
				KASSERT(++loops < 1000,
				    ("pctrie_lookup_le: too many loops"));
				do {
					if (tos == 0)
						return (NULL);
					node = stack[--tos];
				} while (pctrie_slot(index,
				    node->pn_clev) == 0);
				index = pctrie_trimkey(index,
				    node->pn_clev);
			}
			index--;
			KASSERT(!pctrie_keybarr(node, index),
			    ("pctrie_lookup_le: keybarr failed"));
		}
		slot = pctrie_slot(index, node->pn_clev);
		child = node->pn_child[slot];
		if (pctrie_isleaf(child)) {
			m = pctrie_toval(child);
			if (*m <= index)
				return (m);
		} else if (child != NULL)
			goto descend;
		if (slot > 0) {
			inc = PCTRIE_UNITLEVEL(node->pn_clev);
			index |= inc - 1;
			do {
				index -= inc;
				slot--;
				child = node->pn_child[slot];
				if (pctrie_isleaf(child)) {
					m = pctrie_toval(child);
					if (*m <= index)
						return (m);
				} else if (child != NULL)
					goto descend;
			} while (slot > 0);
		}
		KASSERT(child == NULL || pctrie_isleaf(child),
		    ("pctrie_lookup_le: child is radix node"));
		goto ascend;
descend:
		KASSERT(node->pn_clev > 0,
		    ("pctrie_lookup_le: pushing leaf's parent"));
		KASSERT(tos < PCTRIE_LIMIT,
		    ("pctrie_lookup_le: stack overflow"));
		stack[tos++] = node;
		node = child;
	}
}
uint64_t * pctrie_lookup_le ( struct pctrie * ptree , uint64_t index ) { struct pctrie_node * stack [ PCTRIE_LIMIT ] ; uint64_t inc ; uint64_t * m ; struct pctrie_node * child , * node ; #ifdef INVARIANTS int loops = 0 ; #endif int slot , tos ; node = pctrie_getroot ( ptree ) ; if ( node == NULL ) return ( NULL ) ; else if ( pctrie_isleaf ( node ) ) { m = pctrie_toval ( node ) ; if ( * m <= index ) return ( m ) ; else return ( NULL ) ; } tos = 0 ; for ( ; ; ) { if ( pctrie_keybarr ( node , index ) ) { if ( index > node -> pn_owner ) { index = node -> pn_owner + PCTRIE_COUNT * PCTRIE_UNITLEVEL ( node -> pn_clev ) ; } else { ascend : KASSERT ( ++ loops < 1000 , ( " " ) ) ; do { if ( tos == 0 ) return ( NULL ) ; node = stack [ -- tos ] ; } while ( pctrie_slot ( index , node -> pn_clev ) == 0 ) ; index = pctrie_trimkey ( index , node -> pn_clev ) ; } index -- ; KASSERT ( ! pctrie_keybarr ( node , index ) , ( " " ) ) ; } slot = pctrie_slot ( index , node -> pn_clev ) ; child = node -> pn_child [ slot ] ; if ( pctrie_isleaf ( child ) ) { m = pctrie_toval ( child ) ; if ( * m <= index ) return ( m ) ; } else if ( child != NULL ) goto descend ; if ( slot > 0 ) { inc = PCTRIE_UNITLEVEL ( node -> pn_clev ) ; index |= inc - 1 ; do { index -= inc ; slot -- ; child = node -> pn_child [ slot ] ; if ( pctrie_isleaf ( child ) ) { m = pctrie_toval ( child ) ; if ( * m <= index ) return ( m ) ; } else if ( child != NULL ) goto descend ; } while ( slot > 0 ) ; } KASSERT ( child == NULL || pctrie_isleaf ( child ) , ( " " ) ) ; goto ascend ; descend : KASSERT ( node -> pn_clev > 0 , ( " " ) ) ; KASSERT ( tos < PCTRIE_LIMIT , ( " " ) ) ; stack [ tos ++ ] = node ; node = child ; } }
Look up the nearest entry at a position less than or equal to index.
Look up the nearest entry at a position less than or equal to index .
/*
		 * If the keys differ before the current bisection node,
		 * then the search key might rollback to the earliest
		 * available bisection node or to the largest key
		 * in the current node (if the owner is smaller than the
		 * search key).
		 */ /*
				 * Pop nodes from the stack until either the
				 * stack is empty or a node that could have a
				 * matching descendant is found.
				 */ /*
				 * The following computation cannot overflow
				 * because index's slot at the current level
				 * is greater than 0.
				 */ /*
		 * Look for an available edge or value within the current
		 * bisection node.
		 */ /*
		 * If a value or edge smaller than the search slot is not found
		 * in the current node, ascend to the next higher-level node.
		 */