• Main Page
  • Modules
  • Data Structures
  • Files
  • File List

D:/Perso/dev/ocilib/ocilib/src/hash.c

00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2010 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: hash.c, v 3.8.0 2010-10-24 21:53 Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_HashCompute
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 unsigned int OCI_HashCompute
00046 (
00047     OCI_HashTable *table,
00048     const mtext   *str
00049 )
00050 {
00051     unsigned int h;
00052     mtext *p;
00053     mtext c;
00054 
00055     OCI_CHECK(table == NULL, 0);
00056     OCI_CHECK(str   == NULL, 0);
00057 
00058     for(h = 0, p = (mtext *) str; (*p) != 0; p++)
00059     {
00060         c = *p;
00061 
00062         h = 31 * h + mttoupper(c);
00063     }
00064 
00065     return (h % table->size);
00066 }
00067 
00068 /* ********************************************************************************************* *
00069  *                            PUBLIC FUNCTIONS
00070  * ********************************************************************************************* */
00071 
00072 /* --------------------------------------------------------------------------------------------- *
00073  * OCI_HashCreate
00074  * --------------------------------------------------------------------------------------------- */
00075 
00076 OCI_HashTable * OCI_API OCI_HashCreate
00077 (
00078     unsigned int size,
00079     unsigned int type
00080 )
00081 {
00082     OCI_HashTable *table = NULL;
00083     boolean res          = TRUE;
00084 
00085     /* allocate table structure */
00086 
00087     table = (OCI_HashTable *) OCI_MemAlloc(OCI_IPC_HASHTABLE, sizeof(*table),
00088                                            (size_t) 1, TRUE);
00089 
00090     /* set up attributes and allocate internal array of hash entry pointers */
00091 
00092     if (table != NULL)
00093     {
00094         table->size  = size;
00095         table->type  = type;
00096         table->count = 0;
00097 
00098         table->items = (OCI_HashEntry **) OCI_MemAlloc(OCI_IPC_HASHENTRY_ARRAY,
00099                                                        sizeof(*table->items),
00100                                                        (size_t) size, TRUE);
00101         res = (table->items != NULL);
00102     }
00103     else
00104         res = FALSE;
00105 
00106     if (res == FALSE)
00107         OCI_HashFree(table);
00108 
00109     OCI_RESULT(res);
00110 
00111     return table;
00112 }
00113 
00114 /* --------------------------------------------------------------------------------------------- *
00115  * OCI_HashFree
00116  * --------------------------------------------------------------------------------------------- */
00117 
00118 boolean OCI_API OCI_HashFree
00119 (
00120     OCI_HashTable *table
00121 )
00122 {
00123     unsigned int i;
00124 
00125     OCI_HashEntry *e1, *e2;
00126     OCI_HashValue *v1, *v2;
00127 
00128     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE);
00129 
00130     for (i = 0; i < table->size; i++)
00131     {
00132         e1 = table->items[i];
00133 
00134         while (e1 != NULL)
00135         {
00136             e2 = e1;
00137             e1 = e1->next;
00138 
00139             v1 = e2->values;
00140 
00141             while (v1 != NULL)
00142             {
00143                 v2 = v1;
00144                 v1 = v1->next;
00145 
00146                 if (table->type == OCI_HASH_STRING)
00147                     OCI_FREE(v2->value.p_mtext);
00148 
00149                 OCI_FREE(v2);
00150             }
00151 
00152             if (e2->key)
00153                 OCI_FREE(e2->key);
00154 
00155             if (e2)
00156                 OCI_FREE(e2);
00157         }
00158     }
00159 
00160     if (table->items != NULL)
00161     {
00162         OCI_FREE(table->items);
00163     }
00164 
00165     OCI_FREE(table);
00166 
00167     OCI_RESULT(TRUE);
00168 
00169     return TRUE;
00170 }
00171 
00172 /* --------------------------------------------------------------------------------------------- *
00173  * OCI_HashGetSize
00174  * --------------------------------------------------------------------------------------------- */
00175 
00176 unsigned int OCI_API OCI_HashGetSize
00177 (
00178     OCI_HashTable *table
00179 )
00180 {
00181     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, 0);
00182 
00183     OCI_RESULT(TRUE);
00184 
00185     return table->size;
00186 }
00187 
00188 /* --------------------------------------------------------------------------------------------- *
00189  * OCI_HashGetType
00190  * --------------------------------------------------------------------------------------------- */
00191 
00192 unsigned int OCI_API OCI_HashGetType
00193 (
00194     OCI_HashTable *table
00195 )
00196 {
00197     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, OCI_UNKNOWN);
00198 
00199     OCI_RESULT(TRUE);
00200 
00201     return table->type;
00202 }
00203 
00204 /* --------------------------------------------------------------------------------------------- *
00205  * OCI_HashGetValue
00206  * --------------------------------------------------------------------------------------------- */
00207 
00208 OCI_HashValue * OCI_API OCI_HashGetValue
00209 (
00210     OCI_HashTable *table,
00211     const mtext   *key
00212 )
00213 {
00214     OCI_HashEntry *e = NULL;
00215     OCI_HashValue *v = NULL;
00216 
00217     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00218 
00219     e = OCI_HashLookup(table, key, FALSE);
00220 
00221     if (e != NULL)
00222         v = e->values;
00223 
00224     OCI_RESULT(v != NULL);
00225 
00226     return v;
00227 }
00228 
00229 /* --------------------------------------------------------------------------------------------- *
00230  * OCI_HashGetEntry
00231  * --------------------------------------------------------------------------------------------- */
00232 
00233 OCI_HashEntry * OCI_API OCI_HashGetEntry
00234 (
00235     OCI_HashTable *table,
00236     unsigned int   index
00237 )
00238 {
00239     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00240     OCI_CHECK_BOUND(NULL, index, 1, table->size, NULL);
00241 
00242     OCI_RESULT(TRUE);
00243 
00244     return table->items[index];
00245 }
00246 
00247 /* --------------------------------------------------------------------------------------------- *
00248  * OCI_HashGetString
00249  * --------------------------------------------------------------------------------------------- */
00250 
00251 const mtext * OCI_API OCI_HashGetString
00252 (
00253     OCI_HashTable *table,
00254     const mtext   *key
00255 )
00256 {
00257     OCI_HashValue *v   = NULL;
00258     const mtext *value = NULL;
00259 
00260     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00261     OCI_CHECK(table->type != OCI_HASH_STRING, NULL);
00262 
00263     v = OCI_HashGetValue(table, key);
00264 
00265     if (v != NULL)
00266     {
00267         value = v->value.p_mtext;
00268     }
00269 
00270     OCI_RESULT(v != NULL);
00271 
00272     return value;
00273 }
00274 
00275 /* --------------------------------------------------------------------------------------------- *
00276  * OCI_HashGetInt
00277  * --------------------------------------------------------------------------------------------- */
00278 
00279 int OCI_API OCI_HashGetInt
00280 (
00281     OCI_HashTable *table,
00282     const mtext   *key
00283 )
00284 {
00285     OCI_HashValue *v = NULL;
00286     int value        = 0;
00287 
00288     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, 0);
00289     OCI_CHECK(table->type != OCI_HASH_INTEGER, 0);
00290 
00291     v = OCI_HashGetValue(table, key);
00292 
00293     if (v != NULL)
00294     {
00295         value = v->value.num;
00296     }
00297 
00298     OCI_RESULT(v != NULL);
00299 
00300     return value;
00301 }
00302 
00303 /* --------------------------------------------------------------------------------------------- *
00304  * OCI_HashGetPointer
00305  * --------------------------------------------------------------------------------------------- */
00306 
00307 void * OCI_API OCI_HashGetPointer
00308 (
00309     OCI_HashTable *table,
00310     const mtext   *key
00311 )
00312 {
00313     OCI_HashValue *v = NULL;
00314     void *value      = NULL;
00315 
00316     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00317     OCI_CHECK(table->type != OCI_HASH_POINTER, NULL);
00318 
00319     v = OCI_HashGetValue(table, key);
00320 
00321     if (v != NULL)
00322     {
00323         value = v->value.p_void;
00324     }
00325 
00326     OCI_RESULT(v != NULL);
00327 
00328     return value;
00329 }
00330 
00331 /* --------------------------------------------------------------------------------------------- *
00332  * OCI_HashAdd
00333  * --------------------------------------------------------------------------------------------- */
00334 
00335 boolean OCI_HashAdd
00336 (
00337     OCI_HashTable *table,
00338     const mtext   *key,
00339     OCI_Variant    value,
00340     unsigned int   type
00341 )
00342 {
00343     OCI_HashEntry * e = NULL;
00344     OCI_HashValue * v = NULL, *v1 = NULL, *v2 = NULL;
00345 
00346     OCI_CHECK(table == NULL, FALSE);
00347     OCI_CHECK(key   == NULL, FALSE);
00348     OCI_CHECK(table->type != type, FALSE);
00349 
00350     e = OCI_HashLookup(table, key, TRUE);
00351 
00352     if (e != NULL)
00353     {
00354         v = (OCI_HashValue *) OCI_MemAlloc(OCI_IPC_HASHVALUE, sizeof(*v),
00355                                            (size_t) 1, TRUE);
00356 
00357         if (v != NULL)
00358         {
00359             if (table->type == OCI_HASH_STRING && value.p_mtext != NULL)
00360             {
00361                 v->value.p_mtext = mtsdup(value.p_mtext);
00362             }
00363             else if (table->type == OCI_HASH_INTEGER)
00364             {
00365                 v->value.num = value.num;
00366             }
00367             else
00368                 v->value.p_void = value.p_void;
00369 
00370             v1 = v2 = e->values;
00371 
00372             while (v1 != NULL)
00373             {
00374                 v2 = v1;
00375                 v1 = v1->next;
00376             }
00377 
00378             if (v2 != NULL)
00379                 v2->next = v;
00380             else
00381                 e->values = v;
00382         }
00383     }
00384 
00385     return (v != NULL);
00386 }
00387 
00388 /* --------------------------------------------------------------------------------------------- *
00389  * OCI_HashAddString
00390  * --------------------------------------------------------------------------------------------- */
00391 
00392 boolean OCI_API OCI_HashAddString
00393 (
00394     OCI_HashTable *table,
00395     const mtext   *key,
00396     const mtext   *value
00397 )
00398 {
00399     boolean res = TRUE;
00400     OCI_Variant v;
00401 
00402     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE);
00403 
00404     v.p_mtext = (mtext *) value;
00405 
00406     res = OCI_HashAdd(table, key, v, OCI_HASH_STRING);
00407 
00408     OCI_RESULT(res);
00409 
00410     return res;
00411 }
00412 
00413 /* --------------------------------------------------------------------------------------------- *
00414  * OCI_HashAddInt
00415  * --------------------------------------------------------------------------------------------- */
00416 
00417 boolean OCI_API OCI_HashAddInt
00418 (
00419     OCI_HashTable *table,
00420     const mtext   *key,
00421     int            value
00422 )
00423 {
00424     boolean res = TRUE;
00425     OCI_Variant v;
00426 
00427     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE);
00428 
00429     v.num = value;
00430 
00431     res = OCI_HashAdd(table, key, v, OCI_HASH_INTEGER);
00432 
00433     OCI_RESULT(res);
00434 
00435     return res;
00436 }
00437 
00438 /* --------------------------------------------------------------------------------------------- *
00439  * OCI_HashAddPointer
00440  * --------------------------------------------------------------------------------------------- */
00441 
00442 boolean OCI_API OCI_HashAddPointer
00443 (
00444     OCI_HashTable *table,
00445     const mtext   *key,
00446     void          *value
00447 )
00448 {
00449     boolean res = TRUE;
00450     OCI_Variant v;
00451 
00452     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE);
00453 
00454     v.p_void = value;
00455 
00456     res = OCI_HashAdd(table, key, v, OCI_HASH_POINTER);
00457 
00458     OCI_RESULT(res);
00459 
00460     return res;
00461 }
00462 
00463 /* --------------------------------------------------------------------------------------------- *
00464  * OCI_HashLookup
00465  * --------------------------------------------------------------------------------------------- */
00466 
00467 OCI_HashEntry * OCI_API OCI_HashLookup
00468 (
00469     OCI_HashTable *table,
00470     const mtext   *key,
00471     boolean        create
00472 )
00473 {
00474     OCI_HashEntry *e = NULL, *e1 = NULL, *e2 = NULL;
00475     unsigned int i;
00476 
00477     OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00478     OCI_CHECK_PTR(OCI_IPC_STRING, key, NULL);
00479 
00480     i = OCI_HashCompute(table, key);
00481 
00482     if (i < table->size)
00483     {
00484         for(e = table->items[i]; e != NULL; e = e->next)
00485         {
00486             if (mtscasecmp(e->key, key) == 0)
00487                 break;
00488         }
00489 
00490         if ((e == NULL) && (create == TRUE))
00491         {
00492             e = (OCI_HashEntry *) OCI_MemAlloc(OCI_IPC_HASHENTRY, sizeof(*e),
00493                                                (size_t) 1, TRUE);
00494 
00495             if (e != NULL)
00496             {
00497                 e->key = mtsdup(key);
00498 
00499                 e1 = e2 = table->items[i];
00500 
00501                 while (e1 != NULL)
00502                 {
00503                     e2 = e1;
00504                     e1 = e1->next;
00505                 }
00506 
00507                 if (e2 != NULL)
00508                     e2->next = e;
00509                 else
00510                     table->items[i] = e;
00511             }
00512         }
00513     }
00514 
00515     OCI_RESULT(e != NULL);
00516 
00517     return e;
00518 }

Generated on Sun Oct 24 2010 22:02:54 for OCILIB (C Driver for Oracle) by  doxygen 1.7.1