IFPACK  Development
 All Classes Files Functions Variables Enumerations Friends
Hash_dh.c
00001 /*@HEADER
00002 // ***********************************************************************
00003 //
00004 //       Ifpack: Object-Oriented Algebraic Preconditioner Package
00005 //                 Copyright (2002) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 //@HEADER
00041 */
00042 
00043 #include "Hash_dh.h"
00044 #include "Parser_dh.h"
00045 #include "Mem_dh.h"
00046 
00047 static void Hash_dhInit_private (Hash_dh h, int s);
00048 
00049 #define CUR_MARK_INIT  -1
00050 
00051 
00052 struct _hash_node_private
00053 {
00054   int key;
00055   int mark;
00056   HashData data;
00057 };
00058 
00059 
00060 #undef __FUNC__
00061 #define __FUNC__ "Hash_dhCreate"
00062 void
00063 Hash_dhCreate (Hash_dh * h, int size)
00064 {
00065   START_FUNC_DH
00066     struct _hash_dh *tmp =
00067     (struct _hash_dh *) MALLOC_DH (sizeof (struct _hash_dh));
00068   CHECK_V_ERROR;
00069   *h = tmp;
00070   tmp->size = 0;
00071   tmp->count = 0;
00072   tmp->curMark = CUR_MARK_INIT + 1;
00073   tmp->data = NULL;
00074 
00075   Hash_dhInit_private (*h, size);
00076   CHECK_V_ERROR;
00077 END_FUNC_DH}
00078 
00079 #undef __FUNC__
00080 #define __FUNC__ "Hash_dhDestroy"
00081 void
00082 Hash_dhDestroy (Hash_dh h)
00083 {
00084   START_FUNC_DH if (h->data != NULL)
00085     {
00086       FREE_DH (h->data);
00087       CHECK_V_ERROR;
00088     }
00089   FREE_DH (h);
00090   CHECK_V_ERROR;
00091 END_FUNC_DH}
00092 
00093 #undef __FUNC__
00094 #define __FUNC__ "Hash_dhReset"
00095 void
00096 Hash_dhReset (Hash_dh h)
00097 {
00098   START_FUNC_DH h->count = 0;
00099   h->curMark += 1;
00100 END_FUNC_DH}
00101 
00102 #undef __FUNC__
00103 #define __FUNC__ "Hash_dhInit_private"
00104 void
00105 Hash_dhInit_private (Hash_dh h, int s)
00106 {
00107   START_FUNC_DH int i;
00108   int size = 16;
00109   HashRecord *data;
00110 
00111   /* want table size to be a power of 2: */
00112   while (size < s)
00113     size *= 2;
00114   /* rule-of-thumb: ensure there's some padding */
00115   if ((size - s) < (.1 * size))
00116     {
00117       size *= 2.0;
00118     }
00119   h->size = size;
00120 
00121 /*
00122   sprintf(msgBuf_dh, "requested size = %i; allocated size = %i", s, size); 
00123   SET_INFO(msgBuf_dh);
00124 */
00125 
00126   /* allocate and zero the hash table */
00127   data = h->data = (HashRecord *) MALLOC_DH (size * sizeof (HashRecord));
00128   CHECK_V_ERROR;
00129   for (i = 0; i < size; ++i)
00130     {
00131       data[i].key = -1;
00132       data[i].mark = -1;
00133     }
00134 END_FUNC_DH}
00135 
00136 #undef __FUNC__
00137 #define __FUNC__ "Hash_dhLookup"
00138 HashData *
00139 Hash_dhLookup (Hash_dh h, int key)
00140 {
00141   START_FUNC_DH int i, start;
00142   int curMark = h->curMark;
00143   int size = h->size;
00144   HashData *retval = NULL;
00145   HashRecord *data = h->data;
00146 
00147   HASH_1 (key, size, &start) for (i = 0; i < size; ++i)
00148     {
00149       int tmp, idx;
00150       HASH_2 (key, size, &tmp) idx = (start + i * tmp) % size;
00151       if (data[idx].mark != curMark)
00152     {
00153       break;        /* key wasn't found */
00154     }
00155       else
00156     {
00157       if (data[idx].key == key)
00158         {
00159           retval = &(data[idx].data);
00160           break;
00161         }
00162     }
00163     }
00164 END_FUNC_VAL (retval)}
00165 
00166 
00167 /* 
00168   TODO: (1) check for already-inserted  (done?)
00169         (2) rehash, if table grows too large
00170 */
00171 #undef __FUNC__
00172 #define __FUNC__ "Hash_dhInsert"
00173 void
00174 Hash_dhInsert (Hash_dh h, int key, HashData * dataIN)
00175 {
00176   START_FUNC_DH int i, start, size = h->size;
00177   int curMark = h->curMark;
00178   HashRecord *data;
00179 
00180   data = h->data;
00181 
00182   /* check for overflow */
00183   h->count += 1;
00184   if (h->count == h->size)
00185     {
00186       SET_V_ERROR ("hash table overflow; rehash need implementing!");
00187     }
00188 
00189   HASH_1 (key, size, &start) for (i = 0; i < size; ++i)
00190     {
00191       int tmp, idx;
00192       HASH_2 (key, size, &tmp) idx = (start + i * tmp) % size;
00193       if (data[idx].mark < curMark)
00194     {
00195       data[idx].key = key;
00196       data[idx].mark = curMark;
00197       memcpy (&(data[idx].data), dataIN, sizeof (HashData));
00198       break;
00199     }
00200     }
00201 END_FUNC_DH}
00202 
00203 #undef __FUNC__
00204 #define __FUNC__ "Hash_dhPrint"
00205 void
00206 Hash_dhPrint (Hash_dh h, FILE * fp)
00207 {
00208   START_FUNC_DH int i, size = h->size;
00209   int curMark = h->curMark;
00210   HashRecord *data = h->data;
00211 
00212 
00213   fprintf (fp, "\n--------------------------- hash table \n");
00214   for (i = 0; i < size; ++i)
00215     {
00216       if (data[i].mark == curMark)
00217     {
00218       fprintf (fp, "key = %2i;  iData = %3i;  fData = %g\n",
00219            data[i].key, data[i].data.iData, data[i].data.fData);
00220     }
00221     }
00222   fprintf (fp, "\n");
00223 END_FUNC_DH}
 All Classes Files Functions Variables Enumerations Friends