Bookmark and Share

Lee's 程序人生

HTML CSS Javascript XML AJAX ATLAS C# C++ 数据结构 软件工程 设计模式 asp.net Java 数字图象处理 Sql 数据库
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

[转]libhash中的哈希函数

Posted on 2007-08-08 05:09  analyzer  阅读(374)  评论(0编辑  收藏  举报
随便贴一个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 */

 

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;
                }
        }
}

 

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);
}

 

来源:http://ertos.nicta.com.au/software/kenge/libhash/devel/

更多结果:http://www.google.cn/search?complete=1&hl=zh-CN&q=libhash&meta=

 

我要啦免费统计