gif_hash.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002 *   "Gif-Lib" - Yet another gif library.                                     *
00003 *                                                                            *
00004 * Written by:  Gershon Elber                    IBM PC Ver 0.1, Jun. 1989    *
00005 ******************************************************************************
00006 * Module to support the following operations:                                *
00007 *                                                                            *
00008 * 1. InitHashTable - initialize hash table.                                  *
00009 * 2. ClearHashTable - clear the hash table to an empty state.                *
00010 * 2. InsertHashTable - insert one item into data structure.                  *
00011 * 3. ExistsHashTable - test if item exists in data structure.                *
00012 *                                                                            *
00013 * This module is used to hash the GIF codes during encoding.                 *
00014 ******************************************************************************
00015 * History:                                                                   *
00016 * 14 Jun 89 - Version 1.0 by Gershon Elber.                                  *
00017 *****************************************************************************/
00018 
00019 #ifdef _WIN32
00020 #include "../win32/config.h"
00021 #else
00022 #include "../config.h"
00023 #endif
00024 
00025 /* Find a thirty-two bit int type */
00026 #ifdef HAVE_SYS_TYPES_H
00027 #include <sys/types.h>
00028 #endif
00029 
00030 #ifdef __MSDOS__
00031 #include <io.h>
00032 #include <alloc.h>
00033 #include <sys\stat.h>
00034 #else
00035 #include <sys/types.h>
00036 #include <sys/stat.h>
00037 #endif /* __MSDOS__ */
00038 
00039 #ifdef HAVE_FCNTL_H
00040 #include <fcntl.h>
00041 #endif /* HAVE_FCNTL_H */
00042 #include <stdio.h>
00043 #include <string.h>
00044 #include "gif_lib.h"
00045 #include "gif_hash.h"
00046 #include "gif_lib_private.h"
00047 
00048 /* #define  DEBUG_HIT_RATE    Debug number of misses per hash Insert/Exists. */
00049 
00050 #ifdef  DEBUG_HIT_RATE
00051 static long NumberOfTests = 0,
00052             NumberOfMisses = 0;
00053 #endif  /* DEBUG_HIT_RATE */
00054 
00055 static int KeyItem(UINT32 Item);
00056 
00057 /******************************************************************************
00058 * Initialize HashTable - allocate the memory needed and clear it.             *
00059 ******************************************************************************/
00060 GifHashTableType *_InitHashTable(void)
00061 {
00062     GifHashTableType *HashTable;
00063 
00064     if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType)))
00065         == NULL)
00066         return NULL;
00067 
00068     _ClearHashTable(HashTable);
00069 
00070     return HashTable;
00071 }
00072 
00073 /******************************************************************************
00074 * Routine to clear the HashTable to an empty state.                           *
00075 * This part is a little machine depended. Use the commented part otherwise.   *
00076 ******************************************************************************/
00077 void _ClearHashTable(GifHashTableType *HashTable)
00078 {
00079     memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(UINT32));
00080 }
00081 
00082 /******************************************************************************
00083 * Routine to insert a new Item into the HashTable. The data is assumed to be  *
00084 * new one.                                                                    *
00085 ******************************************************************************/
00086 void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code)
00087 {
00088     int HKey = KeyItem(Key);
00089     UINT32 *HTable = HashTable -> HTable;
00090 
00091 #ifdef DEBUG_HIT_RATE
00092         NumberOfTests++;
00093         NumberOfMisses++;
00094 #endif /* DEBUG_HIT_RATE */
00095 
00096     while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) {
00097 #ifdef DEBUG_HIT_RATE
00098             NumberOfMisses++;
00099 #endif /* DEBUG_HIT_RATE */
00100         HKey = (HKey + 1) & HT_KEY_MASK;
00101     }
00102     HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code);
00103 }
00104 
00105 /******************************************************************************
00106 * Routine to test if given Key exists in HashTable and if so returns its code *
00107 * Returns the Code if key was found, -1 if not.                               *
00108 ******************************************************************************/
00109 int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key)
00110 {
00111     int HKey = KeyItem(Key);
00112     UINT32 *HTable = HashTable -> HTable, HTKey;
00113 
00114 #ifdef DEBUG_HIT_RATE
00115         NumberOfTests++;
00116         NumberOfMisses++;
00117 #endif /* DEBUG_HIT_RATE */
00118 
00119     while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) {
00120 #ifdef DEBUG_HIT_RATE
00121             NumberOfMisses++;
00122 #endif /* DEBUG_HIT_RATE */
00123         if (Key == HTKey) return HT_GET_CODE(HTable[HKey]);
00124         HKey = (HKey + 1) & HT_KEY_MASK;
00125     }
00126 
00127     return -1;
00128 }
00129 
00130 /******************************************************************************
00131 * Routine to generate an HKey for the hashtable out of the given unique key.  *
00132 * The given Key is assumed to be 20 bits as follows: lower 8 bits are the     *
00133 * new postfix character, while the upper 12 bits are the prefix code.         *
00134 * Because the average hit ratio is only 2 (2 hash references per entry),      *
00135 * evaluating more complex keys (such as twin prime keys) does not worth it!   *
00136 ******************************************************************************/
00137 static int KeyItem(UINT32 Item)
00138 {
00139     return ((Item >> 12) ^ Item) & HT_KEY_MASK;
00140 }
00141 
00142 #ifdef  DEBUG_HIT_RATE
00143 /******************************************************************************
00144 * Debugging routine to print the hit ratio - number of times the hash table   *
00145 * was tested per operation. This routine was used to test the KeyItem routine *
00146 ******************************************************************************/
00147 void HashTablePrintHitRatio(void)
00148 {
00149     printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n",
00150         NumberOfMisses, NumberOfTests,
00151         NumberOfMisses * 100 / NumberOfTests);
00152 }
00153 #endif  /* DEBUG_HIT_RATE */

Generated on Tue Jul 5 14:13:32 2011 for ROOT_528-00b_version by  doxygen 1.5.1