From 061969d84cc3e98b85de60bd6c10900de200bc6f Mon Sep 17 00:00:00 2001 From: "Daniel N. Baker" Date: Sun, 6 Nov 2016 17:24:56 -0500 Subject: [PATCH 1/8] Add write/load functions. Fix documentation. --- khash.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/khash.h b/khash.h index e44f328..a2dbd81 100644 --- a/khash.h +++ b/khash.h @@ -169,6 +169,7 @@ typedef khint_t khiter_t; #define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) #define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) #define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) +#define __ac_fw(item, fp) (fwrite(&(item), 1, sizeof(item), fp)) #define __ac_fsize(m) ((m) < 16? 1 : (m)>>4) @@ -352,7 +353,39 @@ static const double __ac_HASH_UPPER = 0.77; __ac_set_isdel_true(h->flags, x); \ --h->size; \ } \ - } + } \ + SCOPE void kh_write_##name(kh_##name##_t *map, const char *path) { \ + FILE *fp = fopen(path, "wb"); \ + if(fp == NULL) { \ + fprintf(stderr, "[%s] Could not open file %s.\n", __func__, path);\ + exit(EXIT_FAILURE); \ + } \ + __ac_fw(map->n_buckets, fp); \ + __ac_fw(map->n_occupied, fp); \ + __ac_fw(map->size, fp); \ + __ac_fw(map->upper_bound, fp); \ + fwrite(map->flags, __ac_fsize(map->n_buckets), sizeof(khint32_t), fp);\ + fwrite(map->keys, map->n_buckets, sizeof(*map->keys), fp); \ + fwrite(map->vals, map->n_buckets, sizeof(*map->vals), fp); \ + fclose(fp); \ + } \ + SCOPE kh_##name##_t *khash_load_##name(const char *path) \ + { \ + kh_##name##_t *ret = calloc(1, sizeof(kh_##name##_t)); \ + FILE *fp = fopen(path, "rb"); \ + fread(&ret->n_buckets, 1, sizeof(ret->n_buckets), fp); \ + fread(&ret->n_occupied, 1, sizeof(ret->n_occupied), fp); \ + fread(&ret->size, 1, sizeof(ret->size), fp); \ + fread(&ret->upper_bound, 1, sizeof(ret->upper_bound), fp); \ + ret->flags = malloc(sizeof(*ret->flags) * __ac_fsize(ret->n_buckets));\ + ret->keys = malloc(sizeof(khkey_t) * ret->n_buckets); \ + ret->vals = malloc(sizeof(khval_t) * ret->n_buckets); \ + fread(ret->flags, __ac_fsize(ret->n_buckets), sizeof(*ret->flags), fp);\ + fread(ret->keys, 1, ret->n_buckets * sizeof(*ret->keys), fp); \ + fread(ret->vals, 1, ret->n_buckets * sizeof(*ret->vals), fp); \ + fclose(fp); \ + return ret; \ + } #define KHASH_DECLARE(name, khkey_t, khval_t) \ __KHASH_TYPE(name, khkey_t, khval_t) \ @@ -491,6 +524,21 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key) #define kh_del(name, h, k) kh_del_##name(h, k) /*! @function + @abstract Write a hash map to disk. + @param h Pointer to the hash table [khash_t(name)*] + @param path Path to which to write. [const char *] + */ +#define kh_write(name, h, path) kh_write_##name(h, path) + +/*! @function + @abstract Load a hash table from disk + @param name Name of the hash table [symbol] + @param path Path to file from which to load [const char *] + */ + +#define kh_load(name, path) khash_load_##name(path) + +/*! @function @abstract Test whether a bucket contains data. @param h Pointer to the hash table [khash_t(name)*] @param x Iterator to the bucket [khint_t] From 3277f0550d94fa8d9b35d074a974d6663601c4e8 Mon Sep 17 00:00:00 2001 From: Daniel Baker Date: Sat, 18 Mar 2017 01:26:31 -0400 Subject: [PATCH 2/8] Update khash.h --- khash.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/khash.h b/khash.h index a2dbd81..4daae14 100644 --- a/khash.h +++ b/khash.h @@ -366,7 +366,7 @@ static const double __ac_HASH_UPPER = 0.77; __ac_fw(map->upper_bound, fp); \ fwrite(map->flags, __ac_fsize(map->n_buckets), sizeof(khint32_t), fp);\ fwrite(map->keys, map->n_buckets, sizeof(*map->keys), fp); \ - fwrite(map->vals, map->n_buckets, sizeof(*map->vals), fp); \ + if(is_map) fwrite(map->vals, map->n_buckets, sizeof(*map->vals), fp); \ fclose(fp); \ } \ SCOPE kh_##name##_t *khash_load_##name(const char *path) \ @@ -379,10 +379,10 @@ static const double __ac_HASH_UPPER = 0.77; fread(&ret->upper_bound, 1, sizeof(ret->upper_bound), fp); \ ret->flags = malloc(sizeof(*ret->flags) * __ac_fsize(ret->n_buckets));\ ret->keys = malloc(sizeof(khkey_t) * ret->n_buckets); \ - ret->vals = malloc(sizeof(khval_t) * ret->n_buckets); \ + ret->vals = is_map ? malloc(sizeof(khval_t) * ret->n_buckets) : 0; \ fread(ret->flags, __ac_fsize(ret->n_buckets), sizeof(*ret->flags), fp);\ fread(ret->keys, 1, ret->n_buckets * sizeof(*ret->keys), fp); \ - fread(ret->vals, 1, ret->n_buckets * sizeof(*ret->vals), fp); \ + if(is_map) fread(ret->vals, 1, ret->n_buckets * sizeof(*ret->vals), fp); \ fclose(fp); \ return ret; \ } From 494da2ec77e4059bf3a5ca8561a1763e2a6bc2ad Mon Sep 17 00:00:00 2001 From: dnbh Date: Sat, 18 Mar 2017 03:20:04 -0400 Subject: [PATCH 3/8] Update write/read functions to work for both sets and maps. --- khash.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/khash.h b/khash.h index 4daae14..8942158 100644 --- a/khash.h +++ b/khash.h @@ -366,23 +366,23 @@ static const double __ac_HASH_UPPER = 0.77; __ac_fw(map->upper_bound, fp); \ fwrite(map->flags, __ac_fsize(map->n_buckets), sizeof(khint32_t), fp);\ fwrite(map->keys, map->n_buckets, sizeof(*map->keys), fp); \ - if(is_map) fwrite(map->vals, map->n_buckets, sizeof(*map->vals), fp); \ + if(kh_is_map) fwrite(map->vals, map->n_buckets, sizeof(*map->vals), fp); \ fclose(fp); \ } \ SCOPE kh_##name##_t *khash_load_##name(const char *path) \ { \ - kh_##name##_t *ret = calloc(1, sizeof(kh_##name##_t)); \ + kh_##name##_t *ret = (kh_##name##_t *)calloc(1, sizeof(kh_##name##_t)); \ FILE *fp = fopen(path, "rb"); \ fread(&ret->n_buckets, 1, sizeof(ret->n_buckets), fp); \ fread(&ret->n_occupied, 1, sizeof(ret->n_occupied), fp); \ fread(&ret->size, 1, sizeof(ret->size), fp); \ fread(&ret->upper_bound, 1, sizeof(ret->upper_bound), fp); \ - ret->flags = malloc(sizeof(*ret->flags) * __ac_fsize(ret->n_buckets));\ - ret->keys = malloc(sizeof(khkey_t) * ret->n_buckets); \ - ret->vals = is_map ? malloc(sizeof(khval_t) * ret->n_buckets) : 0; \ + ret->flags = (khint32_t *)malloc(sizeof(*ret->flags) * __ac_fsize(ret->n_buckets));\ + ret->keys = (khkey_t *)malloc(sizeof(khkey_t) * ret->n_buckets); \ + ret->vals = kh_is_map ? (khval_t *)malloc(sizeof(khval_t) * ret->n_buckets) : 0; \ fread(ret->flags, __ac_fsize(ret->n_buckets), sizeof(*ret->flags), fp);\ fread(ret->keys, 1, ret->n_buckets * sizeof(*ret->keys), fp); \ - if(is_map) fread(ret->vals, 1, ret->n_buckets * sizeof(*ret->vals), fp); \ + if(kh_is_map) fread(ret->vals, 1, ret->n_buckets * sizeof(*ret->vals), fp); \ fclose(fp); \ return ret; \ } From 9f5e92e56452c538e17c555b01d1f8b1b5afdc1b Mon Sep 17 00:00:00 2001 From: dnbh Date: Thu, 27 Apr 2017 18:56:36 -0400 Subject: [PATCH 4/8] Add kputuw_, kputw_, and kputl_ functions (which don't set 0). --- kstring.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/kstring.h b/kstring.h index f13fcd9..2328782 100644 --- a/kstring.h +++ b/kstring.h @@ -220,6 +220,29 @@ static inline int kputw(int c, kstring_t *s) return 0; } + +static inline int kputw_(int c, kstring_t *s) +{ + char buf[16]; + int i, l = 0; + unsigned int x = c; + if (c < 0) x = -x; + do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); + if (c < 0) buf[l++] = '-'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + return 0; +} + + static inline int kputuw(unsigned c, kstring_t *s) { char buf[16]; @@ -241,6 +264,29 @@ static inline int kputuw(unsigned c, kstring_t *s) return 0; } + +static inline int kputuw_(unsigned c, kstring_t *s) +{ + char buf[16]; + int l, i; + unsigned x; + if (c == 0) return kputc('0', s); + for (l = 0, x = c; x > 0; x /= 10) buf[l++] = x%10 + '0'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + s->s[s->l] = 0; + return 0; +} + + static inline int kputl(long c, kstring_t *s) { char buf[32]; @@ -263,6 +309,30 @@ static inline int kputl(long c, kstring_t *s) return 0; } + +static inline int kputl_(long c, kstring_t *s) +{ + char buf[32]; + int i, l = 0; + unsigned long x = c; + if (c < 0) x = -x; + do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); + if (c < 0) buf[l++] = '-'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + return 0; +} + +/* + /* * Returns 's' split by delimiter, with *n being the number of components; * NULL on failue. From 4375b21e98ef57da95a30f318b81324492ca0a1c Mon Sep 17 00:00:00 2001 From: dnbh Date: Thu, 27 Apr 2017 20:01:29 -0400 Subject: [PATCH 5/8] Eliminate -Wsign-compare. --- kstring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kstring.c b/kstring.c index 253d281..5adbe4f 100644 --- a/kstring.c +++ b/kstring.c @@ -12,7 +12,7 @@ int kvsprintf(kstring_t *s, const char *fmt, va_list ap) va_copy(args, ap); l = vsnprintf(s->s + s->l, s->m - s->l, fmt, args); // This line does not work with glibc 2.0. See `man snprintf'. va_end(args); - if (l + 1 > s->m - s->l) { + if ((unsigned)(l + 1) > s->m - s->l) { s->m = s->l + l + 2; kroundup32(s->m); s->s = (char*)realloc(s->s, s->m); From 121adbde7213ca53ee8d2cf8cf446c7bc4392895 Mon Sep 17 00:00:00 2001 From: dnbh Date: Thu, 15 Jun 2017 17:57:31 -0400 Subject: [PATCH 6/8] Modify kputuw_. --- kstring.h | 1 - 1 file changed, 1 deletion(-) diff --git a/kstring.h b/kstring.h index 2328782..e3da902 100644 --- a/kstring.h +++ b/kstring.h @@ -282,7 +282,6 @@ static inline int kputuw_(unsigned c, kstring_t *s) return EOF; } for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; - s->s[s->l] = 0; return 0; } From 309d5e58f8abe26e97c7d524003006653f511e71 Mon Sep 17 00:00:00 2001 From: dnbh Date: Thu, 15 Jun 2017 18:04:07 -0400 Subject: [PATCH 7/8] Add HAS_KPUTUW__ macro for checking for function definition. --- kstring.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kstring.h b/kstring.h index e3da902..71aec4d 100644 --- a/kstring.h +++ b/kstring.h @@ -264,7 +264,7 @@ static inline int kputuw(unsigned c, kstring_t *s) return 0; } - +#define HAS_KPUTUW__ static inline int kputuw_(unsigned c, kstring_t *s) { char buf[16]; From 69dc025bf91510597b800278a564864e6e397c24 Mon Sep 17 00:00:00 2001 From: dnbh Date: Thu, 15 Jun 2017 18:42:23 -0400 Subject: [PATCH 8/8] Finished moving things around. --- kstring.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kstring.h b/kstring.h index 71aec4d..89e46d3 100644 --- a/kstring.h +++ b/kstring.h @@ -264,6 +264,7 @@ static inline int kputuw(unsigned c, kstring_t *s) return 0; } +#ifndef HAS_KPUTUW__ #define HAS_KPUTUW__ static inline int kputuw_(unsigned c, kstring_t *s) { @@ -284,6 +285,7 @@ static inline int kputuw_(unsigned c, kstring_t *s) for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; return 0; } +#endif static inline int kputl(long c, kstring_t *s) @@ -331,8 +333,6 @@ static inline int kputl_(long c, kstring_t *s) } /* - -/* * Returns 's' split by delimiter, with *n being the number of components; * NULL on failue. */