/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1985-2008 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.opensource.org/licenses/cpl1.0.txt * * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * David Korn * * Phong Vo * * * ***********************************************************************/ #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); }