bed8e79f1742da6358f6239946fec3d2efde788d markd Sun Mar 6 22:45:46 2011 -0800 added method to print out stats for hash usage diff --git src/lib/hash.c src/lib/hash.c index 10323cb..0cd90b8 100644 --- src/lib/hash.c +++ src/lib/hash.c @@ -393,30 +393,31 @@ { next = hel->next; int hashVal = hel->hashVal & hash->mask; hel->next = hash->table[hashVal]; hash->table[hashVal] = hel; } } /* restore original list order */ for (i=0; i<hash->size; ++i) { struct hashEl *hel = hash->table[i]; if (hel != NULL && hel->next != NULL) slReverse(&hash->table[i]); } freeMem(oldTable); +hash->numResizes++; } struct hash *hashFromSlNameList(void *list) /* Create a hash out of a list of slNames or any kind of list where the */ /* first field is the next pointer and the second is the name. */ { struct hash *hash = NULL; struct slName *namedList = list, *item; if (!list) return NULL; hash = newHash(0); for (item = namedList; item != NULL; item = item->next) hashAdd(hash, item->name, item); return hash; @@ -637,30 +638,52 @@ nel++; return nel; } void hashHisto(struct hash *hash, char *fname) /* Output bucket usage counts to a file for producing a histogram */ { FILE* fh = mustOpen(fname, "w"); int i; for (i=0; i<hash->size; ++i) fprintf(fh, "%d\n", bucketLen(hash->table[i])); carefulClose(&fh); } +void hashPrintStats(struct hash *hash, char *label, FILE *fh) +/* print statistic about a hash table */ +{ +// count up usage +int i, occupiedCnt = 0, maxBucket = 0; +for (i=0; i<hash->size; ++i) + { + if (hash->table[i] != NULL) + occupiedCnt++; + int sz = bucketLen(hash->table[i]); + maxBucket = max(maxBucket, sz); + } + +fprintf(fh, "hashTable\t%s\n", label); +fprintf(fh, "tableSize\t%d\t%d\n", hash->size, hash->powerOfTwoSize); +fprintf(fh, "numElements\t%d\n", hash->elCount); +fprintf(fh, "occupied\t%d\t%0.4f\n", occupiedCnt, ((hash->size == 0) ? 0.0 : ((float)occupiedCnt)/hash->size)); +fprintf(fh, "maxBucket\t%d\n", maxBucket); +fprintf(fh, "numResizes\t%d\n", hash->numResizes); +fprintf(fh, "\n"); +} + struct hashEl *hashReplace(struct hash *hash, char *name, void *val) /* Replace an existing element in hash table, or add it if not present. */ { if (hashLookup(hash, name)) hashRemove(hash, name); return hashAdd(hash, name, val); } char *hashToRaString(struct hash *hash) /* Convert hash to string in ra format. */ { struct hashEl *el, *list = hashElListHash(hash); struct dyString *dy = dyStringNew(0); slSort(&list, hashElCmp); for (el = list; el != NULL; el = el->next)