-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move code from the original repository
- Loading branch information
0 parents
commit dda9555
Showing
18 changed files
with
1,244 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 .) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; |
Oops, something went wrong.