From 69107b2c805a588f3ffc5b7209f48a66f38c4766 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Thu, 17 Aug 2023 11:45:59 -0400 Subject: [PATCH] Progress on new `linkmap` structure, for tracking hardlinks --- Makefile | 1 + haggis.c | 2 +- include/linkmap.h | 69 ++++++++++++++++++++++++++++++ linkmap.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 include/linkmap.h create mode 100644 linkmap.c diff --git a/Makefile b/Makefile index b494341..cb6804c 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,7 @@ srcs += hmap.c srcs += haggis.c srcs += jobq.c srcs += linklist.c +srcs += linkmap.c objs = $(srcs:.c=.o) diff --git a/haggis.c b/haggis.c index 62a7656..401ffbf 100644 --- a/haggis.c +++ b/haggis.c @@ -50,7 +50,7 @@ #include #include // fopen, fread, fwrite, FILE -#include // free, malloc +#include // free, malloc, calloc #include // memcpy, strlen #include // readlink #include // stat diff --git a/include/linkmap.h b/include/linkmap.h new file mode 100644 index 0000000..5069709 --- /dev/null +++ b/include/linkmap.h @@ -0,0 +1,69 @@ +/* _,.---._ .-._ .--.-. ,--.--------. + * _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\ + * /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./ + * |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \ + * |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \ + * |==|,| | -|==| , '=' |==| - _ | |==|- | + * |==| '=' /\==\ - ,_ /|==| /\ , | |==|, | + * |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/ + * `-.`.____.' `--`--'' `--`./ `--` `--`--` + * _ __ ,---. .-._ .=-.-. _,.----. + * .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \ + * /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-' + * |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | . + * |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \ + * |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , | + * |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. / + * /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-' + * `--`---' `--` `--`./ `--``--`-` + * + * @(#)Copyright (c) 2023, Nathan D. Fisher. + * + * This is free software. It comes with NO WARRANTY. + * Permission to use, modify and distribute this source code + * is granted subject to the following conditions. + * 1/ that the above copyright notice and this notice + * are preserved in all copies and that due credit be given + * to the author. + * 2/ that any changes to this code are clearly commented + * as such so that the author does not get blamed for bugs + * other than his own. + */ + +#ifndef HAGGIS_LINKMAP +#define HAGGIS_LINKMAP 1 + +#include "haggis.h" +#include +#include +#include +#include +#include + +#define HAGGIS_BUCKETS_BASE 64 + +struct _haggis_link { + struct _haggis_link *next; + char *path; +}; + +typedef struct _haggis_link haggis_link; + +typedef struct { + union { + ino_t val; + u8 bytes[sizeof(ino_t)]; + } *key; + uint64_t hash; + char * target; + haggis_link *links; +} haggis_linkmap_node; + +typedef struct { + pthread_mutex_t *mutex; + size_t len; + size_t capacity; + haggis_linkmap_node *buckets; +} haggis_linkmap; + +#endif // !HAGGIS_LINKMAP diff --git a/linkmap.c b/linkmap.c new file mode 100644 index 0000000..6a4e8cf --- /dev/null +++ b/linkmap.c @@ -0,0 +1,106 @@ +/* _,.---._ .-._ .--.-. ,--.--------. + * _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\ + * /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./ + * |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \ + * |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \ + * |==|,| | -|==| , '=' |==| - _ | |==|- | + * |==| '=' /\==\ - ,_ /|==| /\ , | |==|, | + * |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/ + * `-.`.____.' `--`--'' `--`./ `--` `--`--` + * _ __ ,---. .-._ .=-.-. _,.----. + * .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \ + * /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-' + * |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | . + * |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \ + * |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , | + * |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. / + * /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-' + * `--`---' `--` `--`./ `--``--`-` + * + * @(#)Copyright (c) 2023, Nathan D. Fisher. + * + * This is free software. It comes with NO WARRANTY. + * Permission to use, modify and distribute this source code + * is granted subject to the following conditions. + * 1/ that the above copyright notice and this notice + * are preserved in all copies and that due credit be given + * to the author. + * 2/ that any changes to this code are clearly commented + * as such so that the author does not get blamed for bugs + * other than his own. + */ + +#include "linkmap.h" +#include "haggis_private.h" +#include +#include +#include + +haggis_link* haggis_link_init(char* path) { + haggis_link *link; + + link = calloc(1, sizeof(haggis_link)); + if (link == NULL) return NULL; + link->path = path; + return link; +} + +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); + free(nod); +} + +int haggis_linkmap_expand(haggis_linkmap *map) { + haggis_linkmap_node *buckets_new; + haggis_linkmap_node *buckets_old; + size_t i, hash, idx; + + buckets_new = calloc(map->capacity + HAGGIS_BUCKETS_BASE, sizeof(haggis_linkmap_node)); + 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)); + map ->capacity += HAGGIS_BUCKETS_BASE; + idx = map->capacity % hash; + buckets_new[idx] = map->buckets[i]; + } + } + buckets_old = map->buckets; + map->buckets = buckets_new; + free(buckets_old); + map->capacity += HAGGIS_BUCKETS_BASE; + return 0; +}