14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1985-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.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 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 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 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 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 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