Question

Hashtable in C Please fix void ht_put(hashtable_t *ht, char *key, void *val) and void free_hashtable(hashtable_t *ht)...

Hashtable in C

Please fix void ht_put(hashtable_t *ht, char *key, void *val) and void free_hashtable(hashtable_t *ht)

Implement void ht_del(hashtable_t *ht, char *key) and void ht_rehash(hashtable_t *ht, unsigned long newsize)

--------------[hashtable.h]---------------------------------------

-#########################################

#ifndef HASHTABLE_T

#define HASHTABLE_T

typedef struct hashtable hashtable_t;

typedef struct bucket bucket_t;

struct bucket {

char *key;

void *val;

bucket_t *next;

};

struct hashtable {

unsigned long size;

bucket_t **buckets;

};

unsigned long hash(char *str);

hashtable_t *make_hashtable(unsigned long size);

void ht_put(hashtable_t *ht, char *key, void *val);

void *ht_get(hashtable_t *ht, char *key);

void ht_del(hashtable_t *ht, char *key);

void ht_iter(hashtable_t *ht, int (*f)(char *, void *));

void ht_rehash(hashtable_t *ht, unsigned long newsize);

void free_hashtable(hashtable_t *ht);

#endif

-------------------------------------------------

----------------------[hashtable.c]--------------------------

--------------------------------------------------

##################################

#include

#include

#include "hashtable.h"

unsigned long hash(char *str) {

unsigned long hash = 5381;

int c;

while ((c = *str++))

hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

return hash;

}

hashtable_t *make_hashtable(unsigned long size) {

hashtable_t *ht = malloc(sizeof(hashtable_t));

ht->size = size;

ht->buckets = calloc(sizeof(bucket_t *), size);

return ht;

}

void ht_put(hashtable_t *ht, char *key, void *val) {

/* FIXME: the current implementation doesn't update existing entries */

unsigned int idx = hash(key) % ht->size;

bucket_t *b = malloc(sizeof(bucket_t));

b->key = key;

b->val = val;

b->next = ht->buckets[idx];

ht->buckets[idx] = b;

}

void *ht_get(hashtable_t *ht, char *key) {

unsigned int idx = hash(key) % ht->size;

bucket_t *b = ht->buckets[idx];

while (b) {

if (strcmp(b->key, key) == 0) {

return b->val;

}

b = b->next;

}

return NULL;

}

void ht_iter(hashtable_t *ht, int (*f)(char *, void *)) {

bucket_t *b;

unsigned long i;

for (i=0; isize; i++) {

b = ht->buckets[i];

while (b) {

if (!f(b->key, b->val)) {

return ; // abort iteration

}

b = b->next;

}

}

}

void free_hashtable(hashtable_t *ht) {

free(ht); // FIXME: must free all substructures!

}

/* TODO */

void ht_del(hashtable_t *ht, char *key) {

}

void ht_rehash(hashtable_t *ht, unsigned long newsize) {

}

0 0
Add a comment Improve this question Transcribed image text
Answer #1

#include <stdlib.h>
#include <string.h>


typedef struct hash_elem_t {
   struct hash_elem_t* next;
   void* data;  
   char key[];   
} hash_elem_t;


typedef struct {
   unsigned int capacity;  
   unsigned int e_num;  
   hash_elem_t** table;  
} hashtable_t;

typedef struct {
   hashtable_t* ht;   
   unsigned int index;  
   hash_elem_t* elem;   
} hash_elem_it;

#define HT_ITERATOR(ht) {ht, 0, ht->table[0]}

char err_ptr;
void* HT_ERROR = &err_ptr;

static unsigned int ht_calc_hash(char* key)
{
   unsigned int h = 5381;
   while(*(key++))
       h = ((h << 5) + h) + (*key);
   return h;
}

hashtable_t* ht_create(unsigned int capacity)
{
   hashtable_t* hasht = malloc(sizeof(hashtable_t));
   if(!hasht)
       return NULL;
   if((hasht->table = malloc(capacity*sizeof(hash_elem_t*))) == NULL)
   {
       free(hasht->table);
       return NULL;
   }
   hasht->capacity = capacity;
   hasht->e_num = 0;
   unsigned int i;
   for(i = 0; i < capacity; i++)
       hasht->table[i] = NULL;
   return hasht;
}

void* ht_put(hashtable_t* hasht, char* key, void* data)
{
   if(data == NULL)
       return NULL;
   unsigned int h = ht_calc_hash(key) % hasht->capacity;
   hash_elem_t* e = hasht->table[h];

   while(e != NULL)
   {
       if(!strcmp(e->key, key))
       {
           void* ret = e->data;
           e->data = data;
           return ret;
       }
       e = e->next;
   }

   if((e = malloc(sizeof(hash_elem_t)+strlen(key)+1)) == NULL)
       return HT_ERROR;
   strcpy(e->key, key);
   e->data = data;

   e->next = hasht->table[h];
   hasht->table[h] = e;
   hasht->e_num ++;

   return NULL;
}

