da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Bell Laboratories
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * hash table library
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "hashlib.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * dump HASH_* flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindumpflags(register int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & HASH_ALLOCATE) sfprintf(sfstderr, "allocate ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & HASH_BUCKET) sfprintf(sfstderr, "bucket ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & HASH_FIXED) sfprintf(sfstderr, "fixed ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & HASH_HASHED) sfprintf(sfstderr, "hashed ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & HASH_RESIZE) sfprintf(sfstderr, "resize ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & HASH_STATIC) sfprintf(sfstderr, "static ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & HASH_VALUE) sfprintf(sfstderr, "value ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * dump hash table bucket info
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindumpbucket(register Hash_table_t* tab, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Hash_bucket_t** sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Hash_bucket_t* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Hash_bucket_t** sx;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NoP(flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sx = tab->table + tab->size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (sp = tab->table; sp < sx; sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (b = *sp; b; b = b->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "%5d %2d :", sp - tab->table, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (b = *sp; b; b = b->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n = tab->root->namesize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " 0x");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (unsigned char*)hashname(b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (n-- > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "%02x", *s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else sfprintf(sfstderr, " %s", hashname(b));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b->hash & HASH_FLAGS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "|");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b->hash & HASH_HIDES) sfprintf(sfstderr, "hides|");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b->hash & HASH_HIDDEN) sfprintf(sfstderr, "hidden|");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b->hash & HASH_KEEP) sfprintf(sfstderr, "keep|");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b->hash & HASH_OPAQUED) sfprintf(sfstderr, "opaque|");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tab->flags & HASH_VALUE) sfprintf(sfstderr, "=0x%08lx", (long)b->value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * dump info on a single table
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindumptable(register Hash_table_t* tab, register int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Hash_table_t* scope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int level;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " name: %s", tab->name ? tab->name : "*no name*");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (scope = tab->scope)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (scope = scope->scope) level++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " level %d scope on 0x%08lx", level, (unsigned long)tab->scope);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)tab);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " flags: ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tab->frozen) sfprintf(sfstderr, "frozen=%d ", tab->frozen);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dumpflags(tab->flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " size: %d\n", tab->size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " buckets: %d\n", tab->buckets);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " bucketsize: %d\n", tab->bucketsize * sizeof(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((flags | tab->flags) & HASH_BUCKET) dumpbucket(tab, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * dump hash table root info
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindumproot(register Hash_root_t* root, register int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Hash_table_t* tab;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " root\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)root);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " flags: ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dumpflags(root->flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->namesize) sfprintf(sfstderr, "namesize=%d ", root->namesize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->local->alloc) sfprintf(sfstderr, "alloc=0x%08lx ", (unsigned long)root->local->alloc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->local->compare) sfprintf(sfstderr, "compare=0x%08lx ", (unsigned long)root->local->compare);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->local->free) sfprintf(sfstderr, "free=0x%08lx ", (unsigned long)root->local->free);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->local->hash) sfprintf(sfstderr, "hash=0x%08lx ", (unsigned long)root->local->hash);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->local->region) sfprintf(sfstderr, "region=0x%08lx handle=0x%08lx ", (unsigned long)root->local->region, (unsigned long)root->local->handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " meanchain: %d\n", root->meanchain);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " accesses: %d\n", root->accesses);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " collisions: %d\n", root->collisions);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (tab = root->references; tab; tab = tab->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dumptable(tab, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * dump hash table accounting info
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if tab is 0 then dump all tables in hash_info.list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * flags are HASH_* flags that specifiy optional dump info
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinhashdump(register Hash_table_t* tab, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Hash_root_t* root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\nhash table information:\n\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tab) dumproot(tab->root, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else for (root = hash_info.list; root; root = root->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dumproot(root, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(sfstderr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}