hash.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:10k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* hash.c - DHCP server hash table routines */
  2. /* Copyright 1984 - 2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01b,09oct01,vvv  fixed mod hist
  8. 01a,07apr97,spm  created by modifying WIDE project DHCP implementation
  9. */
  10. /*
  11. DESCRIPTION
  12. This library contains the code used by the DHCP server to add and remove 
  13. entries from the internal hash tables. The following hash tables are used:
  14.      cidhashtable - contains resource entries accessed by client ID.
  15.                     (These entries are by definition for infinite leases
  16.                      since they may only be issued to a specific client).
  17.      iphashtable - contains resource entries accessed by IP address, so that
  18.                    client requests for particular IP addresses may be 
  19.                    processed efficiently.
  20.      nmhashtable - contains resource entries accessed by entry name. Used
  21.                    when reading binding database from permanent storage and
  22.                    when quoting previously defined address pool entries.
  23.      relayhashtable - contains list of known relay agents, accessed by 
  24.                       IP address.
  25.      paramhashtable - contains client-specific and class-specific DHCP options 
  26.                       accessed by corresponding identifier.
  27. INCLUDE_FILES: None
  28. */
  29. /*
  30.  * Modified by Akihiro Tominaga. (tomy@sfc.wide.ad.jp)
  31.  */
  32. /*
  33.  * Generalized hash table ADT
  34.  *
  35.  * Provides multiple, dynamically-allocated, variable-sized hash tables on
  36.  * various data and keys.
  37.  *
  38.  * This package attempts to follow some of the coding conventions suggested
  39.  * by Bob Sidebotham and the AFS Clean Code Committee of the
  40.  * Information Technology Center at Carnegie Mellon.
  41.  *
  42.  *
  43.  *
  44.  * Copyright (c) 1988 by Carnegie Mellon.
  45.  *
  46.  * Permission to use, copy, modify, and distribute this program for any
  47.  * purpose and without fee is hereby granted, provided that this copyright
  48.  * and permission notice appear on all copies and supporting documentation,
  49.  * the name of Carnegie Mellon not be used in advertising or publicity
  50.  * pertaining to distribution of the program without specific prior
  51.  * permission, and notice be given in supporting documentation that copying
  52.  * and distribution is by permission of Carnegie Mellon.  Carnegie Mellon
  53.  * makes no representations about the suitability of this software for any
  54.  * purpose.  It is provided "as is" without express or implied warranty.
  55.  */
  56. #include "vxWorks.h"
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59. #include "dhcp/hash.h"
  60. static unsigned   hash_func();
  61. /*******************************************************************************
  62. *
  63. * hash_func - calculate a hash code from the given string
  64. *
  65. * This function returns the sum of the squares of all the bytes for use as
  66. * the "hashcode" parameter in to other functions in this library. The size
  67. * of all hashtables currently in use is a prime number. This algorithm
  68. * probably works best under that condition.
  69. *
  70. * RETURNS: Calculated hash code.
  71. *
  72. * ERRNO: N/A
  73. *
  74. * NOMANUAL
  75. */
  76. static unsigned hash_func
  77.     (
  78.     char *string,  /* string to use for hashcode */
  79.     FAST unsigned len  /* length of input string */
  80.     )
  81.     {
  82.     FAST unsigned sum; 
  83.     FAST unsigned value = 0;
  84.     sum = 0;
  85.     for (; len > 0; len--) 
  86.         {
  87.         value = (unsigned) (*string++ & 0xFF);
  88.         sum += value * value;
  89.         }
  90.     return (sum);
  91.     }
  92. /*******************************************************************************
  93. *
  94. * hash_ins - add an element to a hash table
  95. *
  96. * This function inserts the given element into the specified hash table after 
  97. * determining the correct hashcode. If the data item is already present, the
  98. * insertion fails.
  99. *
  100. * RETURNS: 0 if insertion successful, or -1 on duplicate item or error.
  101. *
  102. * ERRNO: N/A
  103. *
  104. * NOMANUAL
  105. */
  106. int hash_ins
  107.     (
  108.     struct hash_tbl *hashtable, /* target hash table */
  109.     char *str,  /* string to use for hash code */
  110.     unsigned length,  /* length of hash code string */
  111.     int (*compare)(),  /* comparison function for hash keys */
  112.     hash_datum *key,  /* hash key for detection of duplicates */
  113.     hash_datum *element  /* data to store in hash table */
  114.     )
  115.     {
  116.     unsigned hashcode;
  117.     struct hash_member *memberptr = NULL; 
  118.     struct hash_member *temp = NULL;
  119.     /* Calculate appropriate hashcode. */
  120.     hashcode = hash_func (str, length);
  121.     hashcode %= HASHTBL_SIZE;
  122.     /* Check for duplicate entry. */
  123.     if (hash_exst (hashtable, hashcode, compare, key)) 
  124.         return (-1); 
  125.     /* Store new element in table. */
  126.     memberptr = (hashtable->head) [hashcode];
  127.     temp = (struct hash_member *)calloc (1, sizeof (struct hash_member));
  128.     if (temp == NULL) 
  129.         return (-1);  
  130.     else
  131.         {
  132.         temp->data = element;
  133.         temp->next = memberptr;
  134.         (hashtable->head) [hashcode] = temp;
  135.         }
  136.     return(0);
  137.     }
  138. /*******************************************************************************
  139. *
  140. * hash_exst - check for existing hash table entries
  141. *
  142. * This routine uses the provided comparison function to determine if 
  143. * a given data item is already present in the indicated bucket of the
  144. * specified hash table. 
  145. *
  146. * RETURNS: TRUE if matching entry found, or FALSE otherwise.
  147. *
  148. * ERRNO: N/A
  149. *
  150. * NOMANUAL
  151. */
  152. int hash_exst
  153.     (
  154.     struct hash_tbl *hashtable, /* target hash table */
  155.     unsigned hashcode,  /* offset in table */
  156.     int (*compare)(),  /* comparison function for hash keys */
  157.     hash_datum *key  /* key to detect duplicate entries */
  158.     )
  159.     {
  160.     FAST struct hash_member *memberptr = NULL;
  161.     memberptr = (hashtable->head) [hashcode % HASHTBL_SIZE];
  162.     while (memberptr) 
  163.         {
  164.         if ( (*compare) (key, memberptr->data)) 
  165.             return TRUE;    /* Entry does exist */
  166.         memberptr = memberptr->next;
  167.         }
  168.     return FALSE;    /* Entry does not exist */
  169.     }
  170. /*******************************************************************************
  171. *
  172. * hash_find - return a hash table entry
  173. *
  174. * This function locates the data entry associated with the given key, if any.
  175. *
  176. * RETURNS: Pointer to data entry, or NULL if not found.
  177. *
  178. * ERRNO: N/A
  179. *
  180. * NOMANUAL
  181. */
  182. hash_datum * hash_find
  183.     (
  184.     struct hash_tbl *hashtable, /* target hash table */
  185.     char *str,  /* string to use for hash code */
  186.     unsigned length,  /* length of hash code string */
  187.     int (*compare)(),  /* comparison function for hash keys */
  188.     hash_datum *key  /* hash key for desired entry */
  189.     )
  190.     {
  191.     unsigned hashcode;
  192.     struct hash_member *memberptr = NULL;
  193.     hashcode = hash_func (str, length);
  194.     memberptr = (hashtable->head) [hashcode % HASHTBL_SIZE];
  195.     while (memberptr) 
  196.         {
  197.         if ( (*compare) (key, memberptr->data)) 
  198.             return (memberptr->data);
  199.         memberptr = memberptr->next;
  200.         }
  201.     return NULL;
  202.     }
  203. /*******************************************************************************
  204. *
  205. * hash_pickup - find and remove a hash table entry
  206. *
  207. * Like hash_exst(), this function searches the indicated bucket of the 
  208. * specified hash table for a data entry associated with the given key. 
  209. * If found, the matching entry is removed from the hash table.
  210. * of all hashtables currently in use is a prime number. This algorithm
  211. * probably works best under that condition.
  212. *
  213. * RETURNS: Pointer to extracted entry, or NULL if not found.
  214. *
  215. * ERRNO: N/A
  216. *
  217. * NOMANUAL
  218. */
  219. hash_datum * hash_pickup
  220.     (
  221.     struct hash_tbl *hashtable,  /* target hash table */
  222.     unsigned hashcode,  /* offset in hash table */
  223.     int (*compare) (),  /* comparison function for hash keys */
  224.     hash_datum *key  /* hash key for desired entry */
  225.     )
  226.     {
  227.     struct hash_member *memberptr = NULL;
  228.     struct hash_member *previous = NULL;
  229.     hash_datum *result = NULL;
  230.     memberptr = (hashtable->head) [hashcode % HASHTBL_SIZE];
  231.     while (memberptr) 
  232.         {
  233.         if ( (*compare) (key, memberptr->data)) 
  234.             {
  235.             if (memberptr == *hashtable->head) 
  236.         *hashtable->head = memberptr->next;
  237.             else 
  238.         previous->next = memberptr->next;
  239.             result = memberptr->data;
  240.             free (memberptr);
  241.             return (result);
  242.             }
  243.         previous = memberptr;
  244.         memberptr = memberptr->next;
  245.         }
  246.     return (NULL);
  247.     }
  248. /*******************************************************************************
  249. *
  250. * hash_del - remove hash table elements
  251. *
  252. * This routine deletes all data elements which match the given key.
  253. *
  254. * RETURNS: 0 if deletion successful, or -1 if no matching elements found.
  255. *
  256. * ERRNO: N/A
  257. *
  258. * NOMANUAL
  259. */
  260. int hash_del
  261.     (
  262.     struct hash_tbl *hashtable,  /* hash table to be cleaned */
  263.     char *str,  /* string to use for hash code */
  264.     unsigned length,  /* length of hash code string */
  265.     int (*compare) (),  /* comparison function for hash keys */
  266.     hash_datum *key,  /* hash key of target entries */
  267.     int (*free_data) ()  /* function to remove table entry */
  268.     )
  269.     {
  270.     unsigned hashcode;
  271.     struct hash_member *memberptr = NULL;
  272.     struct hash_member *previous = NULL;
  273.     struct hash_member *tempptr = NULL;
  274.     int retval = -1;
  275.     hashcode = hash_func (str, length);
  276.     hashcode %= HASHTBL_SIZE;
  277.     /* Remove matching entries at the head of the list. */
  278.     memberptr = (hashtable->head) [hashcode];
  279.     while (memberptr != NULL && (*compare) (key, memberptr->data)) 
  280.         {
  281.         (hashtable->head) [hashcode] = memberptr->next;
  282.    
  283.          /*
  284.           * Clear next pointer to prevent list traversal by removal function. 
  285.           */
  286.         memberptr->next = NULL;
  287.         free_data (memberptr);
  288.         memberptr = (hashtable->head) [hashcode];
  289.         retval = 0;
  290.         }
  291.     /*
  292.      * Now traverse the rest of the list.
  293.      */
  294.     previous = memberptr;
  295.     if (memberptr != NULL) 
  296.         memberptr = memberptr->next;
  297.     while (memberptr != NULL) 
  298.         {
  299.         if ( (*compare) (key, memberptr->data)) 
  300.             {
  301.             tempptr = memberptr;
  302.             /* Bypass lease entry to be removed. */
  303.             previous->next = memberptr = memberptr->next;
  304.             /*
  305.              * Prevent list traversal by removal function. 
  306.              */
  307.             tempptr->next = NULL;
  308.             free_data (tempptr);
  309.             retval = 0;
  310.             } 
  311.         else 
  312.             {
  313.             previous = memberptr;
  314.             memberptr = memberptr->next;
  315.             }
  316.         }
  317.     return retval;
  318.     }