diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
commit | 3950ffe2a485479f6561c27364d3d7df5a21d124 (patch) | |
tree | 468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libast/hash/hashdump.c | |
download | ksh-upstream.tar.gz |
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/hash/hashdump.c')
-rw-r--r-- | src/lib/libast/hash/hashdump.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/lib/libast/hash/hashdump.c b/src/lib/libast/hash/hashdump.c new file mode 100644 index 0000000..3c2829a --- /dev/null +++ b/src/lib/libast/hash/hashdump.c @@ -0,0 +1,173 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Bell Laboratories + * + * hash table library + */ + +#include "hashlib.h" + +/* + * dump HASH_* flags + */ + +static void +dumpflags(register int flags) +{ + if (flags & HASH_ALLOCATE) sfprintf(sfstderr, "allocate "); + if (flags & HASH_BUCKET) sfprintf(sfstderr, "bucket "); + if (flags & HASH_FIXED) sfprintf(sfstderr, "fixed "); + if (flags & HASH_HASHED) sfprintf(sfstderr, "hashed "); + if (flags & HASH_RESIZE) sfprintf(sfstderr, "resize "); + if (flags & HASH_STATIC) sfprintf(sfstderr, "static "); + if (flags & HASH_VALUE) sfprintf(sfstderr, "value "); +} + +/* + * dump hash table bucket info + */ + +static void +dumpbucket(register Hash_table_t* tab, int flags) +{ + register Hash_bucket_t** sp; + register Hash_bucket_t* b; + Hash_bucket_t** sx; + int n; + unsigned char* s; + + NoP(flags); + sx = tab->table + tab->size; + for (sp = tab->table; sp < sx; sp++) + { + n = 0; + for (b = *sp; b; b = b->next) + if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value)) + n++; + if (n) + { + sfprintf(sfstderr, "%5d %2d :", sp - tab->table, n); + for (b = *sp; b; b = b->next) + if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value)) + { + if (n = tab->root->namesize) + { + sfprintf(sfstderr, " 0x"); + s = (unsigned char*)hashname(b); + while (n-- > 0) + sfprintf(sfstderr, "%02x", *s++); + } + else sfprintf(sfstderr, " %s", hashname(b)); + if (b->hash & HASH_FLAGS) + { + sfprintf(sfstderr, "|"); + if (b->hash & HASH_HIDES) sfprintf(sfstderr, "hides|"); + if (b->hash & HASH_HIDDEN) sfprintf(sfstderr, "hidden|"); + if (b->hash & HASH_KEEP) sfprintf(sfstderr, "keep|"); + if (b->hash & HASH_OPAQUED) sfprintf(sfstderr, "opaque|"); + } + if (tab->flags & HASH_VALUE) sfprintf(sfstderr, "=0x%08lx", (long)b->value); + } + sfprintf(sfstderr, "\n"); + } + } + sfprintf(sfstderr, "\n"); +} + +/* + * dump info on a single table + */ + +static void +dumptable(register Hash_table_t* tab, register int flags) +{ + Hash_table_t* scope; + int level; + + sfprintf(sfstderr, " name: %s", tab->name ? tab->name : "*no name*"); + if (scope = tab->scope) + { + level = 1; + while (scope = scope->scope) level++; + sfprintf(sfstderr, " level %d scope on 0x%08lx", level, (unsigned long)tab->scope); + } + sfprintf(sfstderr, "\n"); + sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)tab); + sfprintf(sfstderr, " flags: "); + if (tab->frozen) sfprintf(sfstderr, "frozen=%d ", tab->frozen); + dumpflags(tab->flags); + sfprintf(sfstderr, "\n"); + sfprintf(sfstderr, " size: %d\n", tab->size); + sfprintf(sfstderr, " buckets: %d\n", tab->buckets); + sfprintf(sfstderr, " bucketsize: %d\n", tab->bucketsize * sizeof(char*)); + sfprintf(sfstderr, "\n"); + if ((flags | tab->flags) & HASH_BUCKET) dumpbucket(tab, flags); +} + +/* + * dump hash table root info + */ + +static void +dumproot(register Hash_root_t* root, register int flags) +{ + register Hash_table_t* tab; + + sfprintf(sfstderr, " root\n"); + sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)root); + sfprintf(sfstderr, " flags: "); + dumpflags(root->flags); + if (root->namesize) sfprintf(sfstderr, "namesize=%d ", root->namesize); + if (root->local->alloc) sfprintf(sfstderr, "alloc=0x%08lx ", (unsigned long)root->local->alloc); + if (root->local->compare) sfprintf(sfstderr, "compare=0x%08lx ", (unsigned long)root->local->compare); + if (root->local->free) sfprintf(sfstderr, "free=0x%08lx ", (unsigned long)root->local->free); + if (root->local->hash) sfprintf(sfstderr, "hash=0x%08lx ", (unsigned long)root->local->hash); + if (root->local->region) sfprintf(sfstderr, "region=0x%08lx handle=0x%08lx ", (unsigned long)root->local->region, (unsigned long)root->local->handle); + sfprintf(sfstderr, "\n"); + sfprintf(sfstderr, " meanchain: %d\n", root->meanchain); + sfprintf(sfstderr, " accesses: %d\n", root->accesses); + sfprintf(sfstderr, " collisions: %d\n", root->collisions); + sfprintf(sfstderr, "\n"); + for (tab = root->references; tab; tab = tab->next) + dumptable(tab, flags); +} + +/* + * dump hash table accounting info + * if tab is 0 then dump all tables in hash_info.list + * flags are HASH_* flags that specifiy optional dump info + */ + +void +hashdump(register Hash_table_t* tab, int flags) +{ + register Hash_root_t* root; + + sfprintf(sfstderr, "\nhash table information:\n\n"); + if (tab) dumproot(tab->root, flags); + else for (root = hash_info.list; root; root = root->next) + dumproot(root, flags); + sfsync(sfstderr); +} |