freebsd-nq/include
Ed Schouten 459d04a5ee Let tsearch()/tdelete() use an AVL tree.
The existing implementations of POSIX tsearch() and tdelete() don't
attempt to perform any balancing at all. Testing reveals that inserting
100k nodes into a tree sequentially takes approximately one minute on my
system.

Though most other BSDs also don't use any balanced tree internally, C
libraries like glibc and musl do provide better implementations. glibc
uses a red-black tree and musl uses an AVL tree.

Red-black trees have the advantage over AVL trees that they only require
O(1) rotations after insertion and deletion, but have the disadvantage
that the tree has a maximum depth of 2*log2(n) instead of 1.44*log2(n).
My take is that it's better to focus on having a lower maximum depth,
for the reason that in the case of tsearch() the invocation of the
comparator likely dominates the running time.

This change replaces the tsearch() and tdelete() functions by versions
that create an AVL tree. Compared to musl's implementation, this version
is different in two different ways:

- We don't keep track of heights; just balances. This is sufficient.
  This has the advantage that it reduces the number of nodes that are
  being accessed. Storing heights requires us to also access all of the
  siblings along the path.

- Don't use any recursion at all. We know that the tree cannot 2^64
  elements in size, so the height of the tree can never be larger than
  96. Use a 128-bit bitmask to keep track of the path that is computed.
  This allows us to iterate over the same path twice, meaning we can
  apply rotations from top to bottom.

Inserting 100k nodes into a tree now only takes 0.015 seconds. Insertion
seems to be twice as fast as glibc, whereas deletion has about the same
performance. Unlike glibc, it uses a fixed amount of memory.

I also experimented with both recursive and iterative bottom-up
implementations of the same algorithm. This iterative top-down version
performs similar to the recursive bottom-up version in terms of speed
and code size.

For some reason, the iterative bottom-up algorithm was actually 30%
faster for deletion, but has a quadratic memory complexity to keep track
of all the parent pointers.

