[RELEASE] u22-v03

This version is submitted to U22 breau.
This commit is contained in:
2020-09-14 00:00:00 +00:00
parent 360595de37
commit 84c3a02b9a
357 changed files with 29223 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
add_library(dictres
dictres.c
)
target_link_libraries(dictres
chaos
)
if (BUILD_TESTING)
add_executable(dictres-test test.c)
target_link_libraries(dictres-test dictres)
endif()

87
util/dictres/dictres.c Normal file
View File

@@ -0,0 +1,87 @@
#include "./dictres.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util/chaos/abchash.h"
static void dictres_calculate_hash_(dictres_item_t* items, size_t length) {
assert(items != NULL || length == 0);
for (size_t i = 0; i < length; ++i) {
dictres_item_t* item = &items[i];
const size_t len = strlen(item->key);
if (!chaos_abchash_validate(item->key, len)) {
fprintf(stderr, "dictress: invalid key, '%s'\n", item->key);
abort();
}
item->hash = chaos_abchash(item->key, len);
}
}
static void dictres_sort_(dictres_item_t* items, size_t length) {
assert(items != NULL || length == 0);
for (size_t i = 0; i < length; ++i) {
for (size_t j = 1; j < length-i; ++j) {
if (items[j-1].hash > items[j].hash) {
/* Speed of swapping can be improved but simple is best. :) */
const dictres_item_t temp = items[j-1];
items[j-1] = items[j];
items[j] = temp;
}
}
}
}
static void dictres_validate_(dictres_item_t* items, size_t length) {
assert(items != NULL || length == 0);
for (size_t i = 1; i < length; ++i) {
if (items[i-1].hash == items[i].hash) {
fprintf(stderr,
"dictres: detected hash collision between '%s' and '%s'\n",
items[i-1].key, items[i].key);
}
}
}
void dictres_optimize_(dictres_item_t* items, size_t length) {
assert(items != NULL || length == 0);
dictres_calculate_hash_(items, length);
dictres_sort_(items, length);
dictres_validate_(items, length);
}
const char* dictres_find_(
const dictres_item_t* items, size_t length, const char* key) {
assert(items != NULL || length == 0);
const size_t keylen = strlen(key);
assert(chaos_abchash_validate(key, keylen));
const uint64_t hash = chaos_abchash(key, keylen);
size_t l = 0, r = length-1;
while (l <= r && r < length) {
const size_t i = (l+r)/2;
if (items[i].hash == hash) {
return items[i].value;
}
if (items[i].hash < hash) {
l = i+1;
} else {
if (i == 0) break;
r = i-1;
}
}
fprintf(stderr, "dictres: cannot find key, '%s'\n", key);
abort();
}

27
util/dictres/dictres.h Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
typedef struct {
const char* key;
const char* value;
uint64_t hash;
} dictres_item_t;
void
dictres_optimize_(
dictres_item_t* items,
size_t length
);
#define dictres_optimize(items) \
dictres_optimize_(items, sizeof(items)/sizeof(items[0]))
const char*
dictres_find_(
const dictres_item_t* items,
size_t length,
const char* key
);
#define dictres_find(items, key) \
dictres_find_(items, sizeof(items)/sizeof(items[0]), key)

27
util/dictres/test.c Normal file
View File

@@ -0,0 +1,27 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include "./dictres.h"
static dictres_item_t dictres_[] = {
{"app_name",
"dictres-test"},
{"description",
"dictres provides a static dictionary type which finds value from key fast."},
{"bye",
"see you!"},
};
int main(void) {
dictres_optimize(dictres_);
printf("%s\n", dictres_find(dictres_, "app_name"));
printf("====\n");
printf("%s\n", dictres_find(dictres_, "description"));
printf("%s\n", dictres_find(dictres_, "bye"));
return EXIT_SUCCESS;
}