From fcdcd40e955d2958e9616ae2ecd2d97910aba9b1 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Thu, 17 Aug 2023 23:26:53 -0400 Subject: [PATCH] Add haggis_linkmap_get_or_add --- include/linkmap.h | 19 +++------ linkmap.c | 99 ++++++++++++++++++++++++++--------------------- 2 files changed, 60 insertions(+), 58 deletions(-) diff --git a/include/linkmap.h b/include/linkmap.h index 5069709..9be4722 100644 --- a/include/linkmap.h +++ b/include/linkmap.h @@ -42,28 +42,21 @@ #define HAGGIS_BUCKETS_BASE 64 -struct _haggis_link { - struct _haggis_link *next; - char *path; -}; - -typedef struct _haggis_link haggis_link; - -typedef struct { +typedef struct __bucket { union { ino_t val; u8 bytes[sizeof(ino_t)]; - } *key; + } key; uint64_t hash; - char * target; - haggis_link *links; -} haggis_linkmap_node; + char * path; + struct __bucket * next; +} haggis_bucket; typedef struct { pthread_mutex_t *mutex; size_t len; size_t capacity; - haggis_linkmap_node *buckets; + haggis_bucket *buckets; } haggis_linkmap; #endif // !HAGGIS_LINKMAP diff --git a/linkmap.c b/linkmap.c index 6a4e8cf..a9decb6 100644 --- a/linkmap.c +++ b/linkmap.c @@ -32,67 +32,50 @@ #include "linkmap.h" #include "haggis_private.h" +#include +#include #include +#include #include +#include #include -haggis_link* haggis_link_init(char* path) { - haggis_link *link; +haggis_bucket* haggis_bucket_init(ino_t inode, uint64_t hash, char * path) { + haggis_bucket *bucket; - link = calloc(1, sizeof(haggis_link)); - if (link == NULL) return NULL; - link->path = path; - return link; + bucket = calloc(1, sizeof(haggis_bucket)); + if (bucket == NULL) return NULL; + bucket->key.val = inode; + bucket->hash = hash; + bucket->path = path; + return bucket; } -void haggis_link_deinit(haggis_link *link) { - if (link == NULL) - return; - if (link->path != NULL) - free(link->path); - free(link); -} - -int haggis_link_append(haggis_link *head, char *path) { - haggis_link *tail; - - tail = haggis_link_init(path); - if (tail == NULL) return 2; - while (head->next != NULL) { - head++; - } - head->next = tail; - return 0; -} - -void haggis_linkmap_node_deinit(haggis_linkmap_node *nod) { - haggis_link *current; - haggis_link *previous; - - current = nod->links; - while (current != NULL) { - previous = current; - current = current->next; - free(previous); - } - if (nod->key != NULL) - free(nod->key); - if (nod->target != NULL) - free(nod->target); +void haggis_bucket_deinit(haggis_bucket *nod) { + if (nod->path != NULL) + free(nod->path); free(nod); } +void haggis_bucket_append(haggis_bucket *head, haggis_bucket *tail) { + + while (head->next != NULL) { + head = head->next; + } + head->next = tail; +} + int haggis_linkmap_expand(haggis_linkmap *map) { - haggis_linkmap_node *buckets_new; - haggis_linkmap_node *buckets_old; + haggis_bucket *buckets_new; + haggis_bucket *buckets_old; size_t i, hash, idx; - buckets_new = calloc(map->capacity + HAGGIS_BUCKETS_BASE, sizeof(haggis_linkmap_node)); + buckets_new = calloc(map->capacity + HAGGIS_BUCKETS_BASE, sizeof(haggis_bucket)); if (buckets_new == NULL) return 2; for (i = 0; i < map->capacity; i++) { - if (&map->buckets[i] != NULL) { - hash = hash_fnv1a_64(map->buckets[i].key->bytes, sizeof(ino_t)); + if (map->buckets[i].key.val != 0) { + hash = hash_fnv1a_64(&map->buckets[i].key.bytes[0], sizeof(ino_t)); map ->capacity += HAGGIS_BUCKETS_BASE; idx = map->capacity % hash; buckets_new[idx] = map->buckets[i]; @@ -104,3 +87,29 @@ int haggis_linkmap_expand(haggis_linkmap *map) { map->capacity += HAGGIS_BUCKETS_BASE; return 0; } + +char* haggis_linkmap_get_or_add(haggis_linkmap *map, ino_t inode, char * path) { + union { + ino_t val; + u8 bytes[sizeof(ino_t)]; + } key; + char * target = NULL; + size_t idx, hash; + + pthread_mutex_lock(map->mutex); + key.val = inode; + hash = hash_fnv1a_64(key.bytes, sizeof(ino_t)); + idx = map->capacity % hash; + if (map->buckets[idx].key.val == 0) { + map->buckets[idx].key.val = inode; + map->buckets[idx].hash = hash; + map->buckets[idx].path = path; + pthread_mutex_unlock(map->mutex); + return NULL; + } else if (map->buckets[idx].key.val == inode) { + target = strndup(target, PATH_MAX - 1); + pthread_mutex_unlock(map->mutex); + return target; + } + return NULL; +}