hashtable.c

Go to the documentation of this file.
00001 /* Eliot                                                                     */
00002 /* Copyright (C) 1999  Antoine Fraboulet                                     */
00003 /*                                                                           */
00004 /* This file is part of Eliot.                                               */
00005 /*                                                                           */
00006 /* Eliot is free software; you can redistribute it and/or modify             */
00007 /* it under the terms of the GNU General Public License as published by      */
00008 /* the Free Software Foundation; either version 2 of the License, or         */
00009 /* (at your option) any later version.                                       */
00010 /*                                                                           */
00011 /* Eliot is distributed in the hope that it will be useful,                  */
00012 /* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
00013 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
00014 /* GNU General Public License for more details.                              */
00015 /*                                                                           */
00016 /* You should have received a copy of the GNU General Public License         */
00017 /* along with this program; if not, write to the Free Software               */
00018 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00019 
00020 /**
00021  *  \file   hashtable.c
00022  *  \brief  Simple hashtable type
00023  *  \author Antoine Fraboulet
00024  *  \date   1999
00025  */
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include "hashtable.h"
00031 
00032 typedef struct _Hash_node {
00033   struct _Hash_node *next;
00034   void* key;
00035   unsigned int keysize;
00036   void* value;
00037   unsigned int valuesize;
00038 } Hash_node;
00039 
00040 struct _Hash_table {
00041   unsigned int size;
00042   Hash_node** nodes;
00043 };
00044 
00045 
00046 Hash_table
00047 hash_init(unsigned int size)
00048 {
00049   Hash_table ht;
00050 
00051   ht = (Hash_table) calloc(1,sizeof(struct _Hash_table));
00052   ht->size = size;
00053   ht->nodes = (Hash_node  **) calloc (size, sizeof (Hash_node*));
00054   return ht;
00055 }
00056 
00057 void
00058 hash_rec_free(Hash_node* node)
00059 {
00060   if (node)
00061     {
00062       if (node->next)
00063         hash_rec_free(node->next);
00064       if (node->key)
00065         free(node->key);
00066       if (node->value)
00067         free(node->value);
00068       free(node);
00069     }
00070 }
00071 
00072 int
00073 hash_destroy(Hash_table hashtable)
00074 {
00075   unsigned int i;
00076   if (hashtable)
00077     {
00078       for(i=0; i<hashtable->size; i++)
00079         if (hashtable->nodes[i])
00080           hash_rec_free(hashtable->nodes[i]);
00081       if (hashtable->nodes)
00082         free(hashtable->nodes);
00083       free(hashtable);
00084     }
00085   return 0;
00086 }
00087 
00088 
00089 static unsigned int
00090 hash_key(Hash_table hashtable, void* ptr, unsigned int size)
00091 {
00092   unsigned int i;
00093   unsigned int key = 0;
00094 
00095   if (size % 4 == 0)
00096     {
00097       unsigned int *v = (unsigned int*)ptr;
00098       for (i = 0; i < (size / 4); i++)
00099         key ^= (key << 3) ^ (key >> 1) ^ v[i];
00100     }
00101   else
00102     {
00103       unsigned char *v = (unsigned char*)ptr;
00104       for (i = 0; i < size; i++)
00105         key ^= (key << 3) ^ (key >> 1) ^ v[i];
00106     }
00107   key %= hashtable->size;
00108   return key;
00109 }
00110 
00111 
00112 void*
00113 hash_find(Hash_table hashtable, void* key, unsigned int keysize)
00114 {
00115   Hash_node *entry;
00116   unsigned int h_key;
00117 
00118   h_key = hash_key(hashtable,key,keysize);
00119   for (entry = hashtable->nodes[h_key]; entry; entry = entry -> next)
00120     {
00121       if ((entry -> keysize == keysize) &&
00122           (memcmp(entry->key,key,keysize) == 0))
00123         {
00124           return entry->value;
00125         }
00126     }
00127   return NULL;
00128 }
00129 
00130 
00131 static Hash_node*
00132 new_entry(void* key, unsigned int keysize, void* value, unsigned int
00133           valuesize)
00134 {
00135   Hash_node *n;
00136   n = (Hash_node*)calloc(1,sizeof(Hash_node));
00137   n->key = (void*)malloc(keysize);
00138   n->value = (void*)malloc(valuesize);
00139   n->keysize = keysize;
00140   n->valuesize = valuesize;
00141   memcpy(n->key,key,keysize);
00142   memcpy(n->value,value,valuesize);
00143   return n;
00144 }
00145 
00146 
00147 int
00148 hash_add(Hash_table hashtable,
00149          void* key, unsigned int keysize,
00150          void* value, unsigned int valuesize)
00151 {
00152   Hash_node *entry;
00153   unsigned int h_key;
00154 
00155   h_key = hash_key(hashtable,key,keysize);
00156   entry = new_entry(key,keysize,value,valuesize);
00157   entry->next = hashtable->nodes[h_key];
00158   hashtable->nodes[h_key] = entry;
00159 
00160   return 0;
00161 }
00162 
00163 

Generated on Thu Dec 29 02:01:14 2005 for Eliot by  doxygen 1.4.5