Skip to content

Commit

Permalink
move code from the original repository
Browse files Browse the repository at this point in the history
  • Loading branch information
eerio committed Aug 3, 2023
0 parents commit dda9555
Show file tree
Hide file tree
Showing 18 changed files with 1,244 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
21 changes: 21 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.8)
project(MIMUW-FORK C)

set(CMAKE_CXX_STANDARD "17")
set(CMAKE_C_STANDARD "11")
set(CMAKE_C_FLAGS "-g -Wall -Wextra -Wno-sign-compare")

add_library(err err.c)
add_library(path_utils path_utils.c)
add_library(HashMap HashMap.c)

add_library(rwlock rwlock.c)
target_link_libraries(rwlock pthread err)

add_library(Tree Tree.c)
target_link_libraries(Tree err HashMap path_utils rwlock)

add_executable(main main.c)
target_link_libraries(main Tree HashMap err pthread)

install(TARGETS DESTINATION .)
134 changes: 134 additions & 0 deletions HashMap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "HashMap.h"

// We fix the number of hash buckets for simplicity.
#define N_BUCKETS 8

typedef struct Pair Pair;

struct Pair {
char* key;
void* value;
Pair* next; // Next item in a single-linked list.
};

struct HashMap {
Pair* buckets[N_BUCKETS]; // Linked lists of key-value pairs.
size_t size; // total number of entries in map.
};

static unsigned int get_hash(const char* key);

HashMap* hmap_new()
{
HashMap* map = malloc(sizeof(HashMap));
if (!map)
return NULL;
memset(map, 0, sizeof(HashMap));
return map;
}

void hmap_free(HashMap* map)
{
for (int h = 0; h < N_BUCKETS; ++h) {
for (Pair* p = map->buckets[h]; p;) {
Pair* q = p;
p = p->next;
free(q->key);
free(q);
}
}
free(map);
}

static Pair* hmap_find(HashMap* map, int h, const char* key)
{
for (Pair* p = map->buckets[h]; p; p = p->next) {
if (strcmp(key, p->key) == 0)
return p;
}
return NULL;
}

void* hmap_get(HashMap* map, const char* key)
{
int h = get_hash(key);
Pair* p = hmap_find(map, h, key);
if (p)
return p->value;
else
return NULL;
}

bool hmap_insert(HashMap* map, const char* key, void* value)
{
if (!value)
return false;
int h = get_hash(key);
Pair* p = hmap_find(map, h, key);
if (p)
return false; // Already exists.
Pair* new_p = malloc(sizeof(Pair));
new_p->key = strdup(key);
new_p->value = value;
new_p->next = map->buckets[h];
map->buckets[h] = new_p;
map->size++;
return true;
}

bool hmap_remove(HashMap* map, const char* key)
{
int h = get_hash(key);
Pair** pp = &(map->buckets[h]);
while (*pp) {
Pair* p = *pp;
if (strcmp(key, p->key) == 0) {
*pp = p->next;
free(p->key);
free(p);
map->size--;
return true;
}
pp = &(p->next);
}
return false;
}

size_t hmap_size(HashMap* map)
{
return map->size;
}

HashMapIterator hmap_iterator(HashMap* map)
{
HashMapIterator it = { 0, map->buckets[0] };
return it;
}

bool hmap_next(HashMap* map, HashMapIterator* it, const char** key, void** value)
{
Pair* p = it->pair;
while (!p && it->bucket < N_BUCKETS - 1) {
p = map->buckets[++it->bucket];
}
if (!p)
return false;
*key = p->key;
*value = p->value;
it->pair = p->next;
return true;
}

static unsigned int get_hash(const char* key)
{
unsigned int hash = 17;
while (*key) {
hash = (hash << 3) + hash + *key;
++key;
}
return hash % N_BUCKETS;
}
57 changes: 57 additions & 0 deletions HashMap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once
#include <stdbool.h>
#include <sys/types.h>

// A structure representing a mapping from keys to values.
// Keys are C-strings (null-terminated char*), all distinct.
// Values are non-null pointers (void*, which you can cast to any other pointer type).
typedef struct HashMap HashMap;

// Create a new, empty map.
HashMap* hmap_new();

// Clear the map and free its memory. This frees the map and the keys
// copied by hmap_insert, but does not free any values.
void hmap_free(HashMap* map);

// Get the value stored under `key`, or NULL if not present.
void* hmap_get(HashMap* map, const char* key);

// Insert a `value` under `key` and return true,
// or do nothing and return false if `key` already exists in the map.
// `value` must not be NULL.
// (The caller can free `key` at any time - the map internally uses a copy of it).
bool hmap_insert(HashMap* map, const char* key, void* value);

// Remove the value under `key` and return true (the value is not free'd),
// or do nothing and return false if `key` was not present.
bool hmap_remove(HashMap* map, const char* key);

// Return the number of elements in the map.
size_t hmap_size(HashMap* map);

typedef struct HashMapIterator HashMapIterator;

// Return an iterator to the map. See `hmap_next`.
HashMapIterator hmap_iterator(HashMap* map);

// Set `*key` and `*value` to the current element pointed by iterator and
// move the iterator to the next element.
// If there are no more elements, leaves `*key` and `*value` unchanged and
// returns false.
//
// The map cannot be modified between calls to `hmap_iterator` and `hmap_next`.
//
// Usage: ```
// const char* key;
// void* value;
// HashMapIterator it = hmap_iterator(map);
// while (hmap_next(map, &it, &key, &value))
// foo(key, value);
// ```
bool hmap_next(HashMap* map, HashMapIterator* it, const char** key, void** value);

struct HashMapIterator {
int bucket;
void* pair;
};
Loading

0 comments on commit dda9555

Please sign in to comment.