ruby-minigraph 0.0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +62 -0
- data/ext/Rakefile +56 -0
- data/ext/cmappy/cmappy.c +7 -0
- data/ext/cmappy/cmappy.h +8 -0
- data/ext/minigraph/LICENSE.txt +23 -0
- data/ext/minigraph/Makefile +66 -0
- data/ext/minigraph/NEWS.md +317 -0
- data/ext/minigraph/README.md +207 -0
- data/ext/minigraph/algo.c +194 -0
- data/ext/minigraph/algo.h +33 -0
- data/ext/minigraph/asm-call.c +147 -0
- data/ext/minigraph/bseq.c +133 -0
- data/ext/minigraph/bseq.h +76 -0
- data/ext/minigraph/cal_cov.c +139 -0
- data/ext/minigraph/doc/example1.png +0 -0
- data/ext/minigraph/doc/example2.png +0 -0
- data/ext/minigraph/doc/examples.graffle +0 -0
- data/ext/minigraph/format.c +241 -0
- data/ext/minigraph/galign.c +140 -0
- data/ext/minigraph/gchain1.c +532 -0
- data/ext/minigraph/gcmisc.c +223 -0
- data/ext/minigraph/gfa-aug.c +260 -0
- data/ext/minigraph/gfa-base.c +526 -0
- data/ext/minigraph/gfa-bbl.c +372 -0
- data/ext/minigraph/gfa-ed.c +617 -0
- data/ext/minigraph/gfa-io.c +395 -0
- data/ext/minigraph/gfa-priv.h +154 -0
- data/ext/minigraph/gfa.h +166 -0
- data/ext/minigraph/ggen.c +182 -0
- data/ext/minigraph/ggen.h +21 -0
- data/ext/minigraph/ggsimple.c +570 -0
- data/ext/minigraph/gmap.c +211 -0
- data/ext/minigraph/index.c +230 -0
- data/ext/minigraph/kalloc.c +224 -0
- data/ext/minigraph/kalloc.h +82 -0
- data/ext/minigraph/kavl.h +414 -0
- data/ext/minigraph/kdq.h +134 -0
- data/ext/minigraph/ketopt.h +116 -0
- data/ext/minigraph/khashl.h +348 -0
- data/ext/minigraph/krmq.h +474 -0
- data/ext/minigraph/kseq.h +256 -0
- data/ext/minigraph/ksort.h +164 -0
- data/ext/minigraph/kstring.h +165 -0
- data/ext/minigraph/kthread.c +159 -0
- data/ext/minigraph/kthread.h +15 -0
- data/ext/minigraph/kvec-km.h +105 -0
- data/ext/minigraph/kvec.h +110 -0
- data/ext/minigraph/lchain.c +441 -0
- data/ext/minigraph/main.c +301 -0
- data/ext/minigraph/map-algo.c +500 -0
- data/ext/minigraph/mgpriv.h +128 -0
- data/ext/minigraph/minigraph.1 +359 -0
- data/ext/minigraph/minigraph.h +176 -0
- data/ext/minigraph/miniwfa.c +834 -0
- data/ext/minigraph/miniwfa.h +95 -0
- data/ext/minigraph/misc/mgutils.js +1451 -0
- data/ext/minigraph/misc.c +12 -0
- data/ext/minigraph/options.c +134 -0
- data/ext/minigraph/shortk.c +251 -0
- data/ext/minigraph/sketch.c +109 -0
- data/ext/minigraph/sys.c +147 -0
- data/ext/minigraph/sys.h +20 -0
- data/ext/minigraph/test/MT-chimp.fa +277 -0
- data/ext/minigraph/test/MT-human.fa +239 -0
- data/ext/minigraph/test/MT-orangA.fa +276 -0
- data/ext/minigraph/test/MT.gfa +19 -0
- data/ext/minigraph/tex/Makefile +13 -0
- data/ext/minigraph/tex/minigraph.bib +676 -0
- data/ext/minigraph/tex/minigraph.tex +986 -0
- data/ext/minigraph/tex/plots/CHM13-f1-90.bb.anno.gp +42 -0
- data/ext/minigraph/tex/plots/CHM13-f1-90.bb.anno.tbl +13 -0
- data/ext/minigraph/tex/plots/CHM13-f1-90.bb.mini-inter-none.win.gp +269 -0
- data/ext/minigraph/tex/plots/CHM13-f1-90.bb.mini-inter-none.win.sh +7 -0
- data/ext/minigraph/tex/plots/CHM13v1.cen.bed +23 -0
- data/ext/minigraph/tex/plots/CHM13v1.size +23 -0
- data/ext/minigraph/tex/plots/anno2tbl.js +40 -0
- data/ext/minigraph/tex/plots/bedutils.js +367 -0
- data/ext/minigraph/tex/plots/chr-plot.js +130 -0
- data/ext/minigraph/tex/plots/gen-anno.mak +24 -0
- data/ext/minigraph.patch +21 -0
- data/lib/minigraph/ffi/constants.rb +230 -0
- data/lib/minigraph/ffi/functions.rb +70 -0
- data/lib/minigraph/ffi/mappy.rb +8 -0
- data/lib/minigraph/ffi.rb +27 -0
- data/lib/minigraph/version.rb +5 -0
- data/lib/minigraph.rb +72 -0
- metadata +159 -0
@@ -0,0 +1,116 @@
|
|
1
|
+
#ifndef KETOPT_H
|
2
|
+
#define KETOPT_H
|
3
|
+
|
4
|
+
#include <string.h> /* for strchr() and strncmp() */
|
5
|
+
|
6
|
+
#define ko_no_argument 0
|
7
|
+
#define ko_required_argument 1
|
8
|
+
#define ko_optional_argument 2
|
9
|
+
|
10
|
+
typedef struct {
|
11
|
+
int ind; /* equivalent to optind */
|
12
|
+
int opt; /* equivalent to optopt */
|
13
|
+
char *arg; /* equivalent to optarg */
|
14
|
+
int longidx; /* index of a long option; or -1 if short */
|
15
|
+
/* private variables not intended for external uses */
|
16
|
+
int i, pos, n_args;
|
17
|
+
} ketopt_t;
|
18
|
+
|
19
|
+
typedef struct {
|
20
|
+
char *name;
|
21
|
+
int has_arg;
|
22
|
+
int val;
|
23
|
+
} ko_longopt_t;
|
24
|
+
|
25
|
+
static ketopt_t KETOPT_INIT = { 1, 0, 0, -1, 1, 0, 0 };
|
26
|
+
|
27
|
+
static void ketopt_permute(char *argv[], int j, int n) /* move argv[j] over n elements to the left */
|
28
|
+
{
|
29
|
+
int k;
|
30
|
+
char *p = argv[j];
|
31
|
+
for (k = 0; k < n; ++k)
|
32
|
+
argv[j - k] = argv[j - k - 1];
|
33
|
+
argv[j - k] = p;
|
34
|
+
}
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Parse command-line options and arguments
|
38
|
+
*
|
39
|
+
* This fuction has a similar interface to GNU's getopt_long(). Each call
|
40
|
+
* parses one option and returns the option name. s->arg points to the option
|
41
|
+
* argument if present. The function returns -1 when all command-line arguments
|
42
|
+
* are parsed. In this case, s->ind is the index of the first non-option
|
43
|
+
* argument.
|
44
|
+
*
|
45
|
+
* @param s status; shall be initialized to KETOPT_INIT on the first call
|
46
|
+
* @param argc length of argv[]
|
47
|
+
* @param argv list of command-line arguments; argv[0] is ignored
|
48
|
+
* @param permute non-zero to move options ahead of non-option arguments
|
49
|
+
* @param ostr option string
|
50
|
+
* @param longopts long options
|
51
|
+
*
|
52
|
+
* @return ASCII for a short option; ko_longopt_t::val for a long option; -1 if
|
53
|
+
* argv[] is fully processed; '?' for an unknown option or an ambiguous
|
54
|
+
* long option; ':' if an option argument is missing
|
55
|
+
*/
|
56
|
+
static int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *ostr, const ko_longopt_t *longopts)
|
57
|
+
{
|
58
|
+
int opt = -1, i0, j;
|
59
|
+
if (permute) {
|
60
|
+
while (s->i < argc && (argv[s->i][0] != '-' || argv[s->i][1] == '\0'))
|
61
|
+
++s->i, ++s->n_args;
|
62
|
+
}
|
63
|
+
s->arg = 0, s->longidx = -1, i0 = s->i;
|
64
|
+
if (s->i >= argc || argv[s->i][0] != '-' || argv[s->i][1] == '\0') {
|
65
|
+
s->ind = s->i - s->n_args;
|
66
|
+
return -1;
|
67
|
+
}
|
68
|
+
if (argv[s->i][0] == '-' && argv[s->i][1] == '-') { /* "--" or a long option */
|
69
|
+
if (argv[s->i][2] == '\0') { /* a bare "--" */
|
70
|
+
ketopt_permute(argv, s->i, s->n_args);
|
71
|
+
++s->i, s->ind = s->i - s->n_args;
|
72
|
+
return -1;
|
73
|
+
}
|
74
|
+
s->opt = 0, opt = '?', s->pos = -1;
|
75
|
+
if (longopts) { /* parse long options */
|
76
|
+
int k, n_matches = 0;
|
77
|
+
const ko_longopt_t *o = 0;
|
78
|
+
for (j = 2; argv[s->i][j] != '\0' && argv[s->i][j] != '='; ++j) {} /* find the end of the option name */
|
79
|
+
for (k = 0; longopts[k].name != 0; ++k)
|
80
|
+
if (strncmp(&argv[s->i][2], longopts[k].name, j - 2) == 0)
|
81
|
+
++n_matches, o = &longopts[k];
|
82
|
+
if (n_matches == 1) {
|
83
|
+
s->opt = opt = o->val, s->longidx = o - longopts;
|
84
|
+
if (argv[s->i][j] == '=') s->arg = &argv[s->i][j + 1];
|
85
|
+
if (o->has_arg == 1 && argv[s->i][j] == '\0') {
|
86
|
+
if (s->i < argc - 1) s->arg = argv[++s->i];
|
87
|
+
else opt = ':'; /* missing option argument */
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
} else { /* a short option */
|
92
|
+
char *p;
|
93
|
+
if (s->pos == 0) s->pos = 1;
|
94
|
+
opt = s->opt = argv[s->i][s->pos++];
|
95
|
+
p = strchr((char*)ostr, opt);
|
96
|
+
if (p == 0) {
|
97
|
+
opt = '?'; /* unknown option */
|
98
|
+
} else if (p[1] == ':') {
|
99
|
+
if (argv[s->i][s->pos] == 0) {
|
100
|
+
if (s->i < argc - 1) s->arg = argv[++s->i];
|
101
|
+
else opt = ':'; /* missing option argument */
|
102
|
+
} else s->arg = &argv[s->i][s->pos];
|
103
|
+
s->pos = -1;
|
104
|
+
}
|
105
|
+
}
|
106
|
+
if (s->pos < 0 || argv[s->i][s->pos] == 0) {
|
107
|
+
++s->i, s->pos = 0;
|
108
|
+
if (s->n_args > 0) /* permute */
|
109
|
+
for (j = i0; j < s->i; ++j)
|
110
|
+
ketopt_permute(argv, j, s->n_args);
|
111
|
+
}
|
112
|
+
s->ind = s->i - s->n_args;
|
113
|
+
return opt;
|
114
|
+
}
|
115
|
+
|
116
|
+
#endif
|
@@ -0,0 +1,348 @@
|
|
1
|
+
/* The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2019 by Attractive Chaos <attractor@live.co.uk>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
20
|
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
21
|
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
22
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
SOFTWARE.
|
24
|
+
*/
|
25
|
+
|
26
|
+
#ifndef __AC_KHASHL_H
|
27
|
+
#define __AC_KHASHL_H
|
28
|
+
|
29
|
+
#define AC_VERSION_KHASHL_H "0.1"
|
30
|
+
|
31
|
+
#include <stdlib.h>
|
32
|
+
#include <string.h>
|
33
|
+
#include <limits.h>
|
34
|
+
#include "kalloc.h"
|
35
|
+
|
36
|
+
/************************************
|
37
|
+
* Compiler specific configurations *
|
38
|
+
************************************/
|
39
|
+
|
40
|
+
#if UINT_MAX == 0xffffffffu
|
41
|
+
typedef unsigned int khint32_t;
|
42
|
+
#elif ULONG_MAX == 0xffffffffu
|
43
|
+
typedef unsigned long khint32_t;
|
44
|
+
#endif
|
45
|
+
|
46
|
+
#if ULONG_MAX == ULLONG_MAX
|
47
|
+
typedef unsigned long khint64_t;
|
48
|
+
#else
|
49
|
+
typedef unsigned long long khint64_t;
|
50
|
+
#endif
|
51
|
+
|
52
|
+
#ifndef kh_inline
|
53
|
+
#ifdef _MSC_VER
|
54
|
+
#define kh_inline __inline
|
55
|
+
#else
|
56
|
+
#define kh_inline inline
|
57
|
+
#endif
|
58
|
+
#endif /* kh_inline */
|
59
|
+
|
60
|
+
#ifndef klib_unused
|
61
|
+
#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3)
|
62
|
+
#define klib_unused __attribute__ ((__unused__))
|
63
|
+
#else
|
64
|
+
#define klib_unused
|
65
|
+
#endif
|
66
|
+
#endif /* klib_unused */
|
67
|
+
|
68
|
+
#define KH_LOCAL static kh_inline klib_unused
|
69
|
+
|
70
|
+
typedef khint32_t khint_t;
|
71
|
+
|
72
|
+
/****************************
|
73
|
+
* Simple private functions *
|
74
|
+
****************************/
|
75
|
+
|
76
|
+
#define __kh_used(flag, i) (flag[i>>5] >> (i&0x1fU) & 1U)
|
77
|
+
#define __kh_set_used(flag, i) (flag[i>>5] |= 1U<<(i&0x1fU))
|
78
|
+
#define __kh_set_unused(flag, i) (flag[i>>5] &= ~(1U<<(i&0x1fU)))
|
79
|
+
|
80
|
+
#define __kh_fsize(m) ((m) < 32? 1 : (m)>>5)
|
81
|
+
|
82
|
+
static kh_inline khint_t __kh_h2b(khint_t hash, khint_t bits) { return hash * 2654435769U >> (32 - bits); }
|
83
|
+
|
84
|
+
/*******************
|
85
|
+
* Hash table base *
|
86
|
+
*******************/
|
87
|
+
|
88
|
+
#define __KHASHL_TYPE(HType, khkey_t) \
|
89
|
+
typedef struct HType { \
|
90
|
+
khint_t bits, count; \
|
91
|
+
khint32_t *used; \
|
92
|
+
khkey_t *keys; \
|
93
|
+
void *km; \
|
94
|
+
} HType;
|
95
|
+
|
96
|
+
#define __KHASHL_PROTOTYPES(HType, prefix, khkey_t) \
|
97
|
+
extern HType *prefix##_init2(void *km); \
|
98
|
+
extern HType *prefix##_init(void); \
|
99
|
+
extern void prefix##_destroy(HType *h); \
|
100
|
+
extern void prefix##_clear(HType *h); \
|
101
|
+
extern khint_t prefix##_getp(const HType *h, const khkey_t *key); \
|
102
|
+
extern int prefix##_resize(HType *h, khint_t new_n_buckets); \
|
103
|
+
extern khint_t prefix##_putp(HType *h, const khkey_t *key, int *absent); \
|
104
|
+
extern void prefix##_del(HType *h, khint_t k);
|
105
|
+
|
106
|
+
#define __KHASHL_IMPL_BASIC(SCOPE, HType, prefix) \
|
107
|
+
SCOPE HType *prefix##_init2(void *km) { \
|
108
|
+
HType *h; \
|
109
|
+
h = (HType*)kcalloc(km, 1, sizeof(HType)); \
|
110
|
+
h->km = km; \
|
111
|
+
return h; \
|
112
|
+
} \
|
113
|
+
SCOPE HType *prefix##_init(void) { return prefix##_init2(0); } \
|
114
|
+
SCOPE void prefix##_destroy(HType *h) { \
|
115
|
+
void *km; \
|
116
|
+
if (!h) return; \
|
117
|
+
km = h->km; \
|
118
|
+
kfree(km, (void*)h->keys); kfree(km, h->used); \
|
119
|
+
kfree(km, h); \
|
120
|
+
} \
|
121
|
+
SCOPE void prefix##_clear(HType *h) { \
|
122
|
+
if (h && h->used) { \
|
123
|
+
uint32_t n_buckets = 1U << h->bits; \
|
124
|
+
memset(h->used, 0, __kh_fsize(n_buckets) * sizeof(khint32_t)); \
|
125
|
+
h->count = 0; \
|
126
|
+
} \
|
127
|
+
}
|
128
|
+
|
129
|
+
#define __KHASHL_IMPL_GET(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
130
|
+
SCOPE khint_t prefix##_getp(const HType *h, const khkey_t *key) { \
|
131
|
+
khint_t i, last, n_buckets, mask; \
|
132
|
+
if (h->keys == 0) return 0; \
|
133
|
+
n_buckets = 1U << h->bits; \
|
134
|
+
mask = n_buckets - 1U; \
|
135
|
+
i = last = __kh_h2b(__hash_fn(*key), h->bits); \
|
136
|
+
while (__kh_used(h->used, i) && !__hash_eq(h->keys[i], *key)) { \
|
137
|
+
i = (i + 1U) & mask; \
|
138
|
+
if (i == last) return n_buckets; \
|
139
|
+
} \
|
140
|
+
return !__kh_used(h->used, i)? n_buckets : i; \
|
141
|
+
} \
|
142
|
+
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { return prefix##_getp(h, &key); }
|
143
|
+
|
144
|
+
#define __KHASHL_IMPL_RESIZE(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
145
|
+
SCOPE int prefix##_resize(HType *h, khint_t new_n_buckets) { \
|
146
|
+
khint32_t *new_used = 0; \
|
147
|
+
khint_t j = 0, x = new_n_buckets, n_buckets, new_bits, new_mask; \
|
148
|
+
while ((x >>= 1) != 0) ++j; \
|
149
|
+
if (new_n_buckets & (new_n_buckets - 1)) ++j; \
|
150
|
+
new_bits = j > 2? j : 2; \
|
151
|
+
new_n_buckets = 1U << new_bits; \
|
152
|
+
if (h->count > (new_n_buckets>>1) + (new_n_buckets>>2)) return 0; /* requested size is too small */ \
|
153
|
+
new_used = (khint32_t*)kmalloc(h->km, __kh_fsize(new_n_buckets) * sizeof(khint32_t)); \
|
154
|
+
memset(new_used, 0, __kh_fsize(new_n_buckets) * sizeof(khint32_t)); \
|
155
|
+
if (!new_used) return -1; /* not enough memory */ \
|
156
|
+
n_buckets = h->keys? 1U<<h->bits : 0U; \
|
157
|
+
if (n_buckets < new_n_buckets) { /* expand */ \
|
158
|
+
khkey_t *new_keys = (khkey_t*)krealloc(h->km, (void*)h->keys, new_n_buckets * sizeof(khkey_t)); \
|
159
|
+
if (!new_keys) { kfree(h->km, new_used); return -1; } \
|
160
|
+
h->keys = new_keys; \
|
161
|
+
} /* otherwise shrink */ \
|
162
|
+
new_mask = new_n_buckets - 1; \
|
163
|
+
for (j = 0; j != n_buckets; ++j) { \
|
164
|
+
khkey_t key; \
|
165
|
+
if (!__kh_used(h->used, j)) continue; \
|
166
|
+
key = h->keys[j]; \
|
167
|
+
__kh_set_unused(h->used, j); \
|
168
|
+
while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \
|
169
|
+
khint_t i; \
|
170
|
+
i = __kh_h2b(__hash_fn(key), new_bits); \
|
171
|
+
while (__kh_used(new_used, i)) i = (i + 1) & new_mask; \
|
172
|
+
__kh_set_used(new_used, i); \
|
173
|
+
if (i < n_buckets && __kh_used(h->used, i)) { /* kick out the existing element */ \
|
174
|
+
{ khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
|
175
|
+
__kh_set_unused(h->used, i); /* mark it as deleted in the old hash table */ \
|
176
|
+
} else { /* write the element and jump out of the loop */ \
|
177
|
+
h->keys[i] = key; \
|
178
|
+
break; \
|
179
|
+
} \
|
180
|
+
} \
|
181
|
+
} \
|
182
|
+
if (n_buckets > new_n_buckets) /* shrink the hash table */ \
|
183
|
+
h->keys = (khkey_t*)krealloc(h->km, (void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
|
184
|
+
kfree(h->km, h->used); /* free the working space */ \
|
185
|
+
h->used = new_used, h->bits = new_bits; \
|
186
|
+
return 0; \
|
187
|
+
}
|
188
|
+
|
189
|
+
#define __KHASHL_IMPL_PUT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
190
|
+
SCOPE khint_t prefix##_putp(HType *h, const khkey_t *key, int *absent) { \
|
191
|
+
khint_t n_buckets, i, last, mask; \
|
192
|
+
n_buckets = h->keys? 1U<<h->bits : 0U; \
|
193
|
+
*absent = -1; \
|
194
|
+
if (h->count >= (n_buckets>>1) + (n_buckets>>2)) { /* rehashing */ \
|
195
|
+
if (prefix##_resize(h, n_buckets + 1U) < 0) \
|
196
|
+
return n_buckets; \
|
197
|
+
n_buckets = 1U<<h->bits; \
|
198
|
+
} /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
|
199
|
+
mask = n_buckets - 1; \
|
200
|
+
i = last = __kh_h2b(__hash_fn(*key), h->bits); \
|
201
|
+
while (__kh_used(h->used, i) && !__hash_eq(h->keys[i], *key)) { \
|
202
|
+
i = (i + 1U) & mask; \
|
203
|
+
if (i == last) break; \
|
204
|
+
} \
|
205
|
+
if (!__kh_used(h->used, i)) { /* not present at all */ \
|
206
|
+
h->keys[i] = *key; \
|
207
|
+
__kh_set_used(h->used, i); \
|
208
|
+
++h->count; \
|
209
|
+
*absent = 1; \
|
210
|
+
} else *absent = 0; /* Don't touch h->keys[i] if present */ \
|
211
|
+
return i; \
|
212
|
+
} \
|
213
|
+
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { return prefix##_putp(h, &key, absent); }
|
214
|
+
|
215
|
+
#define __KHASHL_IMPL_DEL(SCOPE, HType, prefix, khkey_t, __hash_fn) \
|
216
|
+
SCOPE int prefix##_del(HType *h, khint_t i) { \
|
217
|
+
khint_t j = i, k, mask, n_buckets; \
|
218
|
+
if (h->keys == 0) return 0; \
|
219
|
+
n_buckets = 1U<<h->bits; \
|
220
|
+
mask = n_buckets - 1U; \
|
221
|
+
while (1) { \
|
222
|
+
j = (j + 1U) & mask; \
|
223
|
+
if (j == i || !__kh_used(h->used, j)) break; /* j==i only when the table is completely full */ \
|
224
|
+
k = __kh_h2b(__hash_fn(h->keys[j]), h->bits); \
|
225
|
+
if ((j > i && (k <= i || k > j)) || (j < i && (k <= i && k > j))) \
|
226
|
+
h->keys[i] = h->keys[j], i = j; \
|
227
|
+
} \
|
228
|
+
__kh_set_unused(h->used, i); \
|
229
|
+
--h->count; \
|
230
|
+
return 1; \
|
231
|
+
}
|
232
|
+
|
233
|
+
#define KHASHL_DECLARE(HType, prefix, khkey_t) \
|
234
|
+
__KHASHL_TYPE(HType, khkey_t) \
|
235
|
+
__KHASHL_PROTOTYPES(HType, prefix, khkey_t)
|
236
|
+
|
237
|
+
#define KHASHL_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
238
|
+
__KHASHL_TYPE(HType, khkey_t) \
|
239
|
+
__KHASHL_IMPL_BASIC(SCOPE, HType, prefix) \
|
240
|
+
__KHASHL_IMPL_GET(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
241
|
+
__KHASHL_IMPL_RESIZE(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
242
|
+
__KHASHL_IMPL_PUT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
243
|
+
__KHASHL_IMPL_DEL(SCOPE, HType, prefix, khkey_t, __hash_fn)
|
244
|
+
|
245
|
+
/*****************************
|
246
|
+
* More convenient interface *
|
247
|
+
*****************************/
|
248
|
+
|
249
|
+
#define __kh_packed __attribute__ ((__packed__))
|
250
|
+
#define __kh_cached_hash(x) ((x).hash)
|
251
|
+
|
252
|
+
#define KHASHL_SET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
253
|
+
typedef struct { khkey_t key; } __kh_packed HType##_s_bucket_t; \
|
254
|
+
static kh_inline khint_t prefix##_s_hash(HType##_s_bucket_t x) { return __hash_fn(x.key); } \
|
255
|
+
static kh_inline int prefix##_s_eq(HType##_s_bucket_t x, HType##_s_bucket_t y) { return __hash_eq(x.key, y.key); } \
|
256
|
+
KHASHL_INIT(KH_LOCAL, HType, prefix##_s, HType##_s_bucket_t, prefix##_s_hash, prefix##_s_eq) \
|
257
|
+
SCOPE HType *prefix##_init2(void *km) { return prefix##_s_init2(km); } \
|
258
|
+
SCOPE HType *prefix##_init(void) { return prefix##_s_init(); } \
|
259
|
+
SCOPE void prefix##_destroy(HType *h) { prefix##_s_destroy(h); } \
|
260
|
+
SCOPE void prefix##_resize(HType *h, khint_t new_n_buckets) { prefix##_s_resize(h, new_n_buckets); } \
|
261
|
+
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_s_bucket_t t; t.key = key; return prefix##_s_getp(h, &t); } \
|
262
|
+
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_s_del(h, k); } \
|
263
|
+
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_s_bucket_t t; t.key = key; return prefix##_s_putp(h, &t, absent); }
|
264
|
+
|
265
|
+
#define KHASHL_MAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
|
266
|
+
typedef struct { khkey_t key; kh_val_t val; } __kh_packed HType##_m_bucket_t; \
|
267
|
+
static kh_inline khint_t prefix##_m_hash(HType##_m_bucket_t x) { return __hash_fn(x.key); } \
|
268
|
+
static kh_inline int prefix##_m_eq(HType##_m_bucket_t x, HType##_m_bucket_t y) { return __hash_eq(x.key, y.key); } \
|
269
|
+
KHASHL_INIT(KH_LOCAL, HType, prefix##_m, HType##_m_bucket_t, prefix##_m_hash, prefix##_m_eq) \
|
270
|
+
SCOPE HType *prefix##_init2(void *km) { return prefix##_m_init2(km); } \
|
271
|
+
SCOPE HType *prefix##_init(void) { return prefix##_m_init(); } \
|
272
|
+
SCOPE void prefix##_destroy(HType *h) { prefix##_m_destroy(h); } \
|
273
|
+
SCOPE void prefix##_resize(HType *h, khint_t new_n_buckets) { prefix##_m_resize(h, new_n_buckets); } \
|
274
|
+
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_m_bucket_t t; t.key = key; return prefix##_m_getp(h, &t); } \
|
275
|
+
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_m_del(h, k); } \
|
276
|
+
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_m_bucket_t t; t.key = key; return prefix##_m_putp(h, &t, absent); }
|
277
|
+
|
278
|
+
#define KHASHL_CSET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
279
|
+
typedef struct { khkey_t key; khint_t hash; } __kh_packed HType##_cs_bucket_t; \
|
280
|
+
static kh_inline int prefix##_cs_eq(HType##_cs_bucket_t x, HType##_cs_bucket_t y) { return x.hash == y.hash && __hash_eq(x.key, y.key); } \
|
281
|
+
KHASHL_INIT(KH_LOCAL, HType, prefix##_cs, HType##_cs_bucket_t, __kh_cached_hash, prefix##_cs_eq) \
|
282
|
+
SCOPE HType *prefix##_init(void) { return prefix##_cs_init(); } \
|
283
|
+
SCOPE void prefix##_destroy(HType *h) { prefix##_cs_destroy(h); } \
|
284
|
+
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_cs_bucket_t t; t.key = key; t.hash = __hash_fn(key); return prefix##_cs_getp(h, &t); } \
|
285
|
+
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_cs_del(h, k); } \
|
286
|
+
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_cs_bucket_t t; t.key = key, t.hash = __hash_fn(key); return prefix##_cs_putp(h, &t, absent); }
|
287
|
+
|
288
|
+
#define KHASHL_CMAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
|
289
|
+
typedef struct { khkey_t key; kh_val_t val; khint_t hash; } __kh_packed HType##_cm_bucket_t; \
|
290
|
+
static kh_inline int prefix##_cm_eq(HType##_cm_bucket_t x, HType##_cm_bucket_t y) { return x.hash == y.hash && __hash_eq(x.key, y.key); } \
|
291
|
+
KHASHL_INIT(KH_LOCAL, HType, prefix##_cm, HType##_cm_bucket_t, __kh_cached_hash, prefix##_cm_eq) \
|
292
|
+
SCOPE HType *prefix##_init(void) { return prefix##_cm_init(); } \
|
293
|
+
SCOPE void prefix##_destroy(HType *h) { prefix##_cm_destroy(h); } \
|
294
|
+
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_cm_bucket_t t; t.key = key; t.hash = __hash_fn(key); return prefix##_cm_getp(h, &t); } \
|
295
|
+
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_cm_del(h, k); } \
|
296
|
+
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_cm_bucket_t t; t.key = key, t.hash = __hash_fn(key); return prefix##_cm_putp(h, &t, absent); }
|
297
|
+
|
298
|
+
/**************************
|
299
|
+
* Public macro functions *
|
300
|
+
**************************/
|
301
|
+
|
302
|
+
#define kh_bucket(h, x) ((h)->keys[x])
|
303
|
+
#define kh_size(h) ((h)->count)
|
304
|
+
#define kh_capacity(h) ((h)->keys? 1U<<(h)->bits : 0U)
|
305
|
+
#define kh_end(h) kh_capacity(h)
|
306
|
+
|
307
|
+
#define kh_key(h, x) ((h)->keys[x].key)
|
308
|
+
#define kh_val(h, x) ((h)->keys[x].val)
|
309
|
+
#define kh_exist(h, x) __kh_used((h)->used, (x))
|
310
|
+
|
311
|
+
/**************************************
|
312
|
+
* Common hash and equality functions *
|
313
|
+
**************************************/
|
314
|
+
|
315
|
+
#define kh_eq_generic(a, b) ((a) == (b))
|
316
|
+
#define kh_eq_str(a, b) (strcmp((a), (b)) == 0)
|
317
|
+
#define kh_hash_dummy(x) ((khint_t)(x))
|
318
|
+
|
319
|
+
typedef const char *kh_cstr_t;
|
320
|
+
|
321
|
+
static kh_inline khint_t kh_hash_uint32(khint_t key) {
|
322
|
+
key += ~(key << 15);
|
323
|
+
key ^= (key >> 10);
|
324
|
+
key += (key << 3);
|
325
|
+
key ^= (key >> 6);
|
326
|
+
key += ~(key << 11);
|
327
|
+
key ^= (key >> 16);
|
328
|
+
return key;
|
329
|
+
}
|
330
|
+
|
331
|
+
static kh_inline khint_t kh_hash_uint64(khint64_t key) {
|
332
|
+
key = ~key + (key << 21);
|
333
|
+
key = key ^ key >> 24;
|
334
|
+
key = (key + (key << 3)) + (key << 8);
|
335
|
+
key = key ^ key >> 14;
|
336
|
+
key = (key + (key << 2)) + (key << 4);
|
337
|
+
key = key ^ key >> 28;
|
338
|
+
key = key + (key << 31);
|
339
|
+
return (khint_t)key;
|
340
|
+
}
|
341
|
+
|
342
|
+
static kh_inline khint_t kh_hash_str(const char *s) {
|
343
|
+
khint_t h = (khint_t)*s;
|
344
|
+
if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s;
|
345
|
+
return h;
|
346
|
+
}
|
347
|
+
|
348
|
+
#endif /* __AC_KHASHL_H */
|