Reviewed by:	jilles
Obtained from:	https://github.com/NuxiNL/cloudlibc
Differential Revision:	https://reviews.freebsd.org/D4412
2015-12-22 18:12:11 +00:00
..
arpa Add META_MODE support. 2015-06-13 19:20:56 +00:00
gssapi Add META_MODE support. 2015-06-13 19:20:56 +00:00
protocols Add META_MODE support. 2015-06-13 19:20:56 +00:00
rpc Add META_MODE support. 2015-06-13 19:20:56 +00:00
rpcsvc Add META_MODE support. 2015-06-13 19:20:56 +00:00
xlocale Commit log from Dragonfly: 2015-10-13 20:43:49 +00:00
_ctype.h Commit log from Dragonfly: 2015-10-13 20:43:49 +00:00
a.out.h
ar.h
assert.h Don't define static_assert for C++. 2011-12-29 14:41:17 +00:00
bitstring.h
complex.h I'm happy to finally commit stephen@'s implementations of cacos, 2013-05-30 04:49:26 +00:00
cpio.h
ctype.h Commit log from Dragonfly: 2015-10-13 20:43:49 +00:00
db.h
dirent.h Fix some edge cases with rewinddir(): 2014-07-11 16:16:26 +00:00
dlfcn.h Implement fdlopen(3), an rtld interface to load shared object by file 2012-01-07 10:33:01 +00:00
elf-hints.h
elf.h
err.h
fmtmsg.h Fix a small typo. Fireware -> firmware. 2012-06-05 19:42:57 +00:00
fnmatch.h
fstab.h
fts.h Allow certain headers to be included more easily. 2013-05-21 21:20:10 +00:00
ftw.h
getopt.h
glob.h - Add restrict keyword to glob(3) 2011-12-20 22:56:13 +00:00
grp.h include: Remove checks for __BSD_VISIBLE where redundant with __XSI_VISIBLE 2014-05-11 13:48:21 +00:00
gssapi.h
hesiod.h We don't use these files. 2014-08-09 20:03:40 +00:00
iconv.h Remove the const qualifier from iconv(3) to comply with POSIX: 2015-04-15 09:09:20 +00:00
ieeefp.h People porting FreeBSD to new architectures ought not have to 2011-10-21 06:41:46 +00:00
ifaddrs.h Allow certain headers to be included more easily. 2013-05-21 21:20:10 +00:00
inttypes.h Rename __wchar_t so it no longer conflicts with __wchar_t from clang 3.4 2014-04-01 14:46:11 +00:00
iso646.h
kenv.h
langinfo.h langinfo.h: Hide YESSTR and NOSTR in strict POSIX mode. 2014-04-19 12:38:01 +00:00
libgen.h
limits.h Merge from HEAD 2015-08-09 00:15:17 +00:00
link.h
locale.h Reapply 227753 (xlocale cleanup), plus some fixes so that it passes build 2012-03-04 15:31:13 +00:00
Makefile Move obscure lib/ installation of /usr/lib/include symlink to include/. 2015-12-04 03:18:02 +00:00
Makefile.depend new depends 2015-06-16 23:37:19 +00:00
malloc_np.h Use bool rather than _Bool for C++ compatibility. 2015-08-19 18:32:12 +00:00
malloc.h
memory.h
mk-osreldate.sh Stop building vers.c in include/ and only build the needed osreldate.h. 2015-11-25 19:10:59 +00:00
monetary.h Correctly expose xlocale functions if people include the headers in the wrong 2012-03-28 12:11:54 +00:00
mpool.h
mqueue.h POSIX requires sigevent to be visible after mqueue.h is included. 2012-09-10 05:12:45 +00:00
ndbm.h
netconfig.h
netdb.h addrinfo.ai_family is an address family, not a protocol family. 2015-12-20 15:18:50 +00:00
nl_types.h
nlist.h
nss.h
nsswitch.h
paths.h Assume that the -f argument is /dev/gpioc0 if it is not passed. 2013-09-17 11:48:47 +00:00
printf.h The register_printf_render_std() function expects regular string. 2012-07-04 17:35:07 +00:00
proc_service.h
pthread_np.h
pthread.h Make use of gcc attributes in some standard include headers. 2015-04-06 01:39:16 +00:00
pwd.h Replace our version of the pwcache(3) API with NetBSD's implementation. 2012-10-19 12:44:22 +00:00
ranlib.h
readpassphrase.h
regex.h Replace __const by const in all non-contributed source code. 2011-12-13 13:32:56 +00:00
res_update.h Update our stub resolver to final version of libbind. 2014-08-12 12:36:06 +00:00
resolv.h resolver: preserve binary compatibility; reduce header pollution 2015-12-14 17:21:06 +00:00
runetype.h After r232498, programs built with -ansi or -std=c89 including <ctype.h> 2012-03-06 20:15:23 +00:00
search.h Let tsearch()/tdelete() use an AVL tree. 2015-12-22 18:12:11 +00:00
semaphore.h Ensure #include <semaphore.h> is sufficient for using SEM_VALUE_MAX. 2015-01-31 16:39:26 +00:00
setjmp.h include: Remove checks for __BSD_VISIBLE where redundant with __XSI_VISIBLE 2014-05-11 13:48:21 +00:00
signal.h Make use of gcc attributes in some standard include headers. 2015-04-06 01:39:16 +00:00
spawn.h
stab.h
stdalign.h Add <stdalign.h> and <stdnoreturn.h>. 2011-12-25 20:51:40 +00:00
stdbool.h Remove unneeded guard. 2011-12-25 20:15:41 +00:00
stddef.h Add guards to ptrdiff_t definition in include/stddef.h 2014-08-21 15:10:10 +00:00
stdio.h Add _flags2 per jhb@ suggestion since no room left in _flags. 2015-10-28 14:40:02 +00:00
stdlib.h Make use of GCC alloc_align attribute 2015-05-15 20:43:37 +00:00
stdnoreturn.h Simply disallow <stdnoreturn.h> to be used in combination with C++. 2012-01-03 23:05:23 +00:00
string.h include: Remove checks for __BSD_VISIBLE where redundant with __XSI_VISIBLE 2014-05-11 13:48:21 +00:00
stringlist.h Remove clause 3 and 4 from the license 2015-05-21 08:38:25 +00:00
strings.h Add explicit_bzero(3) and its kernel counterpart. 2014-10-07 04:54:11 +00:00
sysexits.h
tar.h
termios.h include: Remove checks for __BSD_VISIBLE where redundant with __XSI_VISIBLE 2014-05-11 13:48:21 +00:00
tgmath.h Roll back r271012 even more aggressively. 2014-09-05 05:36:32 +00:00
time.h Add CLOCK_PROCESS_CPUTIME_ID to <time.h>, to synchronize the CLOCK_* 2013-01-14 18:01:19 +00:00
timeconv.h
timers.h
ttyent.h Add a new flag to /etc/ttys: onifconsole. This is equivalent to "on" if the 2014-01-20 18:15:06 +00:00
uchar.h Fix <uchar.h> in for C++11. 2013-05-25 16:58:12 +00:00
ulimit.h
unistd.h Rename __sentinel to __null_sentinel 2015-11-05 14:55:58 +00:00
unwind.h
utime.h
utmpx.h
uuid.h
varargs.h
wchar.h include: Remove checks for __BSD_VISIBLE where redundant with __XSI_VISIBLE 2014-05-11 13:48:21 +00:00
wctype.h Commit log from Dragonfly: 2015-10-13 20:43:49 +00:00
wordexp.h
xlocale.h Reapply 227753 (xlocale cleanup), plus some fixes so that it passes build 2012-03-04 15:31:13 +00:00