csomh / source-git / rpm

Forked from source-git/rpm 4 years ago
Clone
2ff057
/**
2ff057
 * \file lib/rpmhash.h
2ff057
 * Hash table implemenation.
2ff057
 */
2ff057
2ff057
#include <string.h>
2ff057
// Hackery to make sure that macros get expanded
2ff057
#define __JOIN(a,b) a##b
2ff057
#define JOIN(a,b) __JOIN(a,b)
2ff057
#define HASHPREFIX(name) JOIN(HASHTYPE,name)
2ff057
#define HASHSTRUCT JOIN(HASHTYPE,_s)
2ff057
2ff057
typedef struct HASHSTRUCT * HASHTYPE;
2ff057
2ff057
/* function pointer types to deal with the datatypes the hash works with */
2ff057
2ff057
#define hashFunctionType JOIN(HASHTYPE,HashFunctionType)
2ff057
#define hashEqualityType JOIN(HASHTYPE,HashEqualityType)
2ff057
#define hashFreeKey JOIN(HASHTYPE,FreeKey)
2ff057
2ff057
typedef unsigned int (*hashFunctionType) (HTKEYTYPE string);
2ff057
typedef int (*hashEqualityType) (HTKEYTYPE key1, HTKEYTYPE key2);
2ff057
typedef HTKEYTYPE (*hashFreeKey) (HTKEYTYPE);
2ff057
2ff057
#ifdef HTDATATYPE
2ff057
#define hashFreeData JOIN(HASHTYPE,FreeData)
2ff057
typedef HTDATATYPE (*hashFreeData) (HTDATATYPE);
2ff057
#endif
2ff057
2ff057
/**
2ff057
 * Create hash table.
2ff057
 * If keySize > 0, the key is duplicated within the table (which costs
2ff057
 * memory, but may be useful anyway.
2ff057
 * @param numBuckets    number of hash buckets
2ff057
 * @param fn            function to generate hash value for key
2ff057
 * @param eq            function to compare hash keys for equality
2ff057
 * @param freeKey       function to free the keys or NULL
2ff057
 * @param freeData      function to free the data or NULL
2ff057
 * @return		pointer to initialized hash table
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
HASHTYPE  HASHPREFIX(Create)(int numBuckets,
2ff057
			     hashFunctionType fn, hashEqualityType eq,
2ff057
			     hashFreeKey freeKey
2ff057
#ifdef HTDATATYPE
2ff057
, hashFreeData freeData
2ff057
#endif
2ff057
);
2ff057
2ff057
/**
2ff057
 * Destroy hash table.
2ff057
 * @param ht            pointer to hash table
2ff057
 * @return		NULL always
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
HASHTYPE  HASHPREFIX(Free)( HASHTYPE ht);
2ff057
2ff057
/**
2ff057
 * Remove all entries from the hash table.
2ff057
 * @param ht            pointer to hash table
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
void HASHPREFIX(Empty)(HASHTYPE ht);
2ff057
2ff057
/**
2ff057
 * Calculate hash for key.
2ff057
 * @param @ht		pointer to hash table
2ff057
 * @param @key		key
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
unsigned int HASHPREFIX(KeyHash)(HASHTYPE ht, HTKEYTYPE key);
2ff057
2ff057
/**
2ff057
 * Add item to hash table.
2ff057
 * @param ht            pointer to hash table
2ff057
 * @param key           key
2ff057
 * @param data          data value
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
void  HASHPREFIX(AddEntry)(HASHTYPE ht, HTKEYTYPE key
2ff057
#ifdef HTDATATYPE
2ff057
, HTDATATYPE data
2ff057
#endif
2ff057
);
2ff057
2ff057
/* Add item to hash table with precalculated key hash. */
2ff057
RPM_GNUC_INTERNAL
2ff057
void  HASHPREFIX(AddHEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash
2ff057
#ifdef HTDATATYPE
2ff057
, HTDATATYPE data
2ff057
#endif
2ff057
);
2ff057
2ff057
/**
2ff057
 * Retrieve item from hash table.
2ff057
 * @param ht            pointer to hash table
2ff057
 * @param key           key value
2ff057
 * @retval data         address to store data value from bucket
2ff057
 * @retval dataCount    address to store data value size from bucket
2ff057
 * @retval tableKey     address to store key value from bucket (may be NULL)
2ff057
 * @return		1 on success, 0 if the item is not found.
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
int  HASHPREFIX(GetEntry)(HASHTYPE ht, HTKEYTYPE key,
2ff057
#ifdef HTDATATYPE
2ff057
		HTDATATYPE** data,
2ff057
		int * dataCount,
2ff057
#endif
2ff057
		HTKEYTYPE* tableKey);
2ff057
2ff057
/* Retrieve item from hash table with precalculated key hash. */
2ff057
RPM_GNUC_INTERNAL
2ff057
int  HASHPREFIX(GetHEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash,
2ff057
#ifdef HTDATATYPE
2ff057
		HTDATATYPE** data,
2ff057
		int * dataCount,
2ff057
#endif
2ff057
		HTKEYTYPE* tableKey);
2ff057
2ff057
/**
2ff057
 * Check for key in hash table.
2ff057
 * @param ht            pointer to hash table
2ff057
 * @param key           key value
2ff057
 * @return		1 if the key is present, 0 otherwise
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
int  HASHPREFIX(HasEntry)(HASHTYPE ht, HTKEYTYPE key);
2ff057
2ff057
/* Check for key in hash table with precalculated key hash. */
2ff057
RPM_GNUC_INTERNAL
2ff057
int  HASHPREFIX(HasHEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash);
2ff057
2ff057
/**
2ff057
 * How many buckets are currently allocated (result is implementation 
2ff057
 * dependent)
2ff057
 * @param ht            pointer to hash table
2ff057
 * @result		number of buckets allocated
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
unsigned int HASHPREFIX(NumBuckets)(HASHTYPE ht);
2ff057
2ff057
/**
2ff057
 * How many buckets are used (result is implementation dependent)
2ff057
 * @param ht            pointer to hash table
2ff057
 * @result		number of buckets used
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
unsigned int HASHPREFIX(UsedBuckets)(HASHTYPE ht);
2ff057
2ff057
/**
2ff057
 * How many (unique) keys have been added to the hash table
2ff057
 * @param ht            pointer to hash table
2ff057
 * @result		number of unique keys
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
unsigned int HASHPREFIX(NumKeys)(HASHTYPE ht);
2ff057
2ff057
#ifdef HTDATATYPE
2ff057
/**
2ff057
 * How many data entries have been added to the hash table
2ff057
 * @param ht            pointer to hash table
2ff057
 * @result		number of data entries
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
unsigned int HASHPREFIX(NumData)(HASHTYPE ht);
2ff057
#endif
2ff057
2ff057
/**
2ff057
 * Print statistics about the hash to stderr
2ff057
 * This is for debugging only
2ff057
 * @param ht            pointer to hash table
2ff057
 */
2ff057
RPM_GNUC_INTERNAL
2ff057
void HASHPREFIX(PrintStats)(HASHTYPE ht);