#include #include #include #include #include "hash.h" #include "defs.h" int h_malloc(struct hash_table *htable, size_t el_size, size_t n, unsigned long (*func)(const void *, const unsigned long), int (*c)(const void *, const void*)) { /* We use size of table... */ size_t size = el_size*n; size_t i=0; if(size == 0) return YACL_EBADSIZE; /* Check if we got correct parameters. first we check if pointer to hash function points somewhere... and then if pointer to comparison function points somewhere... */ if(func == NULL) return YACL_EFAILED; htable->hash_func = func; if(c == NULL) return YACL_EFAILED; htable->comp = c; /* We get memory from heap... */ htable->table =(yacl_list *)malloc(size); #ifdef DEBUG fprintf(stderr, "hash table malloc - size %d", size); #endif /* Check if we have enough memory... */ if(htable->table == NULL) return YACL_ENOTMEM; /* Now we init table... */ for(i=0; itable[i].data = NULL; htable->table[i].next = NULL; } htable->el_size = el_size; htable->elements = 0; htable->size = n; return YACL_SUCCESS; } void h_free(struct hash_table *htable) { size_t i; /* Data corretion checks... */ assert(htable!=NULL); /* Zwalniamy pamięć przydzieloną poszczególnym elementom tablicy. */ for(i=0; isize; i++) { if(htable->table[i].data != NULL) { free(htable->table[i].data); } if(htable->table[i].next != NULL) { l_free(&htable->table[i].next); } } /* Zwalniamy pamięć przydzieloną tablicy. */ free(htable->table); #ifdef DEBUG fprintf(stderr, "hash table free - size %d", size); #endif htable->table = NULL; htable->size = 0; htable->elements =0; } int h_addElem(struct hash_table *htable, const void *data) { unsigned long index = 0; assert(htable!=NULL); assert(htable->size!=0); assert(htable->hash_func!=NULL); assert(htable->comp!=NULL); /* Obliczamy indeks wstawianego elementu */ index = (*(htable->hash_func))(data, htable->size); /* Sprawdzamy czy zarezerwowano miejsce */ if(htable->table == NULL) return YACL_EFAILED; /* Wstawiamy element do tablicy. Jeśli nie synonimów to wstawiamy bezpośrednio do tablicy. Jeśli są to wstawiamy na koniec listy. */ if(htable->table[index].data == NULL) { htable->table[index].data = malloc(htable->el_size); if(htable->table[index].data == NULL) return YACL_EFAILED; memcpy(htable->table[index].data, data, htable->el_size); htable->elements++; return YACL_SUCCESS; } else { if((*(htable->comp))(htable->table[index].data, data) == 0) return YACL_EFAILED; if(l_findElem(htable->table[index].next, data, htable->comp) != NULL ) return YACL_EFAILED; switch(l_insertEnd(&(htable->table[index]), data, htable->el_size)) { case YACL_SUCCESS: htable->elements++; return YACL_SUCCESS; default: return YACL_EFAILED; } } } yacl_list *h_findElem(const struct hash_table *htable, const void *data) { unsigned long index; assert(htable!=NULL); assert(htable->hash_func!=NULL); assert(htable->comp!=NULL); assert(htable->size!=0); /* Obliczamy indeks szukanego elementu. */ index = (*htable->hash_func)(data, htable->size); /* Sprawdzamy czy znajduje się w tablicy lub na liście synonimów. */ if(htable->table[index].data == NULL) return NULL; if((*htable->comp)(htable->table[index].data, data) == 0) return &htable->table[index]; else return l_findElem(htable->table[index].next, data, htable->comp); }