随便贴一个libhash中的hash函数,写的貌似不错,贴出来玩玩。
hash.h
/*
* Australian Public Licence B (OZPLB)
*
* Version 1-0
*
* Copyright (c) 2004 National ICT Australia
*
* All rights reserved.
*
* Developed by: Embedded, Real-time and Operating Systems Program (ERTOS)
* National ICT Australia
* http://www.ertos.nicta.com.au
*/
#ifndef _HASH_H
#define _HASH_H
#include < stdint.h >
struct hashtable {
struct hashentry ** table;
unsigned int size;
struct hashentry * spares;
};
struct hashentry {
struct hashentry * next;
uintptr_t key;
void * value;
};
struct hashtable * hash_init (unsigned int size);
void hash_free ( struct hashtable * tablestruct);
uintptr_t hash_hash(uintptr_t key);
void * hash_lookup ( struct hashtable * tablestruct, uintptr_t key);
int hash_insert ( struct hashtable * tablestruct, uintptr_t key, void * value);
void hash_remove ( struct hashtable * tablestruct, uintptr_t key);
#endif /* !_HASH_H */
* Australian Public Licence B (OZPLB)
*
* Version 1-0
*
* Copyright (c) 2004 National ICT Australia
*
* All rights reserved.
*
* Developed by: Embedded, Real-time and Operating Systems Program (ERTOS)
* National ICT Australia
* http://www.ertos.nicta.com.au
*/
#ifndef _HASH_H
#define _HASH_H
#include < stdint.h >
struct hashtable {
struct hashentry ** table;
unsigned int size;
struct hashentry * spares;
};
struct hashentry {
struct hashentry * next;
uintptr_t key;
void * value;
};
struct hashtable * hash_init (unsigned int size);
void hash_free ( struct hashtable * tablestruct);
uintptr_t hash_hash(uintptr_t key);
void * hash_lookup ( struct hashtable * tablestruct, uintptr_t key);
int hash_insert ( struct hashtable * tablestruct, uintptr_t key, void * value);
void hash_remove ( struct hashtable * tablestruct, uintptr_t key);
#endif /* !_HASH_H */
hash.c
#include
<
stdint.h
>
#include < stdlib.h >
#include < assert.h >
#include " hash.h "
struct hashtable *
hash_init (unsigned int size)
{
struct hashtable * tablestruct;
int counter;
/* Our hash function only works with power-of-2 bucket sizes for speed. */
assert ((size & (size - 1 )) == 0 );
tablestruct = malloc ( sizeof ( struct hashtable)); assert (tablestruct);
if ( ! tablestruct) {
return NULL;
}
tablestruct -> table = malloc (size * sizeof ( struct hashentry * ));
if ( ! tablestruct -> table) {
return NULL;
}
for (counter = 0 ; counter < size; counter ++ ) {
tablestruct -> table[counter] = NULL;
}
assert (tablestruct -> table);
tablestruct -> size = size;
tablestruct -> spares = NULL;
return tablestruct;
}
/* Ref http://www.concentric.net/ ~Ttwang/tech/inthash.htm */
uintptr_t
hash_hash(uintptr_t key)
{
#if (UINTPTR_MAX == UINT32_MAX)
key += ~ (key << 15 );
key ^= (key >> 10 );
key += (key << 3 );
key ^= (key >> 6 );
key += ~ (key << 11 );
key ^= (key >> 16 );
#elif (UINTPTR_MAX == UINT64_MAX)
key += ~ (key << 32 );
key ^= (key >> 22 );
key += ~ (key << 13 );
key ^= (key >> 8 );
key += (key << 3 );
key ^= (key >> 15 );
key += ~ (key << 27 );
key ^= (key >> 31 );
#else
#error unsupported word size
#endif
// printf ("new key is %d ", key);
return key;
}
void *
hash_lookup ( struct hashtable * tablestruct, uintptr_t key)
{
uintptr_t hash;
struct hashentry * entry;
hash = hash_hash (key) & (tablestruct -> size - 1 );
for (entry = tablestruct -> table[hash]; entry != NULL; entry = entry -> next) {
if (entry -> key == key) {
return entry -> value;
}
}
return NULL;
}
/* Add the key to the hash table. Assumes the key is not already present. */
int
hash_insert ( struct hashtable * tablestruct, uintptr_t key, void * value)
{
uintptr_t hash;
struct hashentry * entry;
hash = hash_hash (key) & (tablestruct -> size - 1 );
// printf ("bucket is %d ", hash);
entry = malloc ( sizeof ( struct hashentry));
if ( ! entry) {
return - 1 ;
}
entry -> key = key;
entry -> value = value;
entry -> next = tablestruct -> table[hash];
tablestruct -> table[hash] = entry;
return 0 ;
}
/* Removes the key from the hash table. Does not signal an error if the key
* was not present. */
void
hash_remove ( struct hashtable * tablestruct, uintptr_t key)
{
uintptr_t hash;
struct hashentry * entry, * tmpentry;
hash = hash_hash (key) & (tablestruct -> size - 1 );
entry = tablestruct -> table[hash];
/* If this is the first entry then it needs special handling. */
if (entry && entry -> key == key) {
tmpentry = entry -> next;
free (entry);
tablestruct -> table[hash] = tmpentry;
} else {
while (entry) {
if (entry -> next && entry -> next -> key == key) {
tmpentry = entry -> next;
entry -> next = entry -> next -> next;
free (tmpentry);
break ;
}
entry = entry -> next;
}
}
}
#include < stdlib.h >
#include < assert.h >
#include " hash.h "
struct hashtable *
hash_init (unsigned int size)
{
struct hashtable * tablestruct;
int counter;
/* Our hash function only works with power-of-2 bucket sizes for speed. */
assert ((size & (size - 1 )) == 0 );
tablestruct = malloc ( sizeof ( struct hashtable)); assert (tablestruct);
if ( ! tablestruct) {
return NULL;
}
tablestruct -> table = malloc (size * sizeof ( struct hashentry * ));
if ( ! tablestruct -> table) {
return NULL;
}
for (counter = 0 ; counter < size; counter ++ ) {
tablestruct -> table[counter] = NULL;
}
assert (tablestruct -> table);
tablestruct -> size = size;
tablestruct -> spares = NULL;
return tablestruct;
}
/* Ref http://www.concentric.net/ ~Ttwang/tech/inthash.htm */
uintptr_t
hash_hash(uintptr_t key)
{
#if (UINTPTR_MAX == UINT32_MAX)
key += ~ (key << 15 );
key ^= (key >> 10 );
key += (key << 3 );
key ^= (key >> 6 );
key += ~ (key << 11 );
key ^= (key >> 16 );
#elif (UINTPTR_MAX == UINT64_MAX)
key += ~ (key << 32 );
key ^= (key >> 22 );
key += ~ (key << 13 );
key ^= (key >> 8 );
key += (key << 3 );
key ^= (key >> 15 );
key += ~ (key << 27 );
key ^= (key >> 31 );
#else
#error unsupported word size
#endif
// printf ("new key is %d ", key);
return key;
}
void *
hash_lookup ( struct hashtable * tablestruct, uintptr_t key)
{
uintptr_t hash;
struct hashentry * entry;
hash = hash_hash (key) & (tablestruct -> size - 1 );
for (entry = tablestruct -> table[hash]; entry != NULL; entry = entry -> next) {
if (entry -> key == key) {
return entry -> value;
}
}
return NULL;
}
/* Add the key to the hash table. Assumes the key is not already present. */
int
hash_insert ( struct hashtable * tablestruct, uintptr_t key, void * value)
{
uintptr_t hash;
struct hashentry * entry;
hash = hash_hash (key) & (tablestruct -> size - 1 );
// printf ("bucket is %d ", hash);
entry = malloc ( sizeof ( struct hashentry));
if ( ! entry) {
return - 1 ;
}
entry -> key = key;
entry -> value = value;
entry -> next = tablestruct -> table[hash];
tablestruct -> table[hash] = entry;
return 0 ;
}
/* Removes the key from the hash table. Does not signal an error if the key
* was not present. */
void
hash_remove ( struct hashtable * tablestruct, uintptr_t key)
{
uintptr_t hash;
struct hashentry * entry, * tmpentry;
hash = hash_hash (key) & (tablestruct -> size - 1 );
entry = tablestruct -> table[hash];
/* If this is the first entry then it needs special handling. */
if (entry && entry -> key == key) {
tmpentry = entry -> next;
free (entry);
tablestruct -> table[hash] = tmpentry;
} else {
while (entry) {
if (entry -> next && entry -> next -> key == key) {
tmpentry = entry -> next;
entry -> next = entry -> next -> next;
free (tmpentry);
break ;
}
entry = entry -> next;
}
}
}
hash_free.c
#include
<
stdint.h
>
#include < stdlib.h >
#include " hash.h "
void
hash_free ( struct hashtable * tablestruct)
{
int counter;
struct hashentry * entry, * prev;
/* Need to free buckets and table struct and every item in every chain */
for (counter = 0 ; counter < tablestruct -> size; counter ++ ) {
entry = tablestruct -> table[counter];
while (entry) {
prev = entry;
entry = entry -> next;
free (prev);
}
}
free (tablestruct -> table);
free (tablestruct);
}
#include < stdlib.h >
#include " hash.h "
void
hash_free ( struct hashtable * tablestruct)
{
int counter;
struct hashentry * entry, * prev;
/* Need to free buckets and table struct and every item in every chain */
for (counter = 0 ; counter < tablestruct -> size; counter ++ ) {
entry = tablestruct -> table[counter];
while (entry) {
prev = entry;
entry = entry -> next;
free (prev);
}
}
free (tablestruct -> table);
free (tablestruct);
}
来源:http://ertos.nicta.com.au/software/kenge/libhash/devel/
更多结果:http://www.google.cn/search?complete=1&hl=zh-CN&q=libhash&meta=