Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <stdbool.h>
- #include <string.h>
- #include <pthread.h>
- #include <time.h>
- #define INITIAL_NUM_BUCKETS 1024
- #define DEFAULT_POOL_SIZE 1024
- #define LOAD_FACTOR_THRESHOLD 0.75
- #define LENGTH 45
- typedef struct node {
- char word[LENGTH + 1];
- bool is_deleted;
- struct node *next;
- struct node *free_next;
- } node;
- typedef struct memory_pool {
- node *pool;
- size_t size;
- size_t free_index;
- node *free_list;
- pthread_mutex_t lock;
- } memory_pool;
- typedef struct {
- node **buckets;
- size_t num_buckets;
- size_t word_count;
- pthread_mutex_t lock;
- memory_pool pool;
- double add_word_time;
- double remove_word_time;
- double resize_table_time;
- } hash_table;
- hash_table *table = NULL;
- bool resize_table();
- unsigned int hash(const char *word);
- bool initialize_memory_pool(memory_pool *pool, size_t size);
- node *allocate_node(memory_pool *pool);
- void add_to_free_list(memory_pool *pool, node *n);
- bool resize_memory_pool(memory_pool *pool, size_t new_size);
- void log_error(const char *message);
- void start_timer(clock_t *start);
- void stop_timer(clock_t start, double *accumulated_time);
- unsigned int hash(const char *word) {
- unsigned int hash = 0;
- while (*word) {
- hash = (hash << 2) ^ tolower(*word++);
- }
- return hash;
- }
- bool init_table(size_t initial_pool_size) {
- table = malloc(sizeof(hash_table));
- if (!table) {
- log_error("Failed to allocate hash table.");
- return false;
- }
- table->num_buckets = INITIAL_NUM_BUCKETS;
- table->word_count = 0;
- table->buckets = calloc(table->num_buckets, sizeof(node *));
- if (!table->buckets) {
- free(table);
- log_error("Failed to allocate buckets.");
- return false;
- }
- pthread_mutex_init(&table->lock, NULL);
- if (!initialize_memory_pool(&table->pool, initial_pool_size)) {
- free(table->buckets);
- free(table);
- log_error("Failed to initialize memory pool.");
- return false;
- }
- table->add_word_time = 0.0;
- table->remove_word_time = 0.0;
- table->resize_table_time = 0.0;
- return true;
- }
- bool initialize_memory_pool(memory_pool *pool, size_t size) {
- pool->pool = malloc(size * sizeof(node));
- if (!pool->pool) {
- return false;
- }
- pool->size = size;
- pool->free_index = 0;
- pool->free_list = NULL;
- pthread_mutex_init(&pool->lock, NULL);
- return true;
- }
- node *allocate_node(memory_pool *pool) {
- pthread_mutex_lock(&pool->lock);
- if (pool->free_list) {
- node *n = pool->free_list;
- pool->free_list = n->free_next;
- pthread_mutex_unlock(&pool->lock);
- return n;
- }
- if (pool->free_index >= pool->size) {
- if (!resize_memory_pool(pool, pool->size * 2)) {
- pthread_mutex_unlock(&pool->lock);
- return NULL;
- }
- }
- node *n = &pool->pool[pool->free_index++];
- pthread_mutex_unlock(&pool->lock);
- return n;
- }
- void add_to_free_list(memory_pool *pool, node *n) {
- pthread_mutex_lock(&pool->lock);
- n->free_next = pool->free_list;
- pool->free_list = n;
- pthread_mutex_unlock(&pool->lock);
- }
- bool resize_memory_pool(memory_pool *pool, size_t new_size) {
- node *new_pool = realloc(pool->pool, new_size * sizeof(node));
- if (!new_pool) {
- log_error("Failed to resize memory pool.");
- return false;
- }
- pool->pool = new_pool;
- pool->size = new_size;
- return true;
- }
- bool load(const char *dictionary, size_t initial_pool_size) {
- if (!init_table(initial_pool_size)) {
- return false;
- }
- FILE *file = fopen(dictionary, "r");
- if (file == NULL) {
- unload();
- log_error("Failed to open dictionary file.");
- return false;
- }
- char word[LENGTH + 1];
- while (fscanf(file, "%45s", word) != EOF) {
- if (!add_word(word)) {
- fclose(file);
- unload();
- return false;
- }
- }
- fclose(file);
- return true;
- }
- bool resize_table() {
- size_t new_num_buckets = table->num_buckets * 2;
- node **new_buckets = calloc(new_num_buckets, sizeof(node *));
- if (!new_buckets) {
- log_error("Failed to allocate new buckets for resizing.");
- return false;
- }
- clock_t start;
- start_timer(&start);
- for (size_t i = 0; i < table->num_buckets; i++) {
- node *current = table->buckets[i];
- while (current) {
- node *next = current->next;
- if (!current->is_deleted) {
- unsigned int new_index = hash(current->word) % new_num_buckets;
- current->next = new_buckets[new_index];
- new_buckets[new_index] = current;
- }
- current = next;
- }
- }
- free(table->buckets);
- table->buckets = new_buckets;
- table->num_buckets = new_num_buckets;
- stop_timer(start, &table->resize_table_time);
- return true;
- }
- bool add_word(const char *word) {
- if (!table) return false;
- pthread_mutex_lock(&table->lock);
- if ((double)table->word_count / table->num_buckets > LOAD_FACTOR_THRESHOLD) {
- if (!resize_table()) {
- pthread_mutex_unlock(&table->lock);
- return false;
- }
- }
- clock_t start;
- start_timer(&start);
- unsigned int index = hash(word) % table->num_buckets;
- node *new_node = allocate_node(&table->pool);
- if (!new_node) {
- pthread_mutex_unlock(&table->lock);
- return false;
- }
- strcpy(new_node->word, word);
- new_node->is_deleted = false;
- new_node->next = table->buckets[index];
- table->buckets[index] = new_node;
- table->word_count++;
- stop_timer(start, &table->add_word_time);
- pthread_mutex_unlock(&table->lock);
- return true;
- }
- bool remove_word(const char *word) {
- if (!table) return false;
- pthread_mutex_lock(&table->lock);
- clock_t start;
- start_timer(&start);
- unsigned int index = hash(word) % table->num_buckets;
- node *current = table->buckets[index];
- while (current) {
- if (!current->is_deleted && strcmp(current->word, word) == 0) {
- current->is_deleted = true;
- table->word_count--;
- add_to_free_list(&table->pool, current);
- stop_timer(start, &table->remove_word_time);
- pthread_mutex_unlock(&table->lock);
- return true;
- }
- current = current->next;
- }
- stop_timer(start, &table->remove_word_time);
- pthread_mutex_unlock(&table->lock);
- return false;
- }
- void clean_up_deleted_nodes() {
- pthread_mutex_lock(&table->lock);
- for (size_t i = 0; i < table->num_buckets; i++) {
- node **current = &table->buckets[i];
- while (*current) {
- if ((*current)->is_deleted) {
- node *temp = *current;
- *current = (*current)->next;
- add_to_free_list(&table->pool, temp);
- } else {
- current = &(*current)->next;
- }
- }
- }
- pthread_mutex_unlock(&table->lock);
- }
- bool unload() {
- if (!table) return false;
- for (size_t i = 0; i < table->num_buckets; i++) {
- node *current = table->buckets[i];
- while (current) {
- node *temp = current;
- current = current->next;
- }
- }
- free(table->buckets);
- free(table->pool.pool);
- pthread_mutex_destroy(&table->lock);
- pthread_mutex_destroy(&table->pool.lock);
- free(table);
- table = NULL;
- return true;
- }
- void log_error(const char *message) {
- fprintf(stderr, "Error: %s\n", message);
- }
- void start_timer(clock_t *start) {
- *start = clock();
- }
- void stop_timer(clock_t start, double *accumulated_time) {
- clock_t end = clock();
- *accumulated_time += ((double)(end - start)) / CLOCKS_PER_SEC;
- }
- int main(int argc, char *argv[]) {
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <dictionary file>\n", argv[0]);
- return 1;
- }
- size_t initial_pool_size = DEFAULT_POOL_SIZE;
- if (!load(argv[1], initial_pool_size)) {
- fprintf(stderr, "Failed to load dictionary.\n");
- return 1;
- }
- add_word("example");
- remove_word("example
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement