14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin * Glenn Fowler
254887Schin * AT&T Bell Laboratories
264887Schin *
274887Schin * hash table library
284887Schin */
294887Schin
304887Schin #include "hashlib.h"
314887Schin
324887Schin /*
334887Schin * dump HASH_* flags
344887Schin */
354887Schin
364887Schin static void
dumpflags(register int flags)374887Schin dumpflags(register int flags)
384887Schin {
394887Schin if (flags & HASH_ALLOCATE) sfprintf(sfstderr, "allocate ");
404887Schin if (flags & HASH_BUCKET) sfprintf(sfstderr, "bucket ");
414887Schin if (flags & HASH_FIXED) sfprintf(sfstderr, "fixed ");
424887Schin if (flags & HASH_HASHED) sfprintf(sfstderr, "hashed ");
434887Schin if (flags & HASH_RESIZE) sfprintf(sfstderr, "resize ");
444887Schin if (flags & HASH_STATIC) sfprintf(sfstderr, "static ");
454887Schin if (flags & HASH_VALUE) sfprintf(sfstderr, "value ");
464887Schin }
474887Schin
484887Schin /*
494887Schin * dump hash table bucket info
504887Schin */
514887Schin
524887Schin static void
dumpbucket(register Hash_table_t * tab,int flags)534887Schin dumpbucket(register Hash_table_t* tab, int flags)
544887Schin {
554887Schin register Hash_bucket_t** sp;
564887Schin register Hash_bucket_t* b;
574887Schin Hash_bucket_t** sx;
584887Schin int n;
594887Schin unsigned char* s;
604887Schin
614887Schin NoP(flags);
624887Schin sx = tab->table + tab->size;
634887Schin for (sp = tab->table; sp < sx; sp++)
644887Schin {
654887Schin n = 0;
664887Schin for (b = *sp; b; b = b->next)
674887Schin if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value))
684887Schin n++;
694887Schin if (n)
704887Schin {
714887Schin sfprintf(sfstderr, "%5d %2d :", sp - tab->table, n);
724887Schin for (b = *sp; b; b = b->next)
734887Schin if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value))
744887Schin {
754887Schin if (n = tab->root->namesize)
764887Schin {
774887Schin sfprintf(sfstderr, " 0x");
784887Schin s = (unsigned char*)hashname(b);
794887Schin while (n-- > 0)
804887Schin sfprintf(sfstderr, "%02x", *s++);
814887Schin }
824887Schin else sfprintf(sfstderr, " %s", hashname(b));
834887Schin if (b->hash & HASH_FLAGS)
844887Schin {
854887Schin sfprintf(sfstderr, "|");
864887Schin if (b->hash & HASH_HIDES) sfprintf(sfstderr, "hides|");
874887Schin if (b->hash & HASH_HIDDEN) sfprintf(sfstderr, "hidden|");
884887Schin if (b->hash & HASH_KEEP) sfprintf(sfstderr, "keep|");
894887Schin if (b->hash & HASH_OPAQUED) sfprintf(sfstderr, "opaque|");
904887Schin }
914887Schin if (tab->flags & HASH_VALUE) sfprintf(sfstderr, "=0x%08lx", (long)b->value);
924887Schin }
934887Schin sfprintf(sfstderr, "\n");
944887Schin }
954887Schin }
964887Schin sfprintf(sfstderr, "\n");
974887Schin }
984887Schin
994887Schin /*
1004887Schin * dump info on a single table
1014887Schin */
1024887Schin
1034887Schin static void
dumptable(register Hash_table_t * tab,register int flags)1044887Schin dumptable(register Hash_table_t* tab, register int flags)
1054887Schin {
1064887Schin Hash_table_t* scope;
1074887Schin int level;
1084887Schin
1094887Schin sfprintf(sfstderr, " name: %s", tab->name ? tab->name : "*no name*");
1104887Schin if (scope = tab->scope)
1114887Schin {
1124887Schin level = 1;
1134887Schin while (scope = scope->scope) level++;
1144887Schin sfprintf(sfstderr, " level %d scope on 0x%08lx", level, (unsigned long)tab->scope);
1154887Schin }
1164887Schin sfprintf(sfstderr, "\n");
1174887Schin sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)tab);
1184887Schin sfprintf(sfstderr, " flags: ");
1194887Schin if (tab->frozen) sfprintf(sfstderr, "frozen=%d ", tab->frozen);
1204887Schin dumpflags(tab->flags);
1214887Schin sfprintf(sfstderr, "\n");
1224887Schin sfprintf(sfstderr, " size: %d\n", tab->size);
1234887Schin sfprintf(sfstderr, " buckets: %d\n", tab->buckets);
1244887Schin sfprintf(sfstderr, " bucketsize: %d\n", tab->bucketsize * sizeof(char*));
1254887Schin sfprintf(sfstderr, "\n");
1264887Schin if ((flags | tab->flags) & HASH_BUCKET) dumpbucket(tab, flags);
1274887Schin }
1284887Schin
1294887Schin /*
1304887Schin * dump hash table root info
1314887Schin */
1324887Schin
1334887Schin static void
dumproot(register Hash_root_t * root,register int flags)1344887Schin dumproot(register Hash_root_t* root, register int flags)
1354887Schin {
1364887Schin register Hash_table_t* tab;
1374887Schin
1384887Schin sfprintf(sfstderr, " root\n");
1394887Schin sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)root);
1404887Schin sfprintf(sfstderr, " flags: ");
1414887Schin dumpflags(root->flags);
1424887Schin if (root->namesize) sfprintf(sfstderr, "namesize=%d ", root->namesize);
1434887Schin if (root->local->alloc) sfprintf(sfstderr, "alloc=0x%08lx ", (unsigned long)root->local->alloc);
1444887Schin if (root->local->compare) sfprintf(sfstderr, "compare=0x%08lx ", (unsigned long)root->local->compare);
1454887Schin if (root->local->free) sfprintf(sfstderr, "free=0x%08lx ", (unsigned long)root->local->free);
1464887Schin if (root->local->hash) sfprintf(sfstderr, "hash=0x%08lx ", (unsigned long)root->local->hash);
1474887Schin if (root->local->region) sfprintf(sfstderr, "region=0x%08lx handle=0x%08lx ", (unsigned long)root->local->region, (unsigned long)root->local->handle);
1484887Schin sfprintf(sfstderr, "\n");
1494887Schin sfprintf(sfstderr, " meanchain: %d\n", root->meanchain);
1504887Schin sfprintf(sfstderr, " accesses: %d\n", root->accesses);
1514887Schin sfprintf(sfstderr, " collisions: %d\n", root->collisions);
1524887Schin sfprintf(sfstderr, "\n");
1534887Schin for (tab = root->references; tab; tab = tab->next)
1544887Schin dumptable(tab, flags);
1554887Schin }
1564887Schin
1574887Schin /*
1584887Schin * dump hash table accounting info
1594887Schin * if tab is 0 then dump all tables in hash_info.list
1604887Schin * flags are HASH_* flags that specifiy optional dump info
1614887Schin */
1624887Schin
1634887Schin void
hashdump(register Hash_table_t * tab,int flags)1644887Schin hashdump(register Hash_table_t* tab, int flags)
1654887Schin {
1664887Schin register Hash_root_t* root;
1674887Schin
1684887Schin sfprintf(sfstderr, "\nhash table information:\n\n");
1694887Schin if (tab) dumproot(tab->root, flags);
1704887Schin else for (root = hash_info.list; root; root = root->next)
1714887Schin dumproot(root, flags);
1724887Schin sfsync(sfstderr);
1734887Schin }
174