mirror of
https://github.com/opnsense/src.git
synced 2026-06-04 22:32:43 -04:00
radix_trie: eliminate iteration in keydiff
Use flsll(), instead of a loop, to find where two keys differ, and then arithmetic to transform that to a trie level. Approved by: alc, markj Differential Revision: https://reviews.freebsd.org/D40585
This commit is contained in:
parent
afb001df81
commit
05963ea4d1
2 changed files with 16 additions and 12 deletions
|
|
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/pctrie.h>
|
||||
#include <sys/proc.h> /* smr.h depends on struct thread. */
|
||||
#include <sys/smr.h>
|
||||
|
|
@ -259,21 +260,22 @@ pctrie_addval(struct pctrie_node *node, uint64_t index, uint16_t clev,
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns the slot where two keys differ.
|
||||
* Returns the level where two keys differ.
|
||||
* It cannot accept 2 equal keys.
|
||||
*/
|
||||
static __inline uint16_t
|
||||
pctrie_keydiff(uint64_t index1, uint64_t index2)
|
||||
{
|
||||
uint16_t clev;
|
||||
|
||||
KASSERT(index1 != index2, ("%s: passing the same key value %jx",
|
||||
__func__, (uintmax_t)index1));
|
||||
CTASSERT(sizeof(long long) >= sizeof(uint64_t));
|
||||
|
||||
index1 ^= index2;
|
||||
for (clev = PCTRIE_LIMIT;; clev--)
|
||||
if (pctrie_slot(index1, clev) != 0)
|
||||
return (clev);
|
||||
/*
|
||||
* From the highest-order bit where the indexes differ,
|
||||
* compute the highest level in the trie where they differ.
|
||||
*/
|
||||
return ((flsll(index1 ^ index2) - 1) / PCTRIE_WIDTH);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/smr.h>
|
||||
|
|
@ -285,21 +286,22 @@ vm_radix_addpage(struct vm_radix_node *rnode, vm_pindex_t index, uint16_t clev,
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns the slot where two keys differ.
|
||||
* Returns the level where two keys differ.
|
||||
* It cannot accept 2 equal keys.
|
||||
*/
|
||||
static __inline uint16_t
|
||||
vm_radix_keydiff(vm_pindex_t index1, vm_pindex_t index2)
|
||||
{
|
||||
uint16_t clev;
|
||||
|
||||
KASSERT(index1 != index2, ("%s: passing the same key value %jx",
|
||||
__func__, (uintmax_t)index1));
|
||||
CTASSERT(sizeof(long long) >= sizeof(vm_pindex_t));
|
||||
|
||||
index1 ^= index2;
|
||||
for (clev = VM_RADIX_LIMIT;; clev--)
|
||||
if (vm_radix_slot(index1, clev) != 0)
|
||||
return (clev);
|
||||
/*
|
||||
* From the highest-order bit where the indexes differ,
|
||||
* compute the highest level in the trie where they differ.
|
||||
*/
|
||||
return ((flsll(index1 ^ index2) - 1) / VM_RADIX_WIDTH);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue