Blender  V2.59
BLI_ghash.c
Go to the documentation of this file.
00001 /*
00002  * $Id: BLI_ghash.c 36276 2011-04-21 15:53:30Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  * A general (pointer -> pointer) hash table ADT
00029  */
00030 
00036 #include "MEM_guardedalloc.h"
00037 
00038 #include "BLI_utildefines.h"
00039 #include "BLI_ghash.h"
00040 #include "BLO_sys_types.h" // for intptr_t support
00041 /***/
00042 
00043 unsigned int hashsizes[]= {
00044         5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, 
00045         16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, 
00046         4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 
00047         268435459
00048 };
00049 
00050 /***/
00051 
00052 /***/
00053 
00054 GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) {
00055         GHash *gh= MEM_mallocN(sizeof(*gh), info);
00056         gh->hashfp= hashfp;
00057         gh->cmpfp= cmpfp;
00058         gh->entrypool = BLI_mempool_create(sizeof(Entry), 64, 64, 0);
00059 
00060         gh->cursize= 0;
00061         gh->nentries= 0;
00062         gh->nbuckets= hashsizes[gh->cursize];
00063         
00064         gh->buckets= MEM_mallocN(gh->nbuckets*sizeof(*gh->buckets), "buckets");
00065         memset(gh->buckets, 0, gh->nbuckets*sizeof(*gh->buckets));
00066         
00067         return gh;
00068 }
00069 
00070 #ifdef BLI_ghash_insert
00071 #undef BLI_ghash_insert
00072 #endif
00073 
00074 int BLI_ghash_size(GHash *gh) {
00075         return gh->nentries;
00076 }
00077 
00078 void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) {
00079         int i;
00080         
00081         if (keyfreefp || valfreefp) {
00082                 for (i=0; i<gh->nbuckets; i++) {
00083                         Entry *e;
00084                         
00085                         for (e= gh->buckets[i]; e; ) {
00086                                 Entry *n= e->next;
00087                                 
00088                                 if (keyfreefp) keyfreefp(e->key);
00089                                 if (valfreefp) valfreefp(e->val);
00090 
00091                                 e= n;
00092                         }
00093                 }
00094         }
00095         
00096         MEM_freeN(gh->buckets);
00097         BLI_mempool_destroy(gh->entrypool);
00098         gh->buckets = NULL;
00099         gh->nentries = 0;
00100         gh->nbuckets = 0;
00101         MEM_freeN(gh);
00102 }
00103 
00104 /***/
00105 
00106 GHashIterator *BLI_ghashIterator_new(GHash *gh) {
00107         GHashIterator *ghi= MEM_mallocN(sizeof(*ghi), "ghash iterator");
00108         ghi->gh= gh;
00109         ghi->curEntry= NULL;
00110         ghi->curBucket= -1;
00111         while (!ghi->curEntry) {
00112                 ghi->curBucket++;
00113                 if (ghi->curBucket==ghi->gh->nbuckets)
00114                         break;
00115                 ghi->curEntry= ghi->gh->buckets[ghi->curBucket];
00116         }
00117         return ghi;
00118 }
00119 void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh) {
00120         ghi->gh= gh;
00121         ghi->curEntry= NULL;
00122         ghi->curBucket= -1;
00123         while (!ghi->curEntry) {
00124                 ghi->curBucket++;
00125                 if (ghi->curBucket==ghi->gh->nbuckets)
00126                         break;
00127                 ghi->curEntry= ghi->gh->buckets[ghi->curBucket];
00128         }
00129 }
00130 void BLI_ghashIterator_free(GHashIterator *ghi) {
00131         MEM_freeN(ghi);
00132 }
00133 
00134 void *BLI_ghashIterator_getKey(GHashIterator *ghi) {
00135         return ghi->curEntry?ghi->curEntry->key:NULL;
00136 }
00137 void *BLI_ghashIterator_getValue(GHashIterator *ghi) {
00138         return ghi->curEntry?ghi->curEntry->val:NULL;
00139 }
00140 
00141 void BLI_ghashIterator_step(GHashIterator *ghi) {
00142         if (ghi->curEntry) {
00143                 ghi->curEntry= ghi->curEntry->next;
00144                 while (!ghi->curEntry) {
00145                         ghi->curBucket++;
00146                         if (ghi->curBucket==ghi->gh->nbuckets)
00147                                 break;
00148                         ghi->curEntry= ghi->gh->buckets[ghi->curBucket];
00149                 }
00150         }
00151 }
00152 int BLI_ghashIterator_isDone(GHashIterator *ghi) {
00153         return !ghi->curEntry;
00154 }
00155 
00156 /***/
00157 
00158 unsigned int BLI_ghashutil_ptrhash(const void *key) {
00159         return (unsigned int)(intptr_t)key;
00160 }
00161 int BLI_ghashutil_ptrcmp(const void *a, const void *b) {
00162         if (a==b)
00163                 return 0;
00164         else
00165                 return (a<b)?-1:1;
00166 }
00167 
00168 unsigned int BLI_ghashutil_inthash(const void *ptr) {
00169         uintptr_t key = (uintptr_t)ptr;
00170 
00171         key += ~(key << 16);
00172         key ^=  (key >>  5);
00173         key +=  (key <<  3);
00174         key ^=  (key >> 13);
00175         key += ~(key <<  9);
00176         key ^=  (key >> 17);
00177 
00178         return (unsigned int)(key & 0xffffffff);
00179 }
00180 
00181 int BLI_ghashutil_intcmp(const void *a, const void *b) {
00182         if (a==b)
00183                 return 0;
00184         else
00185                 return (a<b)?-1:1;
00186 }
00187 
00188 unsigned int BLI_ghashutil_strhash(const void *ptr) {
00189         const char *s= ptr;
00190         unsigned int i= 0;
00191         unsigned char c;
00192         
00193         while ( (c= *s++) )
00194                 i= i*37 + c;
00195                 
00196         return i;
00197 }
00198 int BLI_ghashutil_strcmp(const void *a, const void *b) {
00199         return strcmp(a, b);
00200 }