#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// www.cse.yorku.ca/~oz/hash.html
unsigned long stringHash(const char *str, unsigned long modulinho)
{
unsigned long hash = 5381;
int c;
while ((c = (unsigned char)*str++))
hash = ((hash << 5) + hash) + c;
return hash % modulinho;
}
struct Bucket {
char *key;
char *value;
struct Bucket *next;
};
struct Bucket *createBucket(const char *key, const char *value)
{
if (!key || !value) {
return NULL;
}
struct Bucket
*bucket
= malloc(sizeof(struct Bucket
)); if (!bucket) {
return NULL;
}
if (!bucket->key) {
return NULL;
}
if (!bucket->value) {
return NULL;
}
bucket->next = NULL;
return bucket;
}
void freeBucketList(struct Bucket *bucket)
{
if (!bucket) {
return;
}
if (bucket->next) {
freeBucketList(bucket->next);
}
}
struct Bucket *addBucketToList(struct Bucket *head, const char *key, const char *value)
{
struct Bucket *newBucket = createBucket(key, value);
if (!newBucket) {
return NULL;
}
if (head) {
struct Bucket *lastBucket = head;
while (lastBucket->next) {
lastBucket = lastBucket->next;
}
lastBucket->next = newBucket;
return head;
}
return newBucket; // new head
}
struct Bucket *findBucket(struct Bucket *head, const char *key)
{
while (head) {
if (!strcmp(head
->key
, key
)) { return head;
}
head = head->next;
}
return NULL;
}
int replaceBucketValue(struct Bucket *bucket, const char *value)
{
if (!bucket) {
return 0;
}
if (!newValue) {
return 0;
}
bucket->value = newValue;
return 1;
}
struct HashMap {
unsigned long bucketsSize;
struct Bucket **buckets;
};
struct HashMap *createHashMap(unsigned long bucketsSize)
{
struct HashMap
*map
= malloc(sizeof(struct HashMap
)); if (!map) {
return NULL;
}
map->bucketsSize = bucketsSize;
map
->buckets
= calloc(bucketsSize
, sizeof(struct Bucket
*)); if (!map->buckets) {
return NULL;
}
return map;
}
void freeHashMap(struct HashMap *map)
{
if (!map) {
return;
}
for (unsigned long i = 0; i < map->bucketsSize; i++) {
freeBucketList(map->buckets[i]);
}
}
int mapAddKeyValue(struct HashMap *map, const char *key, const char *value)
{
if (!map) {
return 0;
}
unsigned long hash = stringHash(key, map->bucketsSize);
struct Bucket *existingBucket = findBucket(map->buckets[hash], key);
if (existingBucket) {
return replaceBucketValue(existingBucket, value);
} else {
struct Bucket *newHead = addBucketToList(map->buckets[hash], key, value);
if (!newHead) {
return 0;
}
map->buckets[hash] = newHead;
}
return 1;
}
const char *mapGetValue(struct HashMap *map, const char *key)
{
if (!map) {
return NULL;
}
unsigned long hash = stringHash(key, map->bucketsSize);
struct Bucket *bucket = map->buckets[hash];
if (!bucket) {
return NULL;
}
if (!bucket->next) {
return bucket->value;
}
bucket = findBucket(bucket, key);
if (bucket) {
return bucket->value;
} else {
return NULL;
}
}
int main()
{
struct HashMap *map = createHashMap(100);
if (!map) {
printf("Map creating failed\n"); return EXIT_FAILURE;
}
const char *pairs[2][2] = { {"govno", "shit"}, {"kod", "code"} };
for (unsigned int i = 0; i < 2; i++) {
mapAddKeyValue(map, pairs[i][0], pairs[i][1]);
}
for (unsigned int i = 0; i < 2; i++) {
printf("map[%s] = %s\n", pairs
[i
][0], mapGetValue
(map
, pairs
[i
][0])); }
freeHashMap(map);
return EXIT_SUCCESS;
}
I2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKLy8gd3d3LmNzZS55b3JrdS5jYS9+b3ovaGFzaC5odG1sCnVuc2lnbmVkIGxvbmcgc3RyaW5nSGFzaChjb25zdCBjaGFyICpzdHIsIHVuc2lnbmVkIGxvbmcgbW9kdWxpbmhvKQp7CiAgICB1bnNpZ25lZCBsb25nIGhhc2ggPSA1MzgxOwogICAgaW50IGM7CgogICAgd2hpbGUgKChjID0gKHVuc2lnbmVkIGNoYXIpKnN0cisrKSkKICAgICAgICBoYXNoID0gKChoYXNoIDw8IDUpICsgaGFzaCkgKyBjOwoKICAgIHJldHVybiBoYXNoICUgbW9kdWxpbmhvOwp9CgoKc3RydWN0IEJ1Y2tldCB7CiAgICBjaGFyICprZXk7CiAgICBjaGFyICp2YWx1ZTsKICAgIHN0cnVjdCBCdWNrZXQgKm5leHQ7Cn07CgpzdHJ1Y3QgQnVja2V0ICpjcmVhdGVCdWNrZXQoY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSkKewogICAgaWYgKCFrZXkgfHwgIXZhbHVlKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgc3RydWN0IEJ1Y2tldCAqYnVja2V0ID0gbWFsbG9jKHNpemVvZihzdHJ1Y3QgQnVja2V0KSk7CiAgICBpZiAoIWJ1Y2tldCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGJ1Y2tldC0+a2V5ID0gbWFsbG9jKHN0cmxlbihrZXkpICsgMSk7CiAgICBpZiAoIWJ1Y2tldC0+a2V5KSB7CiAgICAgICAgZnJlZShidWNrZXQpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgYnVja2V0LT52YWx1ZSA9IG1hbGxvYyhzdHJsZW4odmFsdWUpICsgMSk7CiAgICBpZiAoIWJ1Y2tldC0+dmFsdWUpIHsKICAgICAgICBmcmVlKGJ1Y2tldC0+a2V5KTsKICAgICAgICBmcmVlKGJ1Y2tldCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICAKICAgIHN0cmNweShidWNrZXQtPmtleSwga2V5KTsKICAgIHN0cmNweShidWNrZXQtPnZhbHVlLCB2YWx1ZSk7CgogICAgYnVja2V0LT5uZXh0ID0gTlVMTDsKICAgIHJldHVybiBidWNrZXQ7Cn0KCnZvaWQgZnJlZUJ1Y2tldExpc3Qoc3RydWN0IEJ1Y2tldCAqYnVja2V0KQp7CiAgICBpZiAoIWJ1Y2tldCkgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBmcmVlKGJ1Y2tldC0+a2V5KTsKICAgIGZyZWUoYnVja2V0LT52YWx1ZSk7CgogICAgaWYgKGJ1Y2tldC0+bmV4dCkgewogICAgICAgIGZyZWVCdWNrZXRMaXN0KGJ1Y2tldC0+bmV4dCk7CiAgICB9CgogICAgZnJlZShidWNrZXQpOwp9CgoKc3RydWN0IEJ1Y2tldCAqYWRkQnVja2V0VG9MaXN0KHN0cnVjdCBCdWNrZXQgKmhlYWQsIGNvbnN0IGNoYXIgKmtleSwgY29uc3QgY2hhciAqdmFsdWUpCnsKICAgIHN0cnVjdCBCdWNrZXQgKm5ld0J1Y2tldCA9IGNyZWF0ZUJ1Y2tldChrZXksIHZhbHVlKTsKICAgIGlmICghbmV3QnVja2V0KSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKGhlYWQpIHsKICAgICAgICBzdHJ1Y3QgQnVja2V0ICpsYXN0QnVja2V0ID0gaGVhZDsKICAgICAgICB3aGlsZSAobGFzdEJ1Y2tldC0+bmV4dCkgewogICAgICAgICAgICBsYXN0QnVja2V0ID0gbGFzdEJ1Y2tldC0+bmV4dDsKICAgICAgICB9CiAgICAgICAgbGFzdEJ1Y2tldC0+bmV4dCA9IG5ld0J1Y2tldDsKICAgICAgICByZXR1cm4gaGVhZDsKICAgIH0KCiAgICByZXR1cm4gbmV3QnVja2V0OyAgLy8gbmV3IGhlYWQKfQoKc3RydWN0IEJ1Y2tldCAqZmluZEJ1Y2tldChzdHJ1Y3QgQnVja2V0ICpoZWFkLCBjb25zdCBjaGFyICprZXkpCnsKICAgIHdoaWxlIChoZWFkKSB7CiAgICAgICAgaWYgKCFzdHJjbXAoaGVhZC0+a2V5LCBrZXkpKSB7CiAgICAgICAgICAgIHJldHVybiBoZWFkOwogICAgICAgIH0KICAgICAgICBoZWFkID0gaGVhZC0+bmV4dDsKICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQoKaW50IHJlcGxhY2VCdWNrZXRWYWx1ZShzdHJ1Y3QgQnVja2V0ICpidWNrZXQsIGNvbnN0IGNoYXIgKnZhbHVlKQp7CiAgICBpZiAoIWJ1Y2tldCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGNoYXIgKm5ld1ZhbHVlID0gbWFsbG9jKHN0cmxlbih2YWx1ZSkgKyAxKTsKICAgIGlmICghbmV3VmFsdWUpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBzdHJjcHkobmV3VmFsdWUsIHZhbHVlKTsKICAgIGZyZWUoYnVja2V0LT52YWx1ZSk7CiAgICBidWNrZXQtPnZhbHVlID0gbmV3VmFsdWU7CgogICAgcmV0dXJuIDE7Cn0KCnN0cnVjdCBIYXNoTWFwIHsKICAgIHVuc2lnbmVkIGxvbmcgYnVja2V0c1NpemU7CiAgICBzdHJ1Y3QgQnVja2V0ICoqYnVja2V0czsKfTsKCnN0cnVjdCBIYXNoTWFwICpjcmVhdGVIYXNoTWFwKHVuc2lnbmVkIGxvbmcgYnVja2V0c1NpemUpCnsKICAgIHN0cnVjdCBIYXNoTWFwICptYXAgPSBtYWxsb2Moc2l6ZW9mKHN0cnVjdCBIYXNoTWFwKSk7CiAgICBpZiAoIW1hcCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIG1hcC0+YnVja2V0c1NpemUgPSBidWNrZXRzU2l6ZTsKICAgIG1hcC0+YnVja2V0cyA9IGNhbGxvYyhidWNrZXRzU2l6ZSwgc2l6ZW9mKHN0cnVjdCBCdWNrZXQqKSk7CiAgICBpZiAoIW1hcC0+YnVja2V0cykgewogICAgICAgIGZyZWUobWFwKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gbWFwOwp9Cgp2b2lkIGZyZWVIYXNoTWFwKHN0cnVjdCBIYXNoTWFwICptYXApCnsKICAgIGlmICghbWFwKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGZvciAodW5zaWduZWQgbG9uZyBpID0gMDsgaSA8IG1hcC0+YnVja2V0c1NpemU7IGkrKykgewogICAgICAgIGZyZWVCdWNrZXRMaXN0KG1hcC0+YnVja2V0c1tpXSk7CiAgICB9CgogICAgZnJlZShtYXApOwp9CgppbnQgbWFwQWRkS2V5VmFsdWUoc3RydWN0IEhhc2hNYXAgKm1hcCwgY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSkKewogICAgaWYgKCFtYXApIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICB1bnNpZ25lZCBsb25nIGhhc2ggPSBzdHJpbmdIYXNoKGtleSwgbWFwLT5idWNrZXRzU2l6ZSk7CiAgICBzdHJ1Y3QgQnVja2V0ICpleGlzdGluZ0J1Y2tldCA9IGZpbmRCdWNrZXQobWFwLT5idWNrZXRzW2hhc2hdLCBrZXkpOwogICAgaWYgKGV4aXN0aW5nQnVja2V0KSB7CiAgICAgICAgcmV0dXJuIHJlcGxhY2VCdWNrZXRWYWx1ZShleGlzdGluZ0J1Y2tldCwgdmFsdWUpOwogICAgfSBlbHNlIHsKICAgICAgICBzdHJ1Y3QgQnVja2V0ICpuZXdIZWFkID0gYWRkQnVja2V0VG9MaXN0KG1hcC0+YnVja2V0c1toYXNoXSwga2V5LCB2YWx1ZSk7CiAgICAgICAgaWYgKCFuZXdIZWFkKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBtYXAtPmJ1Y2tldHNbaGFzaF0gPSBuZXdIZWFkOwogICAgfQoKICAgIHJldHVybiAxOwp9Cgpjb25zdCBjaGFyICptYXBHZXRWYWx1ZShzdHJ1Y3QgSGFzaE1hcCAqbWFwLCBjb25zdCBjaGFyICprZXkpCnsKICAgIGlmICghbWFwKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgdW5zaWduZWQgbG9uZyBoYXNoID0gc3RyaW5nSGFzaChrZXksIG1hcC0+YnVja2V0c1NpemUpOwogICAgc3RydWN0IEJ1Y2tldCAqYnVja2V0ID0gbWFwLT5idWNrZXRzW2hhc2hdOwoKICAgIGlmICghYnVja2V0KSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICAKICAgIGlmICghYnVja2V0LT5uZXh0KSB7CiAgICAgICAgcmV0dXJuIGJ1Y2tldC0+dmFsdWU7CiAgICB9CgogICAgYnVja2V0ID0gZmluZEJ1Y2tldChidWNrZXQsIGtleSk7CiAgICBpZiAoYnVja2V0KSB7CiAgICAgICAgcmV0dXJuIGJ1Y2tldC0+dmFsdWU7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQp9CgppbnQgbWFpbigpCnsKICAgIHN0cnVjdCBIYXNoTWFwICptYXAgPSBjcmVhdGVIYXNoTWFwKDEwMCk7CiAgICBpZiAoIW1hcCkgewogICAgICAgIHByaW50ZigiTWFwIGNyZWF0aW5nIGZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIEVYSVRfRkFJTFVSRTsKICAgIH0KCiAgICBjb25zdCBjaGFyICpwYWlyc1syXVsyXSA9IHsgeyJnb3ZubyIsICJzaGl0In0sIHsia29kIiwgImNvZGUifSB9OwoKICAgIGZvciAodW5zaWduZWQgaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CiAgICAgICAgbWFwQWRkS2V5VmFsdWUobWFwLCBwYWlyc1tpXVswXSwgcGFpcnNbaV1bMV0pOwogICAgfQoKICAgIGZvciAodW5zaWduZWQgaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CiAgICAgICAgcHJpbnRmKCJtYXBbJXNdID0gJXNcbiIsIHBhaXJzW2ldWzBdLCBtYXBHZXRWYWx1ZShtYXAsIHBhaXJzW2ldWzBdKSk7CiAgICB9CgogICAgZnJlZUhhc2hNYXAobWFwKTsKICAgIHJldHVybiBFWElUX1NVQ0NFU1M7Cn0=