Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Dennis Eichhorn 2022-11-20 14:02:11 +01:00
commit fd97920115
3 changed files with 184 additions and 180 deletions

View File

@ -15,205 +15,207 @@
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
namespace Stdlib { namespace Stdlib
namespace HashTable { {
typedef struct { namespace HashTable
const char *key; {
void *value; typedef struct {
} entry; const char *key;
void *value;
} entry;
struct ht { struct ht {
bool is_fixed = false; bool is_fixed = false;
entry *entries; entry *entries;
size_t max; size_t max;
size_t size; size_t size;
}; };
typedef struct { typedef struct {
const char *key; const char *key;
void *value; void *value;
ht *table; ht *table;
size_t index; size_t index;
} it; } it;
inline inline
unsigned long long hash_key(const char *key) unsigned long long hash_key(const char *key)
{ {
unsigned long long hash = 14695981039346656037UL; unsigned long long hash = 14695981039346656037UL;
for (const char *p = key; *p; ++p) { for (const char *p = key; *p; ++p) {
hash ^= (unsigned long long)(unsigned char)(*p); hash ^= (unsigned long long)(unsigned char)(*p);
hash *= 1099511628211UL; hash *= 1099511628211UL;
}
return hash;
} }
ht *create_table(int max = 0, bool is_fixed = false) return hash;
{ }
ht *table = (ht *) malloc(sizeof(ht));
if (table == NULL) {
return NULL;
}
table->size = 0;
table->max = max == 0 ? 16 : max;
table->is_fixed = is_fixed;
table->entries = (entry *) calloc(table->max, sizeof(entry));
if (table->entries == NULL) {
free(table);
return NULL;
}
return table;
}
void *get_entry(ht *table, const char *key)
{
unsigned long long hash = hash_key(key);
size_t index = (size_t)(hash & (unsigned long long)(table->max - 1));
while (table->entries[index].key != NULL) {
if (strcmp(key, table->entries[index].key) == 0) {
return table->entries[index].value;
}
++index;
if (index >= table->max) {
index = 0;
}
}
ht *create_table(int max = 0, bool is_fixed = false)
{
ht *table = (ht *) malloc(sizeof(ht));
if (table == NULL) {
return NULL; return NULL;
} }
const char *_set_entry(entry *entries, size_t max, const char *key, void *value, size_t *size) table->size = 0;
{ table->max = max == 0 ? 16 : max;
unsigned long long hash = hash_key(key); table->is_fixed = is_fixed;
size_t index = (size_t)(hash & (unsigned long long)(max - 1));
while (entries[index].key != NULL) { table->entries = (entry *) calloc(table->max, sizeof(entry));
if (strcmp(key, entries[index].key) == 0) { if (table->entries == NULL) {
entries[index].value = value; free(table);
return NULL;
return entries[index].key;
}
++index;
if (index >= max) {
index = 0;
}
}
if (size != NULL) {
#ifdef _WIN32
key = _strdup(key);
#else
key = strdup(key);
#endif
if (key == NULL) {
return NULL;
}
++(*size);
}
entries[index].key = (char *) key;
entries[index].value = value;
return key;
} }
bool expand_table(ht *table) return table;
{ }
size_t new_max = table->max * 2;
if (new_max < table->max) { void *get_entry(ht *table, const char *key)
return false; {
unsigned long long hash = hash_key(key);
size_t index = (size_t)(hash & (unsigned long long)(table->max - 1));
while (table->entries[index].key != NULL) {
if (strcmp(key, table->entries[index].key) == 0) {
return table->entries[index].value;
} }
entry *new_entries = (entry *) calloc(new_max, sizeof(entry)); ++index;
if (new_entries == NULL) { if (index >= table->max) {
return false; index = 0;
} }
for (size_t i = 0; i < table->max; ++i) {
entry tmp = table->entries[i];
if (tmp.key != NULL) {
_set_entry(new_entries, new_max, tmp.key, tmp.value, NULL);
}
}
free(table->entries);
table->entries = new_entries;
table->max = new_max;
return true;
} }
const char *set_entry(ht *table, const char *key, void *value) return NULL;
{ }
if (value == NULL) {
const char *_set_entry(entry *entries, size_t max, const char *key, void *value, size_t *size)
{
unsigned long long hash = hash_key(key);
size_t index = (size_t)(hash & (unsigned long long)(max - 1));
while (entries[index].key != NULL) {
if (strcmp(key, entries[index].key) == 0) {
entries[index].value = value;
return entries[index].key;
}
++index;
if (index >= max) {
index = 0;
}
}
if (size != NULL) {
#ifdef _WIN32
key = _strdup(key);
#else
key = strdup(key);
#endif
if (key == NULL) {
return NULL; return NULL;
} }
if (table->is_fixed && table->size == table->max) { ++(*size);
return NULL;
}
if (!table->is_fixed && table->size >= table->max / 2) {
if (!expand_table(table)) {
return NULL;
}
}
return _set_entry(table->entries, table->max, key, value, &table->size);
} }
it table_iterator(ht *table) entries[index].key = (char *) key;
{ entries[index].value = value;
it it;
it.table = table;
it.index = 0;
return it; return key;
} }
bool next(it *it)
{
ht *table = it->table;
while (it->index < table->max) {
size_t i = it->index;
++(it->index);
if (table->entries[i].key != NULL) {
entry tmp = table->entries[i];
it->key = tmp.key;
it->value = tmp.value;
return true;
}
}
bool expand_table(ht *table)
{
size_t new_max = table->max * 2;
if (new_max < table->max) {
return false; return false;
} }
void free_table(ht *table) entry *new_entries = (entry *) calloc(new_max, sizeof(entry));
{ if (new_entries == NULL) {
if (!table || !table->entries) { return false;
return;
}
for (size_t i = 0; i < table->max; ++i) {
if (table->entries[i].key) {
free((void *) table->entries[i].key);
}
}
free(table->entries);
} }
};
for (size_t i = 0; i < table->max; ++i) {
entry tmp = table->entries[i];
if (tmp.key != NULL) {
_set_entry(new_entries, new_max, tmp.key, tmp.value, NULL);
}
}
free(table->entries);
table->entries = new_entries;
table->max = new_max;
return true;
}
const char *set_entry(ht *table, const char *key, void *value)
{
if (value == NULL) {
return NULL;
}
if (table->is_fixed && table->size == table->max) {
return NULL;
}
if (!table->is_fixed && table->size >= table->max / 2) {
if (!expand_table(table)) {
return NULL;
}
}
return _set_entry(table->entries, table->max, key, value, &table->size);
}
it table_iterator(ht *table)
{
it it;
it.table = table;
it.index = 0;
return it;
}
bool next(it *it)
{
ht *table = it->table;
while (it->index < table->max) {
size_t i = it->index;
++(it->index);
if (table->entries[i].key != NULL) {
entry tmp = table->entries[i];
it->key = tmp.key;
it->value = tmp.value;
return true;
}
}
return false;
}
void free_table(ht *table)
{
if (!table || !table->entries) {
return;
}
for (size_t i = 0; i < table->max; ++i) {
if (table->entries[i].key) {
free((void *) table->entries[i].key);
}
}
free(table->entries);
}
}
} }
#endif #endif

