diff --git a/Makefile b/Makefile index cb6804c..ccbfd23 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ libhaggis.a: $(objs) libhaggis.so: $(objs) $(CC) -shared -o $@ $? $(LIBS) -install: libhaggis.a libhaggis.so haggis.h +install: libhaggis.a libhaggis.so include/haggis.h [ -d $(includedir) ] || install -d $(includedir) [ -d $(libdir) ] || install -d $(libdir) install -m755 libhaggis.so $(libdir)/ diff --git a/include/linkmap.h b/include/linkmap.h index 9be4722..73ba10c 100644 --- a/include/linkmap.h +++ b/include/linkmap.h @@ -53,7 +53,7 @@ typedef struct __bucket { } haggis_bucket; typedef struct { - pthread_mutex_t *mutex; + pthread_mutex_t mutex; size_t len; size_t capacity; haggis_bucket *buckets; diff --git a/linkmap.c b/linkmap.c index f7357f6..5fa9d04 100644 --- a/linkmap.c +++ b/linkmap.c @@ -65,6 +65,21 @@ void haggis_bucket_append(haggis_bucket *head, haggis_bucket *tail) { head->next = tail; } +haggis_linkmap* haggis_linkmap_init() { + haggis_linkmap *map; + + map = calloc(1, sizeof(haggis_linkmap)); + if (map == NULL) + return NULL; + map->buckets = calloc(HAGGIS_BUCKETS_BASE, sizeof(size_t)); + if (map->buckets == NULL) { + free(map); + return NULL; + } + map->capacity = HAGGIS_BUCKETS_BASE; + return map; +} + int haggis_linkmap_expand(haggis_linkmap *map) { haggis_bucket *buckets_new; haggis_bucket *buckets_old; @@ -95,23 +110,31 @@ char* haggis_linkmap_get_or_add(haggis_linkmap *map, ino_t inode, char * path) { } key; char * target = NULL; size_t idx, hash; + int i; - pthread_mutex_lock(map->mutex); + pthread_mutex_lock(&map->mutex); + if (map->len >= map->capacity) + haggis_linkmap_expand(map); 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; + for (i = 0; i < map->capacity; i++) { + if (map->buckets[idx].key.val == 0) { + map->buckets[idx].key.val = inode; + map->buckets[idx].hash = hash; + map->buckets[idx].path = path; + map->len++; + pthread_mutex_unlock(&map->mutex); + break; + } else if (map->buckets[idx].key.val == inode) { + target = strndup(target, PATH_MAX - 1); + pthread_mutex_unlock(&map->mutex); + break; + } + if (idx == map->capacity - 1) + idx = 0; + else + idx++; } - // todo: if buckets[idx] has a different value stored, loop until we find an - // empty slot or a slot with the correct value (whichever is first) - return NULL; + return target; }