While reading a data structure book, I have implemented a chained hash table. I want to share the code with you and get your opinion about it.chained_hash_table.h#ifndef CHAINED_HASH_TABLE_H_INCLUDED#define CHAINED_HASH_TABLE_H_INCLUDED#include <stdlib.h>#include ../linked_list/linked_list.htypedef size_t hkey_t;typedef struct ChainedHashTable_ {    size_t buckets;    List **table;    hkey_t (*hash)(const void *key);    void (*destroy)(void *data);    int (*compare)(const void *fdata, const void *sdata);}ChainedHashTable;ChainedHashTable *chtb_init(size_t buckets,        hkey_t (*hash)(const void *key),        void (*destroy)(void *data),        int (*compare)(const void *fdata, const void *sdata));void chtb_destroy(ChainedHashTable *chtb);int chtb_insert(ChainedHashTable *chtb, void *data);int chtb_remove(ChainedHashTable *chtb, void **data);int chtb_lookup(const ChainedHashTable *chtb, const void *data);#endifchained_hash_table.c#include <string.h>#include chained_hash_table.h#define chtb_hash_key(chtb, data)   chtb->hash(data) % chtb->bucketsChainedHashTable *chtb_init(size_t buckets,        hkey_t (*hash)(const void *key),        void (*destroy)(void *data),        int (*compare)(const void *fdata, const void *sdata)) {    ChainedHashTable *chtb;    if( (chtb = malloc(sizeof *chtb)) != NULL ) {        chtb->buckets = buckets;        chtb->hash = hash;        chtb->destroy = destroy;        chtb->compare = compare;        if( (chtb->table = malloc(buckets * sizeof *chtb->table)) == NULL) {            free(chtb);            return NULL;        }        int i;        for(i = 0; i < buckets; ++i) {            if( (chtb->table[i] = list_init(destroy, compare)) == NULL) {                for(--i; i >= 0; --i)                     free(chtb->table[i]);                free(chtb);                return NULL;            }        }    }    return chtb;}void chtb_destroy(ChainedHashTable *chtb) {    size_t i;    for(i = 0; i < chtb->buckets; ++i)        if(chtb->table[i] != NULL)            list_destroy(chtb->table[i]);    free(chtb->table);    free(chtb);}int chtb_insert(ChainedHashTable *chtb, void *data) {    size_t bucket = chtb_hash_key(chtb, data);     if(list_find(chtb->table[bucket], data) != NULL)        return 1;    if(list_prepend(chtb->table[bucket], data) != 0)        return -1;    return 0;}int chtb_remove(ChainedHashTable *chtb, void **data) {    size_t bucket = chtb_hash_key(chtb, data);     if(chtb->table[bucket] == NULL)        return -1;    return list_remove(chtb->table[bucket], data);}int chtb_lookup(const ChainedHashTable *chtb, const void *data) {    size_t bucket = chtb_hash_key(chtb, data);     return list_find(chtb->table[bucket], data) == NULL ? 0 : 1;}
Chained hash table implementation
c;hash table