Added hashtable
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.0 )
 | 
					cmake_minimum_required(VERSION 3.10 )
 | 
				
			||||||
set(CMAKE_C_STANDARD 11)
 | 
					set(CMAKE_C_STANDARD 11)
 | 
				
			||||||
project(wlgol
 | 
					project(wlgol
 | 
				
			||||||
    VERSION 0.0.1
 | 
					    VERSION 0.0.1
 | 
				
			||||||
@@ -22,7 +22,6 @@ add_custom_command(
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(SOURCES
 | 
					set(SOURCES
 | 
				
			||||||
    wlgol.c
 | 
					 | 
				
			||||||
    tkeyboard.c
 | 
					    tkeyboard.c
 | 
				
			||||||
    tpointer.c
 | 
					    tpointer.c
 | 
				
			||||||
	hashtable.c
 | 
						hashtable.c
 | 
				
			||||||
@@ -33,7 +32,7 @@ set(GENHEADERS
 | 
				
			|||||||
    ${CMAKE_CURRENT_BINARY_DIR}/include/xdg-shell.h
 | 
					    ${CMAKE_CURRENT_BINARY_DIR}/include/xdg-shell.h
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_executable(wlgol ${SOURCES} ${GENHEADERS})
 | 
					add_executable(wlgol wlgol.c ${SOURCES} ${GENHEADERS})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_include_directories(wlgol
 | 
					target_include_directories(wlgol
 | 
				
			||||||
    PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include
 | 
					    PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include
 | 
				
			||||||
@@ -44,3 +43,20 @@ target_link_libraries(wlgol
 | 
				
			|||||||
    wayland-client
 | 
					    wayland-client
 | 
				
			||||||
    wayland-cursor
 | 
					    wayland-cursor
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_executable(test_hashtable tests/test_hashtable.c
 | 
				
			||||||
 | 
					    ${SOURCES}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					target_link_libraries(test_hashtable
 | 
				
			||||||
 | 
					    wayland-client
 | 
				
			||||||
 | 
					    wayland-cursor
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					target_include_directories(test_hashtable
 | 
				
			||||||
 | 
					    PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include
 | 
				
			||||||
 | 
					    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enable_testing()
 | 
				
			||||||
 | 
					add_test(NAME Hashtable COMMAND test_hashtable)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										245
									
								
								hashtable.c
									
									
									
									
									
								
							
							
						
						
									
										245
									
								
								hashtable.c
									
									
									
									
									
								
							@@ -7,124 +7,193 @@
 | 
				
			|||||||
#include "hashtable.h"
 | 
					#include "hashtable.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					
 | 
				
			||||||
 * @brief Hash function for hashtable
 | 
					// entry in the hashtable
 | 
				
			||||||
 *
 | 
					struct entry
 | 
				
			||||||
 * This function takes a string key and calculates a hash value.
 | 
					{
 | 
				
			||||||
 * The hash value is used to determine the index in the hashtable
 | 
						const char *key;
 | 
				
			||||||
 * where the key-value pair should be stored.
 | 
					  void *value;
 | 
				
			||||||
 *
 | 
						struct entry *next;
 | 
				
			||||||
 * @param key The string key to hash
 | 
					};
 | 
				
			||||||
 * @return The calculated hash value
 | 
					
 | 
				
			||||||
 */
 | 
					struct htobj
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int size;
 | 
				
			||||||
 | 
						struct entry **table;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct item {
 | 
				
			||||||
 | 
						struct entry *prev, *found;
 | 
				
			||||||
 | 
						int index;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int hash(const char *key)
 | 
					static unsigned int hash(const char *key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int hash = 0; // Initialize hash value to 0
 | 
						unsigned int hash = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Iterate over each character in the key string
 | 
					 | 
				
			||||||
	while (*key)
 | 
						while (*key)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// Calculate the hash value by multiplying the current hash value
 | 
					 | 
				
			||||||
		// with 32 (2^5) and subtracting the current hash value. Then add the
 | 
					 | 
				
			||||||
		// ASCII value of the current character.
 | 
					 | 
				
			||||||
		hash = (hash << 5) - hash + *key++;
 | 
							hash = (hash << 5) - hash + *key++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Return the calculated hash value
 | 
					 | 
				
			||||||
	return hash;
 | 
						return hash;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					hashtable hashtable_new(int size)
 | 
				
			||||||
 * @brief Create a new hashtable
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This function creates a new hashtable with the specified size.
 | 
					 | 
				
			||||||
 * It initializes the table with NULL entries.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @param size The size of the hashtable
 | 
					 | 
				
			||||||
 * @return A pointer to the newly created hashtable
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
hashtable *hashtable_new(int size)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// Allocate memory for the hashtable
 | 
						// Allocate memory for the hashtable
 | 
				
			||||||
	hashtable *h = malloc(sizeof(hashtable));
 | 
						hashtable h = malloc(sizeof(struct htobj));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Set the size of the hashtable
 | 
						// Set the size of the hashtable
 | 
				
			||||||
	h->size = size;
 | 
						h->size = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allocate memory for the entry pointers
 | 
						// Allocate memory for the entry pointers
 | 
				
			||||||
	h->table = malloc(sizeof(entry *) * size);
 | 
						h->table = calloc(size, sizeof(struct entry *));
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Initialize all entries to NULL
 | 
					 | 
				
			||||||
	for (int i = 0; i < size; i++)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		h->table[i] = NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Return the newly created hashtable
 | 
						// Return the newly created hashtable
 | 
				
			||||||
	return h;
 | 
						return h;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// hashtable_insert
 | 
					struct item hashtable_lookup_item(hashtable h, const char *key)
 | 
				
			||||||
void hashtable_insert(hashtable *h, const char *key, void *value) {
 | 
					{
 | 
				
			||||||
 | 
						struct item result = {
 | 
				
			||||||
 | 
							.found = NULL,
 | 
				
			||||||
 | 
							.index = -1,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Calculate the index using the hash function
 | 
					 | 
				
			||||||
	int index = hash(key) % h->size;
 | 
						int index = hash(key) % h->size;
 | 
				
			||||||
 | 
						struct entry *e = h->table[index];
 | 
				
			||||||
 | 
						struct entry *prev = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create a new entry
 | 
					 | 
				
			||||||
	entry *e = malloc(sizeof(entry));
 | 
					 | 
				
			||||||
	e->key = key;
 | 
					 | 
				
			||||||
	e->value = value;
 | 
					 | 
				
			||||||
	e->next = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Insert the entry at the beginning of the linked list
 | 
					 | 
				
			||||||
	e->next = h->table[index];
 | 
					 | 
				
			||||||
	h->table[index] = e;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// hashtable_lookup
 | 
					 | 
				
			||||||
void *hashtable_lookup(hashtable *h, const char *key) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Calculate the index using the hash function
 | 
					 | 
				
			||||||
	int index = hash(key) % h->size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Traverse the linked list at the index
 | 
					 | 
				
			||||||
	entry *e = h->table[index];
 | 
					 | 
				
			||||||
	while (e != NULL) {
 | 
						while (e != NULL) {
 | 
				
			||||||
		if (strcmp(e->key, key) == 0) {
 | 
							if (strcmp(e->key, key) == 0) {
 | 
				
			||||||
			return e->value;
 | 
								result.index = index;
 | 
				
			||||||
		}
 | 
								result.found = e;
 | 
				
			||||||
		e = e->next;
 | 
								result.prev = prev;
 | 
				
			||||||
	}
 | 
								return result;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Return NULL if the key is not found
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// hashtable_remove
 | 
					 | 
				
			||||||
void hashtable_remove(hashtable *h, const char *key) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Calculate the index using the hash function
 | 
					 | 
				
			||||||
	int index = hash(key) % h->size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Traverse the linked list at the index
 | 
					 | 
				
			||||||
	entry *e = h->table[index];
 | 
					 | 
				
			||||||
	entry *prev = NULL;
 | 
					 | 
				
			||||||
	while (e != NULL) {
 | 
					 | 
				
			||||||
		if (strcmp(e->key, key) == 0) {
 | 
					 | 
				
			||||||
			if (prev == NULL) {
 | 
					 | 
				
			||||||
				h->table[index] = e->next;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				prev->next = e->next;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			free(e);
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		prev = e;
 | 
							prev = e;
 | 
				
			||||||
		e = e->next;
 | 
							e = e->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return result; // empty in this case
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *hashtable_set(hashtable h, const char *key, void *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct item item = hashtable_lookup_item(h, key);
 | 
				
			||||||
 | 
						// not found - insert new
 | 
				
			||||||
 | 
						if (item.found == NULL) {
 | 
				
			||||||
 | 
							int index = hash(key) % h->size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Create a new entry
 | 
				
			||||||
 | 
							struct entry *e = malloc(sizeof(struct entry));
 | 
				
			||||||
 | 
							e->key = strdup(key); // key is the copy
 | 
				
			||||||
 | 
							e->value = value;
 | 
				
			||||||
 | 
							e->next = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Insert the entry at the beginning of the linked list
 | 
				
			||||||
 | 
							e->next = h->table[index];
 | 
				
			||||||
 | 
							h->table[index] = e;
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// found replace the value
 | 
				
			||||||
 | 
						void *old_value = item.found->value;
 | 
				
			||||||
 | 
						item.found-> value = value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return old_value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *hashtable_lookup(hashtable h, const char *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct item item = hashtable_lookup_item(h, key);
 | 
				
			||||||
 | 
						if (item.found != NULL) {
 | 
				
			||||||
 | 
							return item.found->value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *hashtable_remove(hashtable h, const char *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct item item = hashtable_lookup_item(h, key);
 | 
				
			||||||
 | 
						if (item.found == NULL) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// found, so detete it
 | 
				
			||||||
 | 
					  if (item.prev != NULL) {
 | 
				
			||||||
 | 
					  	item.prev->next = item.found->next;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					  	h->table[item.index] = item.found->next;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // free unused memory
 | 
				
			||||||
 | 
					  void *value = item.found->value; // remember value
 | 
				
			||||||
 | 
					  free((void*) item.found->key); // free key
 | 
				
			||||||
 | 
					  free((void*) item.found); // free entry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hashtable_destroy_bucket(hashtable h, int i)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct entry *e = h->table[i];
 | 
				
			||||||
 | 
						while (e != NULL) {
 | 
				
			||||||
 | 
							free((void*)e->key);
 | 
				
			||||||
 | 
							e = e->next;
 | 
				
			||||||
 | 
							free(e);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hashtable_destroy(hashtable h)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (h==NULL) return;
 | 
				
			||||||
 | 
						for (int i = 0; i < h->size; i++) {
 | 
				
			||||||
 | 
							hashtable_destroy_bucket(h, i);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						free (h->table);
 | 
				
			||||||
 | 
						free(h);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ht_iterator hashtable_iter(hashtable h)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ht_iterator iter = {
 | 
				
			||||||
 | 
							.h = h,
 | 
				
			||||||
 | 
							.index = -1,
 | 
				
			||||||
 | 
						  .entry = NULL,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return iter;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ht_iter_next(ht_iterator *iter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (iter == NULL) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hashtable h = iter->h;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while(true)	{
 | 
				
			||||||
 | 
							if (iter->index >= h->size) {
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (iter->entry == NULL) {
 | 
				
			||||||
 | 
								iter->index++;
 | 
				
			||||||
 | 
								iter->entry = h->table[iter->index];
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								iter->entry = iter->entry->next;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (iter->entry != NULL) return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *ht_iter_key(ht_iterator *iter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (iter == NULL || iter->entry == NULL) return NULL;
 | 
				
			||||||
 | 
						return iter->entry->key;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *ht_iter_value(ht_iterator *iter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (iter == NULL || iter->entry == NULL) return NULL;
 | 
				
			||||||
 | 
						return iter->entry->value;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +1,16 @@
 | 
				
			|||||||
#ifndef HASHTABLE_H
 | 
					#ifndef HASHTABLE_H
 | 
				
			||||||
#define HASHTABLE_H
 | 
					#define HASHTABLE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// entry in the hashtable
 | 
					struct htobj;
 | 
				
			||||||
typedef struct entry
 | 
					typedef struct htobj *hashtable;
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	const char *key;
 | 
					 | 
				
			||||||
	void *value;
 | 
					 | 
				
			||||||
	struct entry *next;
 | 
					 | 
				
			||||||
} entry;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// hashtable
 | 
					typedef struct {
 | 
				
			||||||
typedef struct
 | 
						struct htobj *h;
 | 
				
			||||||
{
 | 
						struct entry *entry;
 | 
				
			||||||
	int size;
 | 
						int index;
 | 
				
			||||||
	entry **table;
 | 
					} ht_iterator;
 | 
				
			||||||
} hashtable;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Create a new hashtable
 | 
					 * @brief Create a new hashtable
 | 
				
			||||||
@@ -28,7 +21,7 @@ typedef struct
 | 
				
			|||||||
 * @param size The size of the hashtable
 | 
					 * @param size The size of the hashtable
 | 
				
			||||||
 * @return A pointer to the newly created hashtable
 | 
					 * @return A pointer to the newly created hashtable
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
hashtable *hashtable_new(int size);
 | 
					hashtable hashtable_new(int size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Insert a new key-value pair into the hashtable
 | 
					 * @brief Insert a new key-value pair into the hashtable
 | 
				
			||||||
@@ -40,8 +33,9 @@ hashtable *hashtable_new(int size);
 | 
				
			|||||||
 * @param h Pointer to the hashtable
 | 
					 * @param h Pointer to the hashtable
 | 
				
			||||||
 * @param key Pointer to the key
 | 
					 * @param key Pointer to the key
 | 
				
			||||||
 * @param value Pointer to the value
 | 
					 * @param value Pointer to the value
 | 
				
			||||||
 | 
					 * @return null or pointer to the previous value of the key
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void hashtable_insert(hashtable *h, const char *key, void *value);
 | 
					void *hashtable_set(hashtable h, const char *key, void *value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Get the value associated with a key from the hashtable
 | 
					 * @brief Get the value associated with a key from the hashtable
 | 
				
			||||||
@@ -54,7 +48,7 @@ void hashtable_insert(hashtable *h, const char *key, void *value);
 | 
				
			|||||||
 * @param key Pointer to the key
 | 
					 * @param key Pointer to the key
 | 
				
			||||||
 * @return Pointer to the value associated with the key, or NULL if not found
 | 
					 * @return Pointer to the value associated with the key, or NULL if not found
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void *hashtable_lookup(hashtable *h, const char *key);
 | 
					void *hashtable_lookup(hashtable h, const char *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Remove a key-value pair from the hashtable
 | 
					 * @brief Remove a key-value pair from the hashtable
 | 
				
			||||||
@@ -66,6 +60,57 @@ void *hashtable_lookup(hashtable *h, const char *key);
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param h Pointer to the hashtable
 | 
					 * @param h Pointer to the hashtable
 | 
				
			||||||
 * @param key Pointer to the key to remove
 | 
					 * @param key Pointer to the key to remove
 | 
				
			||||||
 | 
					 * @return null or value associated with the removed key.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void hashtable_remove(hashtable *h, const char *key);
 | 
					void *hashtable_remove(hashtable h, const char *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Destroy hashtable.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Values must be destroyed by the caller earlier.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param h Reference to the hastable.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void hashtable_destroy(hashtable h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the iterator of key-value pairs in the hashtable
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function returns the iterator of key-value pairs in the hashtable.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param h Pointer to the hashtable
 | 
				
			||||||
 | 
					 * @return The iterator of key-value pairs in the hashtable
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					ht_iterator hashtable_iter(hashtable h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the next key-value pair from the iterator
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function returns the next key-value pair from the iterator.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param iter Pointer to the iterator
 | 
				
			||||||
 | 
					 * @return true if there is a next key-value pair, false otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool ht_iter_next(ht_iterator *iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the key from the iterator
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function returns the key from the iterator.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param iter Pointer to the iterator
 | 
				
			||||||
 | 
					 * @return The key from the iterator
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const char *ht_iter_key(ht_iterator *iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the value from the iterator
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function returns the value from the iterator.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param iter Pointer to the iterator
 | 
				
			||||||
 | 
					 * @return The value from the iterator
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void *ht_iter_value(ht_iterator *iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										63
									
								
								tests/test_hashtable.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								tests/test_hashtable.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <hashtable.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void test_hashtable(int size) {
 | 
				
			||||||
 | 
						hashtable h =  hashtable_new(size);
 | 
				
			||||||
 | 
						void *value1 = "to jest jakaś tam wartość";
 | 
				
			||||||
 | 
						void *value2 = "I inna";
 | 
				
			||||||
 | 
						void *value3 = "trzecia";
 | 
				
			||||||
 | 
						void *value4 = "Czwarta";
 | 
				
			||||||
 | 
						void *value5 = "Piąta";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *retval = hashtable_set(h, "jeden", value1);
 | 
				
			||||||
 | 
						assert(retval == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *found = hashtable_lookup(h, "jeden");
 | 
				
			||||||
 | 
						assert(found != NULL && !strcmp(value1, found));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						retval = hashtable_set(h, "dwa", value2);
 | 
				
			||||||
 | 
						assert(retval == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						retval = hashtable_set(h, "trzy", value3);
 | 
				
			||||||
 | 
						assert(retval == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						retval = hashtable_set(h, "cztery", value4);
 | 
				
			||||||
 | 
						assert(retval == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						retval = hashtable_set(h, "jeden", value5);
 | 
				
			||||||
 | 
						assert(retval != NULL);
 | 
				
			||||||
 | 
						assert (retval == value1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						retval = hashtable_lookup(h, "niema");
 | 
				
			||||||
 | 
						assert(retval == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						retval = hashtable_lookup(h, "jeden");
 | 
				
			||||||
 | 
						assert(retval == value5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ht_iterator iter = hashtable_iter(h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (ht_iter_next(&iter)) {
 | 
				
			||||||
 | 
							printf("Key %s, value: %s\n", ht_iter_key(&iter), (const char*) ht_iter_value(&iter));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						retval = hashtable_remove(h, "cztery");
 | 
				
			||||||
 | 
						assert (retval == value4);
 | 
				
			||||||
 | 
						retval = hashtable_remove(h, "trzy");
 | 
				
			||||||
 | 
						assert(retval == value3);
 | 
				
			||||||
 | 
						retval = hashtable_remove(h, "dwa");
 | 
				
			||||||
 | 
						assert(retval == value2);
 | 
				
			||||||
 | 
						retval = hashtable_remove(h, "jeden");
 | 
				
			||||||
 | 
						assert(retval == value5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hashtable_destroy(h);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					   test_hashtable(2);
 | 
				
			||||||
 | 
					   test_hashtable(10);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user