Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

mntd_volume_hash.c

00001 /***************************************************************************
00002  * CVSID: $Id: mntd_volume_hash.c,v 1.10 2004/05/26 19:12:40 stefanb Exp $
00003  *
00004  * mntd_volume_hash.c : Volume Manager hash functions for MNT daemon
00005  *
00006  * Copyright (C) 2004 Stefan Bambach, <stefan@bambach.biz>
00007  *
00008  * Licensed under the GNU General Public License 2.0
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  **************************************************************************/
00025  
00026 #ifdef HAVE_CONFIG_H
00027 #  include <config.h>
00028 #endif
00029 
00030 
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <glib.h>
00035 #include "mntd_volume_hash.h"
00036 #include "errmanager.h"
00037 
00038 
00039 /* private prototypes */
00040 PHASHMAPELEMENT new_HashMapElement(PHASHMAP phm, void (*func_free)(void *data), 
00041                                                 const char *key, void *userdata);
00042 void hashmapelement_destroy(PHASHMAPELEMENT phme);
00043 int hashmap_init(PHASHMAP phm);
00044 void hashmap_destroy(PHASHMAP phm);
00045 int hashmap_hash_element(const void *obj);
00046 int hashmap_compare_element(const void *obj1, const void *obj2);
00047 void hashmap_free_element(void *userdata);
00048 
00049 /* public prototypes */
00050 int hashmap_add(PHASHMAP phm, const char *key, void *data);
00051 int hashmap_remove(PHASHMAP phm, const char *key);
00052 int hashmap_size(PHASHMAP phm);
00053 int hashmap_contains(PHASHMAP phm, const char *key);
00054 int hashmap_get(PHASHMAP phm, const char *key, void **userdata);
00055 int hashmap_update(PHASHMAP phm, const char *key, void *userdata);
00056 int hashmap_foreach_call_function(PHASHMAP phm, int (*func)(void *data, void *userdata), void *userdata);
00057 
00058 
00070 PHASHMAPELEMENT 
00071 new_HashMapElement(PHASHMAP phm, void (*func_free)(void *userdata), const char *key, void *userdata)
00072 {
00073     PHASHMAPELEMENT phme = NULL;
00074     
00075     g_assert(phm!=NULL);
00076     g_assert(func_free!=NULL);
00077     g_assert(key!=NULL);
00078     
00079     //MSG_DEBUG("new_HashMapElement('%s', %p) called", key, userdata);
00080     
00081     phme = (PHASHMAPELEMENT) malloc(sizeof(HASHMAPELEMENT));
00082     if (phme == NULL) {
00083         MSG_ERR("Out of memory");
00084         return NULL;
00085     }
00086     
00087     // clear structure
00088     memset(phme, 0, sizeof(HASHMAPELEMENT));
00089     
00090     // initialize data
00091     phme->phm = phm;
00092     phme->key = strdup(key);
00093     phme->userdata = userdata;
00094     
00095     // private methods
00096     phme->destroy = hashmapelement_destroy;
00097     phme->free = func_free;
00098     
00099     //MSG_DEBUG("new_HashMapElement('%s', %p) returned %p", key, userdata, phme);
00100     
00101     // return object
00102     return phme;
00103 }
00104 
00105 
00111 void
00112 hashmapelement_destroy(PHASHMAPELEMENT phme)
00113 {
00114     g_assert(phme!=NULL);
00115     
00116     //MSG_DEBUG("hashmapelement_destroy(%p) called (key='%s', userdata=%p)", phme, phme->key, phme->userdata);
00117 
00118     // free memory for key
00119     if (phme->key != NULL) {
00120         free(phme->key);
00121         phme->key = NULL;
00122     }
00123     
00124     // call user defined functions
00125     if ((phme->free != NULL) && (phme->userdata != NULL)) {
00126         phme->free(phme->userdata);
00127         phme->free = NULL;
00128         phme->userdata = NULL;
00129     }
00130     
00131     // clear structure
00132     memset(phme, 0, sizeof(HASHMAPELEMENT));
00133     free(phme);
00134     phme = NULL;
00135     
00136     return;
00137 }
00138 
00139 
00140 PHASHMAP 
00141 new_HashMap(unsigned int bucket, 
00142     void (*func_free)(void *userdata)
00143     )
00144 {
00145     PHASHMAP phm = NULL;
00146     
00147     phm = (PHASHMAP) malloc(sizeof(HASHMAP));
00148     if (phm == NULL) {
00149         MSG_ERR("Out of memory");
00150         return NULL;
00151     }
00152     
00153     // clear structure
00154     memset(phm, 0, sizeof(HASHMAP));
00155     
00156     // no. of buckets (should be prime num)
00157     if (bucket>0) {
00158         phm->bucket = bucket;
00159     } else {
00160         MSG_INF("bucket not correctly setup. Using %d as default.", DEFAULT_BUCKETS);
00161         phm->bucket = DEFAULT_BUCKETS;
00162     }
00163 
00164     // private methods
00165     phm->init = hashmap_init;
00166     phm->destroy = hashmap_destroy;
00167     // hash, compare, free methods (implemented for each object)
00168     phm->hash = hashmap_hash_element;
00169     phm->compare = hashmap_compare_element;
00170     if (func_free != NULL) {
00171         phm->free = func_free;
00172     } else {
00173         phm->free = hashmap_free_element;
00174     }
00175     // public methods
00176     phm->add = hashmap_add;
00177     phm->remove = hashmap_remove;
00178     phm->size = hashmap_size;
00179     phm->contains = hashmap_contains;
00180     phm->get = hashmap_get;
00181     phm->update = hashmap_update;
00182     phm->foreach = hashmap_foreach_call_function;
00183     
00184     // call constructor
00185     if(phm->init(phm) == -1) {
00186         free(phm);
00187         phm = NULL;
00188     }
00189 
00190     // return object
00191     return phm;
00192 }
00193 
00194 
00201 int
00202 hashmap_init(PHASHMAP phm)
00203 {
00204     CHTbl *htbl = NULL;
00205 
00206     if (phm==NULL) {
00207         return -1;
00208     }
00209     
00210     // get mem for structure
00211     htbl = (CHTbl *) malloc(sizeof(CHTbl));
00212     if (htbl == NULL) {
00213         MSG_ERR("not enough mem for hash table");
00214         return -1;
00215     }
00216     
00217     // initialize table
00218     if (chtbl_init(htbl, phm->bucket, phm->hash, phm->compare, phm->free) != 0) {
00219         MSG_ERR("could not initialize hash table");
00220         if (htbl!=NULL) free(htbl);
00221         return -1;
00222     }
00223     
00224     // store table pointer
00225     phm->hm = htbl;
00226     
00227     // return success
00228     return 0;
00229 }
00230 
00231 
00238 void
00239 hashmap_destroy(PHASHMAP phm)
00240 {
00241     if ((phm==NULL) || ((phm->hm)==NULL)) {
00242         return;
00243     }
00244     
00245     chtbl_destroy(phm->hm);
00246     free(phm->hm);
00247     phm->hm = NULL;
00248     return;
00249 }
00250 
00251 
00258 int
00259 hashmap_hash_element(const void *obj)
00260 {
00261     char *key = NULL;
00262     unsigned int crc = 0;
00263     
00264     if (obj==NULL) {
00265         MSG_EMERG("Hashmap HASH function called with wrong parameter ! (obj=0x%08x)", obj);
00266         return 0;
00267     }
00268     
00269     key = ((PHASHMAPELEMENT)obj)->key;
00270     while(*key!='\0') {
00271         crc += *key++;
00272     }
00273     
00274     return crc;
00275 }
00276 
00277 
00285 int
00286 hashmap_compare_element(const void *obj1, const void *obj2)
00287 {
00288     char *key1 = NULL;
00289     char *key2 = NULL;
00290     int res = 0;
00291     
00292     if ((obj1==NULL) || (obj2==NULL)) {
00293         MSG_EMERG("Hashmap MATCH function called with wrong parameters ! (obj1=0x%08x, obj2=0x%08x)", obj1, obj2);
00294         return 0;
00295     }
00296         
00297     if (obj1==obj2) {
00298         MSG_EMERG("Hashmap MATCH function called with identical parameters ! (obj1=obj2=0x%08x)", obj1);
00299         return 0;
00300     }
00301         
00302     key1 = ((PHASHMAPELEMENT)obj1)->key;
00303     key2 = ((PHASHMAPELEMENT)obj2)->key;
00304 
00305     res = strcmp(key1, key2);
00306 
00307     return res == 0 ? 1 : 0;
00308 }
00309 
00310 
00316 void
00317 hashmap_free_element(void *userdata)
00318 {
00319     if (userdata != NULL) {
00320         MSG_WARNING("You really should set the 'free()' method !");
00321     }
00322     return;
00323 }
00324 
00325 
00335 int
00336 hashmap_add(PHASHMAP phm, const char *key, void *data)
00337 {
00338     PHASHMAPELEMENT phme = NULL;
00339     int retval;
00340     
00341     if ((phm==NULL) || (key==NULL)) {
00342         return -1;
00343     }
00344 
00345     phme = new_HashMapElement(phm, phm->free, key, data);
00346     if (phme == NULL) {
00347         return -1;
00348     }
00349     
00350     retval = chtbl_insert(phm->hm, phme);
00351     
00352     return retval;
00353 }
00354 
00355 
00362 int
00363 hashmap_remove(PHASHMAP phm, const char *key)
00364 {
00365     PHASHMAPELEMENT tmp = NULL;
00366     PHASHMAPELEMENT phme = NULL;
00367     void *chtbl_data = NULL;
00368     int retval;
00369     
00370     if ((phm==NULL) || ((phm->hm)==NULL) || (key==NULL)) {
00371         return -1;
00372     }
00373 
00374     tmp = new_HashMapElement(phm, phm->free, key, NULL);
00375     if (tmp == NULL) {
00376         return -1;
00377     }
00378     
00379     chtbl_data = (void *)tmp;
00380     retval = chtbl_remove(phm->hm, &chtbl_data);
00381     if (retval == 0) {
00382         if (chtbl_data != NULL) {
00383             phme = (PHASHMAPELEMENT)chtbl_data;
00384             if (phme != tmp) {
00385                 if (phme != NULL) {
00386                     phme->destroy(phme);
00387                 }
00388             }
00389         }
00390     }
00391     tmp->destroy(tmp); tmp=NULL;
00392     
00393     return retval;
00394 }
00395 
00396 
00402 int
00403 hashmap_size(PHASHMAP phm)
00404 {
00405     if ((phm==NULL) || ((phm->hm)==NULL)) {
00406         return -1;
00407     }
00408     
00409     return chtbl_size(phm->hm);
00410 }
00411 
00412 
00419 int
00420 hashmap_contains(PHASHMAP phm, const char *key)
00421 {
00422     PHASHMAPELEMENT tmp = NULL;
00423     void *data = NULL;
00424     int retval;
00425     
00426     if ((phm==NULL) || ((phm->hm)==NULL)) {
00427         return 0;
00428     }
00429     
00430     tmp = new_HashMapElement(phm, phm->free, key, NULL);
00431     if (tmp == NULL) {
00432         return 0;
00433     }
00434     
00435     data = (void *)tmp;
00436     retval = chtbl_lookup(phm->hm, &data);
00437     tmp->destroy(tmp); tmp=NULL;
00438     
00439     return (retval==0) ? 1 : 0;
00440 }
00441 
00442 
00450 int
00451 hashmap_get(PHASHMAP phm, const char *key, void **userdata)
00452 {
00453     PHASHMAPELEMENT tmp = NULL;
00454     void *data = NULL;
00455     int retval;
00456     
00457     if ((phm==NULL) || ((phm->hm)==NULL)) {
00458         return -1;
00459     }
00460     
00461     tmp = new_HashMapElement(phm, phm->free, key, NULL);
00462     if (tmp == NULL) {
00463         return -1;
00464     }
00465     
00466     data = (void *)tmp;
00467     retval = chtbl_lookup(phm->hm, &data);
00468     tmp->destroy(tmp); tmp=NULL;
00469     
00470     if (retval != 0) {
00471         *userdata = NULL;
00472         return -1;
00473     }
00474     
00475     // return data
00476     *userdata = ((PHASHMAPELEMENT)data)->userdata;
00477     return 0;
00478 }
00479 
00480 
00488 int
00489 hashmap_update(PHASHMAP phm, const char *key, void *userdata)
00490 {
00491     PHASHMAPELEMENT tmp = NULL;
00492     PHASHMAPELEMENT phme = NULL;
00493     void *data = NULL;
00494     int retval;
00495     
00496     if ((phm==NULL) || (key==NULL)) {
00497         return -1;
00498     }
00499 
00500     if (phm->contains(phm, key)) {
00501         tmp = new_HashMapElement(phm, phm->free, key, NULL);
00502         if (tmp == NULL) {
00503             return -1;
00504         }
00505     
00506         data = (void *)tmp;
00507         retval = chtbl_lookup(phm->hm, &data);
00508         tmp->destroy(tmp); tmp=NULL;
00509         
00510         if (retval == 0) {
00511             phme = (PHASHMAPELEMENT)data;
00512             if (phme != NULL) {
00513                 phme->free(phme->userdata);
00514                 phme->userdata = userdata;
00515             }
00516         }
00517     }
00518     
00519     return -1;
00520 }
00521 
00522 
00530 int
00531 hashmap_foreach_call_function(PHASHMAP phm, 
00532     int (*func)(void *data, void *userdata), 
00533    void *userdata)
00534 {
00535     int i=0;
00536     
00537     if ((phm==NULL) || (func==NULL) || (phm->hm==NULL)) {
00538         return -1;
00539     }
00540 
00541     for (i=0; i<phm->hm->buckets; i++) {
00542         list_for_each_call(&phm->hm->table[i], func, userdata);
00543     }
00544     
00545     return 0;
00546 }

Generated on Thu May 27 23:27:28 2004 for Mntd by doxygen 1.3.5