View File

@ -13,8 +13,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
namespace Utils { namespace Utils
namespace ArraySort { {
namespace ArraySort
{
inline inline
void reverse_int(int *arr, int size) void reverse_int(int *arr, int size)
{ {

View File

@ -22,7 +22,7 @@ namespace Utils {
inline inline
char *search_replace(const char *haystack, const char *needle, const char *replace) char *search_replace(const char *haystack, const char *needle, const char *replace)
{ {
const char* haystackT = haystack; const char *haystackT = haystack;
size_t i; size_t i;
size_t match = 0; size_t match = 0;
@ -83,10 +83,10 @@ namespace Utils {
int size; int size;
} text_diff; } text_diff;
text_diff computeLCSDiff (char **from, int fromSize, char **to, int toSize) text_diff computeLCSDiff(char **from, int fromSize, char **to, int toSize)
{ {
char **diffValues = (char **) malloc(fromSize * toSize * sizeof(char *)); char **diffValues = (char **) malloc(fromSize * toSize * sizeof(char *));
int *diffMasks = (int *) calloc(fromSize * toSize, sizeof(int)); int *diffMasks = (int *) calloc(fromSize * toSize, sizeof(int));
int *dm = (int *) calloc((fromSize + 1) * (toSize + 1), sizeof(int)); int *dm = (int *) calloc((fromSize + 1) * (toSize + 1), sizeof(int));
@ -134,7 +134,7 @@ namespace Utils {
#else #else
strcpy(diffValues[diffIndex], to[j - 1]); strcpy(diffValues[diffIndex], to[j - 1]);
#endif #endif
diffMasks[diffIndex] = 1; diffMasks[diffIndex] = 1;
--j; --j;
@ -147,7 +147,7 @@ namespace Utils {
diffValues[diffIndex] = (char *) malloc((strlen(from[i - 1]) + 1) * sizeof(char)); diffValues[diffIndex] = (char *) malloc((strlen(from[i - 1]) + 1) * sizeof(char));
if (!diffValues[diffIndex]) { if (!diffValues[diffIndex]) {
fprintf(stderr, "CRITICAL: malloc failed"); fprintf(stderr, "CRITICAL: malloc failed");
continue; continue;
} }
@ -156,7 +156,7 @@ namespace Utils {
#else #else
strcpy(diffValues[diffIndex], from[i - 1]); strcpy(diffValues[diffIndex], from[i - 1]);
#endif #endif
diffMasks[diffIndex] = -1; diffMasks[diffIndex] = -1;
--i; --i;
@ -168,7 +168,7 @@ namespace Utils {
diffValues[diffIndex] = (char *) malloc((strlen(from[i - 1]) + 1) * sizeof(char)); diffValues[diffIndex] = (char *) malloc((strlen(from[i - 1]) + 1) * sizeof(char));
if (!diffValues[diffIndex]) { if (!diffValues[diffIndex]) {
fprintf(stderr, "CRITICAL: malloc failed"); fprintf(stderr, "CRITICAL: malloc failed");
continue; continue;
} }
@ -210,7 +210,7 @@ namespace Utils {
ArraySort::reverse_char(diffValues, diffIndex); ArraySort::reverse_char(diffValues, diffIndex);
ArraySort::reverse_int(diffMasks, diffIndex); ArraySort::reverse_int(diffMasks, diffIndex);
return text_diff { diffValues, diffMasks, diffIndex }; return text_diff{diffValues, diffMasks, diffIndex};
} }
} }
} }