void* ht_get(hashtable_t* hasht, char* key)
{
   unsigned int h = ht_calc_hash(key) % hasht->capacity;
   hash_elem_t* e = hasht->table[h];
   while(e != NULL)
   {
       if(!strcmp(e->key, key))
           return e->data;
       e = e->next;
   }
   return NULL;
}

void* ht_remove(hashtable_t* hasht, char* key)
{
   unsigned int h = ht_calc_hash(key) % hasht->capacity;
   hash_elem_t* e = hasht->table[h];
   hash_elem_t* prev = NULL;
   while(e != NULL)
   {
       if(!strcmp(e->key, key))
       {
           void* ret = e->data;
           if(prev != NULL)
               prev->next = e->next;
           else
               hasht->table[h] = e->next;
           free(e);
           e = NULL;
           hasht->e_num --;
           return ret;
       }
       prev = e;
       e = e->next;
   }
   return NULL;
}

void ht_list_keys(hashtable_t* hasht, char** k, size_t len)
{
   if(len < hasht->e_num)
       return;
   int ki = 0;
   int i = hasht->capacity;
   while(--i >= 0)
   {
       hash_elem_t* e = hasht->table[i];
       while(e)
       {
           k[ki++] = e->key;
           e = e->next;
       }
   }
}

void ht_list_values(hashtable_t* hasht, void** v, size_t len)
{
   if(len < hasht->e_num)
       return;
   int vi = 0;
   int i = hasht->capacity;
   while(--i >= 0)
   {
       hash_elem_t* e = hasht->table[i];
       while(e)
       {
           v[vi++] = e->data;
           e = e->next;
       }
   }
}

hash_elem_t* ht_iterate(hash_elem_it* iterator)
{
   while(iterator->elem == NULL)
   {
       if(iterator->index < iterator->ht->capacity - 1)
       {
           iterator->index++;
           iterator->elem = iterator->ht->table[iterator->index];
       }
       else
           return NULL;
   }
   hash_elem_t* e = iterator->elem;
   if(e)
       iterator->elem = e->next;
   return e;
}

char* ht_iterate_keys(hash_elem_it* iterator)
{
   hash_elem_t* e = ht_iterate(iterator);
   return (e == NULL ? NULL : e->key);
}

void* ht_iterate_values(hash_elem_it* iterator)
{
   hash_elem_t* e = ht_iterate(iterator);
   return (e == NULL ? NULL : e->data);
}


void ht_clear(hashtable_t* hasht, int free_data)
{
   hash_elem_it it = HT_ITERATOR(hasht);
   char* k = ht_iterate_keys(&it);
   while(k != NULL)
   {
       free_data ? free(ht_remove(hasht, k)) : ht_remove(hasht, k);
       k = ht_iterate_keys(&it);
   }
}

void ht_destroy(hashtable_t* hasht)
{
   ht_clear(hasht, 1);
   free(hasht->table);
   free(hasht);
}

#ifdef TEST_HASHTABLE
#include <stdio.h>

int main()
{
   hashtable_t *ht = ht_create(1024);
   ht_put(ht, "foo", "bar");
   printf("%s\n", (char*)ht_get(ht, "foo"));
   ht_put(ht, "foo", "rab");
   printf("%s\n", (char*)ht_get(ht, "foo"));
   ht_remove(ht, "foo");
   if(!ht_get(ht, "foo"))
       printf("foo removed\n");

   ht_put(ht, "foo", "bar");
   ht_put(ht, "toto", "titi");

   printf("Listing keys\n");
   char* str[ht->e_num];
   unsigned int i;
   ht_list_keys(ht, str, ht->e_num);
   for(i = 0; i < ht->e_num; i++)
       printf("%s\n", str[i]);
  
   printf("Listing values\n");
   ht_list_values(ht, (void**)str, ht->e_num);
   for(i = 0; i < ht->e_num; i++)
       printf("%s\n", str[i]);

   hash_elem_it it = HT_ITERATOR(ht);
   hash_elem_t* e = ht_iterate(&it);
   while(e != NULL)
   {
       printf("%s = %s \n", e->key, (char*)e->data);
       e = ht_iterate(&it);
   }
  
   printf("Iterating keys\n");
   hash_elem_it it2 = HT_ITERATOR(ht);
   char* k = ht_iterate_keys(&it2);
   while(k != NULL)
   {
       printf("%s\n", k);
       k = ht_iterate_keys(&it2);
   }

   ht_destroy(ht);
   return 0;
}
#endif

