/* evtgen string hash functions. Copyright (C) 2003 Julien Olivain and LSV, CNRS UMR 8643 & ENS Cachan. This file is part of evtgen. evtgen is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. evtgen is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with evtgen; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Copyright (C) 2004 Tommi Rantala * * Modified for usage in Pacman. */ /* ** strhash.c -- string hash utility functions */ #include #include #include #include "util.h" #include "list.h" #include "strhash.h" void strhash_add_list(strhash_t *hash, PMList* list) { for(; list; list = list->next) { strhash_add(hash, list->data, NULL); } } strhash_t* new_strhash(size_t hsize) { strhash_t *h; MALLOC(h, sizeof(strhash_t)); h->size = hsize; h->elmts = 0; h->hash = DEFAULT_STRHASH_FUNCTION; MALLOC(h->htable, hsize * sizeof(strhash_elmt_t *)); memset(h->htable, 0, hsize * sizeof(strhash_elmt_t *)); return(h); } void clear_strhash(strhash_t *hash) { int i; strhash_elmt_t *tmp; strhash_elmt_t *tmp_next; for(i = 0; i < hash->size; i++) { tmp = hash->htable[i]; while(tmp) { tmp_next = tmp->next; free(tmp); tmp = tmp_next; } } hash->elmts = 0; memset(hash->htable, 0, hash->size * sizeof(void *)); } void free_strhash(strhash_t *hash) { int i; strhash_elmt_t *tmp; strhash_elmt_t *tmp_next; for(i = 0; i < hash->size; i++) { tmp = hash->htable[i]; while(tmp) { tmp_next = tmp->next; free(tmp); tmp = tmp_next; } } free(hash->htable); free(hash); } void strhash_add(strhash_t *hash, char *key, char *data) { strhash_elmt_t *elmt; unsigned long hcode; MALLOC(elmt, sizeof(strhash_elmt_t)); elmt->key = key; elmt->data = data; hcode = hash->hash(key) % hash->size; elmt->next = hash->htable[hcode]; hash->htable[hcode] = elmt; hash->elmts++; } void strhash_remove(strhash_t *hash, char *key) { unsigned long hcode; strhash_elmt_t *elmt; strhash_elmt_t *prev = NULL; hcode = hash->hash(key) % hash->size; elmt = hash->htable[hcode]; for(; elmt; elmt = elmt->next) { if(!strcmp(key, elmt->key)) { if(prev) { prev->next = elmt->next; } else { hash->htable[hcode] = elmt->next; } FREE(elmt); return; } prev = elmt; } } /* 1: Yes, the key exists in the hash table. * 0: No, it's not here. */ int strhash_isin(strhash_t *hash, char* key) { strhash_elmt_t *elmt; elmt = hash->htable[hash->hash(key) % hash->size]; for(; elmt; elmt = elmt->next) { if(!strcmp(key, elmt->key)) { return 1; } } return 0; } char* strhash_get(strhash_t *hash, char* key) { strhash_elmt_t *elmt; elmt = hash->htable[hash->hash(key) % hash->size]; for(; elmt; elmt = elmt->next) { if(!strcmp(key, elmt->key)) { return elmt->data; } } return NULL; } /* ** fast hash function samples */ unsigned long strhash_pjw(char *key) { unsigned long h; unsigned long g; h = 0; while(*key) { h = (h << 4) + *key++; if((g = h & 0xF0000000U) != 0) { h = h ^ (g >> 24); h = h ^ g; } } return (h); } int strhash_collide_count(strhash_t *hash) { int count; int i; count = 0; for(i = 0; i < hash->size; i++) { strhash_elmt_t *tmp; for(tmp = hash->htable[i]; tmp; tmp = tmp->next) { if(tmp->next) { count++; } } } return(count); }