00001 /* Hash - a simple hash table that provides name/value pairs. 00002 * 00003 * This file is copyright 2002 Jim Kent, but license is hereby 00004 * granted for all use - public, private or commercial. */ 00005 00006 #ifndef HASH_H 00007 #define HASH_H 00008 00009 struct hashEl 00010 /* An element in a hash list. */ 00011 { 00012 struct hashEl *next; 00013 char *name; 00014 void *val; 00015 }; 00016 00017 struct hash 00018 { 00019 struct hash *next; /* Next in list. */ 00020 bits32 mask; /* Mask hashCrc with this to get it to fit table. */ 00021 struct hashEl **table; /* Hash buckets. */ 00022 int powerOfTwoSize; /* Size of table as a power of two. */ 00023 int size; /* Size of table. */ 00024 struct lm *lm; /* Local memory pool. */ 00025 int elCount; /* Count of elements. */ 00026 }; 00027 00028 #define hashMaxSize 24 00029 00030 struct hashCookie 00031 /* used by hashFirst/hashNext in tracking location in traversing hash */ 00032 { 00033 struct hash *hash; /* hash we are associated with */ 00034 int idx; /* current index in hash */ 00035 struct hashEl *nextEl; /* current element in hash */ 00036 }; 00037 00038 bits32 hashString(char *string); 00039 /* Compute a hash value of a string. */ 00040 00041 bits32 hashCrc(char *string); 00042 /* Returns a CRC value on string. */ 00043 00044 struct hashEl *hashLookup(struct hash *hash, char *name); 00045 /* Looks for name in hash table. Returns associated element, 00046 * if found, or NULL if not. */ 00047 00048 struct hashEl *hashLookupUpperCase(struct hash *hash, char *name); 00049 /* Lookup upper cased name in hash. (Assumes all elements of hash 00050 * are themselves already in upper case.) */ 00051 00052 struct hashEl *hashLookupNext(struct hashEl *hashEl); 00053 /* Find the next occurance of name that may occur in the table multiple times, 00054 * or NULL if not found. Use hashLookup to find the first occurence. */ 00055 00056 struct hashEl *hashAdd(struct hash *hash, char *name, void *val); 00057 /* Add new element to hash table. */ 00058 00059 struct hashEl *hashAddN(struct hash *hash, char *name, int nameSize, void *val); 00060 /* Add name of given size to hash (no need to be zero terminated) */ 00061 00062 void *hashRemove(struct hash *hash, char *name); 00063 /* Remove item of the given name from hash table. 00064 * Returns value of removed item, or NULL if not in the table. */ 00065 00066 struct hashEl *hashAddUnique(struct hash *hash, char *name, void *val); 00067 /* Add new element to hash table. Squawk and die if is already in table. */ 00068 00069 struct hashEl *hashAddSaveName(struct hash *hash, char *name, void *val, char **saveName); 00070 /* Add new element to hash table. Save the name of the element, which is now 00071 * allocated in the hash table, to *saveName. A typical usage would be: 00072 * AllocVar(el); 00073 * hashAddSaveName(hash, name, el, &el->name); 00074 */ 00075 00076 struct hashEl *hashStore(struct hash *hash, char *name); 00077 /* If element in hash already return it, otherwise add it 00078 * and return it. */ 00079 00080 char *hashStoreName(struct hash *hash, char *name); 00081 /* Put name into hash table. */ 00082 00083 char *hashMustFindName(struct hash *hash, char *name); 00084 /* Return name as stored in hash table (in hel->name). 00085 * Abort if not found. */ 00086 00087 void *hashMustFindVal(struct hash *hash, char *name); 00088 /* Lookup name in hash and return val. Abort if not found. */ 00089 00090 void *hashFindVal(struct hash *hash, char *name); 00091 /* Look up name in hash and return val or NULL if not found. */ 00092 00093 void *hashOptionalVal(struct hash *hash, char *name, void *usual); 00094 /* Look up name in hash and return val, or usual if not found. */ 00095 00096 struct hashEl *hashAddInt(struct hash *hash, char *name, int val); 00097 /* Store integer value in hash */ 00098 00099 int hashIntVal(struct hash *hash, char *name); 00100 /* Return integer value associated with name in a simple 00101 * hash of ints. */ 00102 00103 int hashIntValDefault(struct hash *hash, char *name, int defaultInt); 00104 /* Return integer value associated with name in a simple 00105 * hash of ints or defaultInt if not found. */ 00106 00107 long long hashIntSum(struct hash *hash); 00108 /* Return sum of all the ints in a hash of ints. */ 00109 00110 void hashTraverseEls(struct hash *hash, void (*func)(struct hashEl *hel)); 00111 /* Apply func to every element of hash with hashEl as parameter. */ 00112 00113 void hashTraverseVals(struct hash *hash, void (*func)(void *val)); 00114 /* Apply func to every element of hash with hashEl->val as parameter. */ 00115 00116 struct hashEl *hashElListHash(struct hash *hash); 00117 /* Return a list of all elements of hash. Free return with hashElFreeList. */ 00118 00119 int hashElCmp(const void *va, const void *vb); 00120 /* Compare two hashEl by name. */ 00121 00122 void *hashElFindVal(struct hashEl *list, char *name); 00123 /* Look up name in hashEl list and return val or NULL if not found. */ 00124 00125 void hashElFree(struct hashEl **pEl); 00126 /* Free hash el list returned from hashListAll. */ 00127 00128 void hashElFreeList(struct hashEl **pList); 00129 /* Free hash el list returned from hashListAll. (Don't use 00130 * this internally. */ 00131 00132 struct hashCookie hashFirst(struct hash *hash); 00133 /* Return an object to use by hashNext() to traverse the hash table. 00134 * The first call to hashNext will return the first entry in the table. */ 00135 00136 struct hashEl* hashNext(struct hashCookie *cookie); 00137 /* Return the next entry in the hash table, or NULL if no more. Do not modify 00138 * hash table while this is being used. (see note in code if you want to fix 00139 * this) */ 00140 00141 void *hashNextVal(struct hashCookie *cookie); 00142 /* Return the next value in the hash table, or NULL if no more. Do not modify 00143 * hash table while this is being used. */ 00144 00145 char *hashNextName(struct hashCookie *cookie); 00146 /* Return the next name in the hash table, or NULL if no more. Do not modify 00147 * hash table while this is being used. */ 00148 00149 struct hash *newHash(int powerOfTwoSize); 00150 /* Returns new hash table. */ 00151 #define hashNew(a) newHash(a) /* Synonym */ 00152 00153 struct hash *hashFromSlNameList(void *list); 00154 /* Create a hash out of a list of slNames or any kind of list where the */ 00155 /* first field is the next pointer and the second is the name. */ 00156 00157 void freeHash(struct hash **pHash); 00158 /* Free up hash table. */ 00159 #define hashFree(a) freeHash(a) /* Synonym */ 00160 00161 void freeHashAndVals(struct hash **pHash); 00162 /* Free up hash table and all values associated with it. 00163 * (Just calls freeMem on each hel->val) */ 00164 00165 void hashFreeWithVals(struct hash **pHash, void (freeFunc)()); 00166 /* Free up hash table and all values associated with it. freeFunc is a 00167 * function to free an entry, should take a pointer to a pointer to an 00168 * entry. */ 00169 00170 void hashFreeList(struct hash **pList); 00171 /* Free up a list of hashes. */ 00172 00173 void hashHisto(struct hash *hash, char *fname); 00174 /* Output bucket usage counts to a file for producing a histogram */ 00175 00176 struct hashEl *hashReplace(struct hash *hash, char *name, void *val); 00177 /* Replace an existing element in hash table, or add it if not present. */ 00178 00179 boolean hashMayRemove(struct hash *hash, char *name); 00180 /* Remove item of the given name from hash table, if present. 00181 * Return true if it was present */ 00182 00183 void hashMustRemove(struct hash *hash, char *name); 00184 /* Remove item of the given name from hash table, or error 00185 * if not present */ 00186 00187 char *hashToRaString(struct hash *hash); 00188 /* Convert hash to string in ra format. */ 00189 00190 #endif /* HASH_H */ 00191
1.5.2