1*4882a593Smuzhiyun #ifndef HASHTABLE_H 2*4882a593Smuzhiyun #define HASHTABLE_H 1 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun #include <dix-config.h> 5*4882a593Smuzhiyun #include <X11/Xfuncproto.h> 6*4882a593Smuzhiyun #include <X11/Xdefs.h> 7*4882a593Smuzhiyun #include "list.h" 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun /** @brief A hashing function. 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun @param[in/out] cdata Opaque data that can be passed to HtInit that will 12*4882a593Smuzhiyun eventually end up here 13*4882a593Smuzhiyun @param[in] ptr The data to be hashed. The size of the data, if 14*4882a593Smuzhiyun needed, can be configured via a record that can be 15*4882a593Smuzhiyun passed via cdata. 16*4882a593Smuzhiyun @param[in] numBits The number of bits this hash needs to have in the 17*4882a593Smuzhiyun resulting hash 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun @return A numBits-bit hash of the data 20*4882a593Smuzhiyun */ 21*4882a593Smuzhiyun typedef unsigned (*HashFunc)(void * cdata, const void * ptr, int numBits); 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun /** @brief A comparison function for hashed keys. 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun @param[in/out] cdata Opaque data that ca be passed to Htinit that will 26*4882a593Smuzhiyun eventually end up here 27*4882a593Smuzhiyun @param[in] l The left side data to be compared 28*4882a593Smuzhiyun @param[in] r The right side data to be compared 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun @return -1 if l < r, 0 if l == r, 1 if l > r 31*4882a593Smuzhiyun */ 32*4882a593Smuzhiyun typedef int (*HashCompareFunc)(void * cdata, const void * l, const void * r); 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun struct HashTableRec; 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun typedef struct HashTableRec *HashTable; 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun /** @brief A configuration for HtGenericHash */ 39*4882a593Smuzhiyun typedef struct { 40*4882a593Smuzhiyun int keySize; 41*4882a593Smuzhiyun } HtGenericHashSetupRec, *HtGenericHashSetupPtr; 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun /** @brief ht_create initalizes a hash table for a certain hash table 44*4882a593Smuzhiyun configuration 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun @param[out] ht The hash table structure to initialize 47*4882a593Smuzhiyun @param[in] keySize The key size in bytes 48*4882a593Smuzhiyun @param[in] dataSize The data size in bytes 49*4882a593Smuzhiyun @param[in] hash The hash function to use for hashing keys 50*4882a593Smuzhiyun @param[in] compare The comparison function for hashing keys 51*4882a593Smuzhiyun @param[in] cdata Opaque data that will be passed to hash and 52*4882a593Smuzhiyun comparison functions 53*4882a593Smuzhiyun */ 54*4882a593Smuzhiyun extern _X_EXPORT HashTable ht_create(int keySize, 55*4882a593Smuzhiyun int dataSize, 56*4882a593Smuzhiyun HashFunc hash, 57*4882a593Smuzhiyun HashCompareFunc compare, 58*4882a593Smuzhiyun void *cdata); 59*4882a593Smuzhiyun /** @brief HtDestruct deinitializes the structure. It does not free the 60*4882a593Smuzhiyun memory allocated to HashTableRec 61*4882a593Smuzhiyun */ 62*4882a593Smuzhiyun extern _X_EXPORT void ht_destroy(HashTable ht); 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /** @brief Adds a new key to the hash table. The key will be copied 65*4882a593Smuzhiyun and a pointer to the value will be returned. The data will 66*4882a593Smuzhiyun be initialized with zeroes. 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun @param[in/out] ht The hash table 69*4882a593Smuzhiyun @param[key] key The key. The contents of the key will be copied. 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun @return On error NULL is returned, otherwise a pointer to the data 72*4882a593Smuzhiyun associated with the newly inserted key. 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun @note If dataSize is 0, a pointer to the end of the key may be returned 75*4882a593Smuzhiyun to avoid returning NULL. Obviously the data pointed cannot be 76*4882a593Smuzhiyun modified, as implied by dataSize being 0. 77*4882a593Smuzhiyun */ 78*4882a593Smuzhiyun extern _X_EXPORT void *ht_add(HashTable ht, const void *key); 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun /** @brief Removes a key from the hash table along with its 81*4882a593Smuzhiyun associated data, which will be free'd. 82*4882a593Smuzhiyun */ 83*4882a593Smuzhiyun extern _X_EXPORT void ht_remove(HashTable ht, const void *key); 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun /** @brief Finds the associated data of a key from the hash table. 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun @return If the key cannot be found, the function returns NULL. 88*4882a593Smuzhiyun Otherwise it returns a pointer to the data associated 89*4882a593Smuzhiyun with the key. 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun @note If dataSize == 0, this function may return NULL 92*4882a593Smuzhiyun even if the key has been inserted! If dataSize == NULL, 93*4882a593Smuzhiyun use HtMember instead to determine if a key has been 94*4882a593Smuzhiyun inserted. 95*4882a593Smuzhiyun */ 96*4882a593Smuzhiyun extern _X_EXPORT void *ht_find(HashTable ht, const void *key); 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun /** @brief A generic hash function */ 99*4882a593Smuzhiyun extern _X_EXPORT unsigned ht_generic_hash(void *cdata, 100*4882a593Smuzhiyun const void *ptr, 101*4882a593Smuzhiyun int numBits); 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun /** @brief A generic comparison function. It compares data byte-wise. */ 104*4882a593Smuzhiyun extern _X_EXPORT int ht_generic_compare(void *cdata, 105*4882a593Smuzhiyun const void *l, 106*4882a593Smuzhiyun const void *r); 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun /** @brief A debugging function that dumps the distribution of the 109*4882a593Smuzhiyun hash table: for each bucket, list the number of elements 110*4882a593Smuzhiyun contained within. */ 111*4882a593Smuzhiyun extern _X_EXPORT void ht_dump_distribution(HashTable ht); 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun /** @brief A debugging function that dumps the contents of the hash 114*4882a593Smuzhiyun table: for each bucket, list the elements contained 115*4882a593Smuzhiyun within. */ 116*4882a593Smuzhiyun extern _X_EXPORT void ht_dump_contents(HashTable ht, 117*4882a593Smuzhiyun void (*print_key)(void *opaque, void *key), 118*4882a593Smuzhiyun void (*print_value)(void *opaque, void *value), 119*4882a593Smuzhiyun void* opaque); 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun /** @brief A hashing function to be used for hashing resource IDs when 122*4882a593Smuzhiyun used with HashTables. It makes no use of cdata, so that can 123*4882a593Smuzhiyun be NULL. It uses HashXID underneath, and should HashXID be 124*4882a593Smuzhiyun unable to hash the value, it switches into using the generic 125*4882a593Smuzhiyun hash function. */ 126*4882a593Smuzhiyun extern _X_EXPORT unsigned ht_resourceid_hash(void *cdata, 127*4882a593Smuzhiyun const void * data, 128*4882a593Smuzhiyun int numBits); 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun /** @brief A comparison function to be used for comparing resource 131*4882a593Smuzhiyun IDs when used with HashTables. It makes no use of cdata, 132*4882a593Smuzhiyun so that can be NULL. */ 133*4882a593Smuzhiyun extern _X_EXPORT int ht_resourceid_compare(void *cdata, 134*4882a593Smuzhiyun const void *a, 135*4882a593Smuzhiyun const void *b); 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun #endif // HASHTABLE_H 138