📄 hash.c
字号:
}
/* Try to allocate a new element in the hash */
if (raAdd(hash->elements, (RAElement*)&newElem) < 0)
{
/* Not found... */
return NULL;
}
/* Calculate the key's hash value */
keyValue = hash->hash(key, (int)(hash->userKeySize), (int)(hash->numKeys)) % hash->numKeys;
/* Update new element's information (this is the first in the list) */
newElem->prev = NULL;
newElem->entryNum = keyValue;
newElem->next = (hashListElement *)hash->keys[keyValue];
/* Fix the next one in list if there is one */
if (newElem->next != NULL) newElem->next->prev = newElem;
/* Fill in with the element */
memcpy((char*)newElem + sizeof(hashListElement), key, hash->userKeySize);
memcpy((char*)newElem + sizeof(hashListElement) + hash->alignedKeySize, userElem, hash->userElemSize);
hash->keys[keyValue] = (RAElement)newElem;
return newElem;
}
/************************************************************************
* hashFind
* purpose: Find the location of an element by its key
* input : hHash - HASH object handle
* key - Pointer to the key
* output : none
* return : Pointer to the element's location in the hash table on success
* NULL on failure or if the element wasn't found
************************************************************************/
void*
hashFind(
IN HHASH hHash,
IN void* key)
{
hashStruct* hash = (hashStruct *)hHash;
RvUint32 keyValue;
hashListElement* hashElem;
if (hHash == NULL) return NULL;
/* Calculate the key's hash value */
keyValue = hash->hash(key, (int)(hash->userKeySize), (int)(hash->numKeys)) % hash->numKeys;
/* See if there are any elements in this key value at all */
if (hash->keys[keyValue] == NULL)
return NULL;
/* Start looking for the element */
hashElem = (hashListElement *)hash->keys[keyValue];
/* Search for this element */
while (hashElem != NULL)
{
if (hash->compare(key, (char*)hashElem + sizeof(hashListElement), hash->userKeySize))
{
/* Found! */
return hashElem;
}
hashElem = hashElem->next;
}
/* No such element was found */
return NULL;
}
/************************************************************************
* hashFindNext
* purpose: Find the location of the next element with the same key
* input : hHash - HASH object handle
* key - Pointer to the key
* location - Location given in the last call to hashFindNext()
* or hashFind().
* output : none
* return : Pointer to the element's location in the hash table on success
* NULL on failure or if the element wasn't found
************************************************************************/
void*
hashFindNext(
IN HHASH hHash,
IN void* key,
IN void* location)
{
hashStruct* hash = (hashStruct *)hHash;
hashListElement* hashElem;
if (location == NULL) return NULL;
/* Start looking for the element */
hashElem = (hashListElement *)location;
/* First we skip the one we already know is ok */
hashElem = hashElem->next;
/* Search for this element */
while (hashElem != NULL)
{
if (hash->compare(key, (char*)hashElem + sizeof(hashListElement), hash->userKeySize))
{
/* Found! */
return hashElem;
}
hashElem = hashElem->next;
}
/* No such element was found */
return NULL;
}
/************************************************************************
* hashGetElement
* purpose: Get the element's data by its location (given by hashFind()).
* input : hHash - HASH object handle
* location - Pointer to the element in hash
* (given by hashAdd)
* output : none
* return : Pointer to the element's date in the hash table on success
* NULL on failure or if the element wasn't found
************************************************************************/
void*
hashGetElement(
IN HHASH hHash,
IN void* location)
{
hashStruct* hash = (hashStruct *)hHash;
if (location == NULL) return NULL;
return ((char*)location + sizeof(hashListElement) + hash->alignedKeySize);
}
/************************************************************************
* hashSetElement
* purpose: Set the element's data by its location (given by hashFind()).
* input : hHash - HASH object handle
* location - Pointer to the element in hash
* (given by hashAdd)
* output : none
* return : Non negative value on success
* Negative value on failure
************************************************************************/
int
hashSetElement(
IN HHASH hHash,
IN void* location,
IN void* userElem)
{
hashStruct* hash = (hashStruct *)hHash;
if (hash == NULL) return RV_ERROR_UNKNOWN;
memcpy((char*)location + sizeof(hashListElement) + hash->alignedKeySize, userElem, hash->userElemSize);
return 0;
}
/************************************************************************
* hashGetKey
* purpose: Get the element's key by its location (given by hashFind()).
* input : hHash - HASH object handle
* location - Pointer to the element in hash
* (given by hashAdd)
* output : none
* return : Pointer to the element's key in the hash table on success
* NULL on failure or if the element wasn't found
************************************************************************/
void*
hashGetKey(
IN HHASH hHash,
IN void* location)
{
RV_UNUSED_ARG(hHash);
if (location == NULL) return NULL;
return ((char*)location + sizeof(hashListElement));
}
/************************************************************************
* hashDelete
* purpose: Delete an element from the HASH
* input : hHash - HASH object handle
* location - Pointer to the element in hash
* (given by hashAdd)
* output : none
* return : Non negative value on success
* Negative value on failure
************************************************************************/
int
hashDelete(
IN HHASH hHash,
IN void* location)
{
hashStruct* hash = (hashStruct *)hHash;
hashListElement* userElem;
if (hash == NULL) return RV_ERROR_UNKNOWN;
userElem = (hashListElement *)location;
/* Remove linkages to this element, making sure to update the key if
we have to */
if (userElem->prev == NULL)
{
/* First element - update keys table */
hash->keys[userElem->entryNum] = (RAElement)userElem->next;
}
else
userElem->prev->next = userElem->next;
if (userElem->next != NULL)
userElem->next->prev = userElem->prev;
/* Remove this element from RA */
return raDelete(hash->elements, (RAElement)userElem);
}
/************************************************************************
* hashDoAll
* purpose: Call a function on all used elements stored in HASH
* input : hHash - HASH object handle
* func - Function to execute on all elements
* param - Context to use when executing the function
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int hashDoAll(
IN HHASH hHash,
IN HASHEFunc func,
IN void* param)
{
hashStruct* hash = (hashStruct *)hHash;
int cur;
if (hash == NULL) return RV_ERROR_UNKNOWN;
cur = -1;
while ((cur = raGetNext(hash->elements, cur)) >= 0)
{
param = func(hHash, (void*)raGet(hash->elements, cur), param);
}
return RV_OK;
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -