Annotation of embedaddon/quagga/lib/hash.c, revision 1.1.1.1

1.1       misho       1: /* Hash routine.
                      2:  * Copyright (C) 1998 Kunihiro Ishiguro
                      3:  *
                      4:  * This file is part of GNU Zebra.
                      5:  *
                      6:  * GNU Zebra is free software; you can redistribute it and/or modify
                      7:  * it under the terms of the GNU General Public License as published
                      8:  * by the Free Software Foundation; either version 2, or (at your
                      9:  * option) any later version.
                     10:  *
                     11:  * GNU Zebra is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU General Public License
                     17:  * along with GNU Zebra; see the file COPYING.  If not, write to the
                     18:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
                     19:  * Boston, MA 02111-1307, USA.
                     20:  */
                     21: 
                     22: #include <zebra.h>
                     23: 
                     24: #include "hash.h"
                     25: #include "memory.h"
                     26: 
                     27: /* Allocate a new hash.  */
                     28: struct hash *
                     29: hash_create_size (unsigned int size, unsigned int (*hash_key) (void *),
                     30:                                      int (*hash_cmp) (const void *, const void *))
                     31: {
                     32:   struct hash *hash;
                     33: 
                     34:   hash = XMALLOC (MTYPE_HASH, sizeof (struct hash));
                     35:   hash->index = XCALLOC (MTYPE_HASH_INDEX,
                     36:                         sizeof (struct hash_backet *) * size);
                     37:   hash->size = size;
                     38:   hash->hash_key = hash_key;
                     39:   hash->hash_cmp = hash_cmp;
                     40:   hash->count = 0;
                     41: 
                     42:   return hash;
                     43: }
                     44: 
                     45: /* Allocate a new hash with default hash size.  */
                     46: struct hash *
                     47: hash_create (unsigned int (*hash_key) (void *), 
                     48:              int (*hash_cmp) (const void *, const void *))
                     49: {
                     50:   return hash_create_size (HASHTABSIZE, hash_key, hash_cmp);
                     51: }
                     52: 
                     53: /* Utility function for hash_get().  When this function is specified
                     54:    as alloc_func, return arugment as it is.  This function is used for
                     55:    intern already allocated value.  */
                     56: void *
                     57: hash_alloc_intern (void *arg)
                     58: {
                     59:   return arg;
                     60: }
                     61: 
                     62: /* Lookup and return hash backet in hash.  If there is no
                     63:    corresponding hash backet and alloc_func is specified, create new
                     64:    hash backet.  */
                     65: void *
                     66: hash_get (struct hash *hash, void *data, void * (*alloc_func) (void *))
                     67: {
                     68:   unsigned int key;
                     69:   unsigned int index;
                     70:   void *newdata;
                     71:   struct hash_backet *backet;
                     72: 
                     73:   key = (*hash->hash_key) (data);
                     74:   index = key % hash->size;
                     75: 
                     76:   for (backet = hash->index[index]; backet != NULL; backet = backet->next) 
                     77:     if (backet->key == key && (*hash->hash_cmp) (backet->data, data))
                     78:       return backet->data;
                     79: 
                     80:   if (alloc_func)
                     81:     {
                     82:       newdata = (*alloc_func) (data);
                     83:       if (newdata == NULL)
                     84:        return NULL;
                     85: 
                     86:       backet = XMALLOC (MTYPE_HASH_BACKET, sizeof (struct hash_backet));
                     87:       backet->data = newdata;
                     88:       backet->key = key;
                     89:       backet->next = hash->index[index];
                     90:       hash->index[index] = backet;
                     91:       hash->count++;
                     92:       return backet->data;
                     93:     }
                     94:   return NULL;
                     95: }
                     96: 
                     97: /* Hash lookup.  */
                     98: void *
                     99: hash_lookup (struct hash *hash, void *data)
                    100: {
                    101:   return hash_get (hash, data, NULL);
                    102: }
                    103: 
                    104: /* Simple Bernstein hash which is simple and fast for common case */
                    105: unsigned int string_hash_make (const char *str)
                    106: {
                    107:   unsigned int hash = 0;
                    108: 
                    109:   while (*str)
                    110:     hash = (hash * 33) ^ (unsigned int) *str++;
                    111: 
                    112:   return hash;
                    113: }
                    114: 
                    115: /* This function release registered value from specified hash.  When
                    116:    release is successfully finished, return the data pointer in the
                    117:    hash backet.  */
                    118: void *
                    119: hash_release (struct hash *hash, void *data)
                    120: {
                    121:   void *ret;
                    122:   unsigned int key;
                    123:   unsigned int index;
                    124:   struct hash_backet *backet;
                    125:   struct hash_backet *pp;
                    126: 
                    127:   key = (*hash->hash_key) (data);
                    128:   index = key % hash->size;
                    129: 
                    130:   for (backet = pp = hash->index[index]; backet; backet = backet->next)
                    131:     {
                    132:       if (backet->key == key && (*hash->hash_cmp) (backet->data, data)) 
                    133:        {
                    134:          if (backet == pp) 
                    135:            hash->index[index] = backet->next;
                    136:          else 
                    137:            pp->next = backet->next;
                    138: 
                    139:          ret = backet->data;
                    140:          XFREE (MTYPE_HASH_BACKET, backet);
                    141:          hash->count--;
                    142:          return ret;
                    143:        }
                    144:       pp = backet;
                    145:     }
                    146:   return NULL;
                    147: }
                    148: 
                    149: /* Iterator function for hash.  */
                    150: void
                    151: hash_iterate (struct hash *hash, 
                    152:              void (*func) (struct hash_backet *, void *), void *arg)
                    153: {
                    154:   unsigned int i;
                    155:   struct hash_backet *hb;
                    156:   struct hash_backet *hbnext;
                    157: 
                    158:   for (i = 0; i < hash->size; i++)
                    159:     for (hb = hash->index[i]; hb; hb = hbnext)
                    160:       {
                    161:        /* get pointer to next hash backet here, in case (*func)
                    162:         * decides to delete hb by calling hash_release
                    163:         */
                    164:        hbnext = hb->next;
                    165:        (*func) (hb, arg);
                    166:       }
                    167: }
                    168: 
                    169: /* Clean up hash.  */
                    170: void
                    171: hash_clean (struct hash *hash, void (*free_func) (void *))
                    172: {
                    173:   unsigned int i;
                    174:   struct hash_backet *hb;
                    175:   struct hash_backet *next;
                    176: 
                    177:   for (i = 0; i < hash->size; i++)
                    178:     {
                    179:       for (hb = hash->index[i]; hb; hb = next)
                    180:        {
                    181:          next = hb->next;
                    182:              
                    183:          if (free_func)
                    184:            (*free_func) (hb->data);
                    185: 
                    186:          XFREE (MTYPE_HASH_BACKET, hb);
                    187:          hash->count--;
                    188:        }
                    189:       hash->index[i] = NULL;
                    190:     }
                    191: }
                    192: 
                    193: /* Free hash memory.  You may call hash_clean before call this
                    194:    function.  */
                    195: void
                    196: hash_free (struct hash *hash)
                    197: {
                    198:   XFREE (MTYPE_HASH_INDEX, hash->index);
                    199:   XFREE (MTYPE_HASH, hash);
                    200: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>