Add a comment
Know the answer?
Add Answer to:
Hashtable in C Please fix void ht_put(hashtable_t *ht, char *key, void *val) and void free_hashtable(hashtable_t *ht)...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • Currently I am learning about set theory. I am trying to implement a set using a hashtable with singly linked lists. I a...

    Currently I am learning about set theory. I am trying to implement a set using a hashtable with singly linked lists. I am very confused as to where I should start, as many of the online resources reference basically hash table implementations. How would I go about a template to implement the very basic structures needed for the set in C? Just confused as to where to start. Currently this is my current structure: typedef struct s_entry t char *key...

  • Please answer this problem in C++, Thank you! Read and study the sample program: "hashing with chaining using singly...

    Please answer this problem in C++, Thank you! Read and study the sample program: "hashing with chaining using singly linked lists", as well as "hashing with chaining using doubly linked lists". Notice this program is complete except it doesn't include the remove function. Write the remove function and test it with the rest of the program including the given main program. Upload your C++ source file. ---Here is the referenced program: "hashing with chaining using singly linked lists". Below this...

  • In C++: Please help me correct this code .... All parts with (FIX ME) #include <algorithm> #include <climits&gt...

    In C++: Please help me correct this code .... All parts with (FIX ME) #include <algorithm> #include <climits> #include <iostream> #include <string> // atoi #include <time.h> #include "CSVparser.hpp" using namespace std; //============================================================================ // Global definitions visible to all methods and classes //============================================================================ const unsigned int DEFAULT_SIZE = 179; // forward declarations double strToDouble(string str, char ch); // define a structure to hold bid information struct Bid { string bidId; // unique identifier string title; string fund; double amount; Bid() {...

  • Concurrent Key-Value Database Implement a non-persistent, concurrent key-value database using the Reader/Writers algorithm. - Use a...

    Concurrent Key-Value Database Implement a non-persistent, concurrent key-value database using the Reader/Writers algorithm. - Use a hashmap as the underlying data structure. Inspiration is ok, however the implementation must be yours. The hashmap must be able to grow to fit new elements, but it does not need to reduce its size. -- Linked lists? Positional arrays? All are fine. - Keys and values are strings (char *) - Operations are: get, put Provided files: - Implement the contract set in...

  • Follow the TODOs and complete the insertItem(), searchItem() and printTable() functions in hash.cpp. The hash function...

    Follow the TODOs and complete the insertItem(), searchItem() and printTable() functions in hash.cpp. The hash function has already been implemented for you. // hash.CPP program to implement hashing with chaining #include<iostream> #include "hash.hpp" using namespace std; node* HashTable::createNode(int key, node* next) { node* nw = new node; nw->key = key; nw->next = next; return nw; } HashTable::HashTable(int bsize) { this->tableSize= bsize; table = new node*[tableSize]; for(int i=0;i<bsize;i++) table[i] = nullptr; } //function to calculate hash function unsigned int HashTable::hashFunction(int key)...

  • PLease explain output of these two programs: 1. #include <stdio.h> typedef struct { char *name; int...

    PLease explain output of these two programs: 1. #include <stdio.h> typedef struct { char *name; int x, y; int h, w; } box; typedef struct { unsigned int baud : 5; unsigned int div2 : 1; unsigned int use_external_clock : 1; } flags; int main(int argc, char** argv){ printf("The size of box is %d bytes\n", sizeof(box)); printf("The size of flags is %d bytes\n", sizeof(flags)); return 0; } 2. #include <stdio.h> #include <string.h> /* define simple structure */ struct { unsigned...

  • Using C code 1. Consider a hash table that is implemented using the following struct definitions....

    Using C code 1. Consider a hash table that is implemented using the following struct definitions. #define NUMBUCKETS 10 typedef struct _HTE { int Key; int Value; struct _HTE *Next; } HashTableEntry; typedef struct _HT { HashTableEntry *Buckets[ NUMBUCKETS ]; unsigned int Size; } HashTable; a.) Complete the following function, which takes a pointer to a HashTableEntry, which is the head of a linked list of entries, and an integer x. It returns the first entry in the list whose...

  • *** Tasks to be completed *** Task 1: Define structures to hold bids Task 2: Initialize...

    *** Tasks to be completed *** Task 1: Define structures to hold bids Task 2: Initialize the structures used to hold bids Task 3: Implement logic to free storage when class is destroyed Task 4: Implement logic to calculate a hash value using the bid Id as the source for calculating the key Task 5: Implement logic to insert a bid Be sure to check for key collisions and use the chaining technique with a linked list to store the...

  • C programming Problem 3 [Set via Hashing] As mentioned in the lecture, a hash table can...

    C programming Problem 3 [Set via Hashing] As mentioned in the lecture, a hash table can be used to implement a Set ADT. Let's try to use the template below to implement a Set with double hashing. Here we assume the Set contains names with 3 characters long. Since it is a Set, we do not need to have an explicit value for each key. We will use a token value of 1 if a name belongs to the Set....

  • C programming Let's try to use the template below to implement a Set with double hashing....

    C programming Let's try to use the template below to implement a Set with double hashing. Here we assume the Set contains names with 3 characters long. Since it is a Set, we do not need to have an explicit value for each key. We will use a token value of 1 if a name belongs to the Set. Let's reuse the exact hash functions we have seen in example in Part 7 of the lecture notes, page 3. As...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT