ruby-minigraph 0.0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,159 @@
|
|
1
|
+
#include <pthread.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <limits.h>
|
4
|
+
#include <stdint.h>
|
5
|
+
#include "kthread.h"
|
6
|
+
|
7
|
+
#if (defined(WIN32) || defined(_WIN32)) && defined(_MSC_VER)
|
8
|
+
#define __sync_fetch_and_add(ptr, addend) _InterlockedExchangeAdd((void*)ptr, addend)
|
9
|
+
#endif
|
10
|
+
|
11
|
+
/************
|
12
|
+
* kt_for() *
|
13
|
+
************/
|
14
|
+
|
15
|
+
struct kt_for_t;
|
16
|
+
|
17
|
+
typedef struct {
|
18
|
+
struct kt_for_t *t;
|
19
|
+
long i;
|
20
|
+
} ktf_worker_t;
|
21
|
+
|
22
|
+
typedef struct kt_for_t {
|
23
|
+
int n_threads;
|
24
|
+
long n;
|
25
|
+
ktf_worker_t *w;
|
26
|
+
void (*func)(void*,long,int);
|
27
|
+
void *data;
|
28
|
+
} kt_for_t;
|
29
|
+
|
30
|
+
static inline long steal_work(kt_for_t *t)
|
31
|
+
{
|
32
|
+
int i, min_i = -1;
|
33
|
+
long k, min = LONG_MAX;
|
34
|
+
for (i = 0; i < t->n_threads; ++i)
|
35
|
+
if (min > t->w[i].i) min = t->w[i].i, min_i = i;
|
36
|
+
k = __sync_fetch_and_add(&t->w[min_i].i, t->n_threads);
|
37
|
+
return k >= t->n? -1 : k;
|
38
|
+
}
|
39
|
+
|
40
|
+
static void *ktf_worker(void *data)
|
41
|
+
{
|
42
|
+
ktf_worker_t *w = (ktf_worker_t*)data;
|
43
|
+
long i;
|
44
|
+
for (;;) {
|
45
|
+
i = __sync_fetch_and_add(&w->i, w->t->n_threads);
|
46
|
+
if (i >= w->t->n) break;
|
47
|
+
w->t->func(w->t->data, i, w - w->t->w);
|
48
|
+
}
|
49
|
+
while ((i = steal_work(w->t)) >= 0)
|
50
|
+
w->t->func(w->t->data, i, w - w->t->w);
|
51
|
+
pthread_exit(0);
|
52
|
+
}
|
53
|
+
|
54
|
+
void kt_for(int n_threads, void (*func)(void*,long,int), void *data, long n)
|
55
|
+
{
|
56
|
+
if (n_threads > 1) {
|
57
|
+
int i;
|
58
|
+
kt_for_t t;
|
59
|
+
pthread_t *tid;
|
60
|
+
t.func = func, t.data = data, t.n_threads = n_threads, t.n = n;
|
61
|
+
t.w = (ktf_worker_t*)calloc(n_threads, sizeof(ktf_worker_t));
|
62
|
+
tid = (pthread_t*)calloc(n_threads, sizeof(pthread_t));
|
63
|
+
for (i = 0; i < n_threads; ++i)
|
64
|
+
t.w[i].t = &t, t.w[i].i = i;
|
65
|
+
for (i = 0; i < n_threads; ++i) pthread_create(&tid[i], 0, ktf_worker, &t.w[i]);
|
66
|
+
for (i = 0; i < n_threads; ++i) pthread_join(tid[i], 0);
|
67
|
+
free(tid); free(t.w);
|
68
|
+
} else {
|
69
|
+
long j;
|
70
|
+
for (j = 0; j < n; ++j) func(data, j, 0);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
/*****************
|
75
|
+
* kt_pipeline() *
|
76
|
+
*****************/
|
77
|
+
|
78
|
+
struct ktp_t;
|
79
|
+
|
80
|
+
typedef struct {
|
81
|
+
struct ktp_t *pl;
|
82
|
+
int64_t index;
|
83
|
+
int step;
|
84
|
+
void *data;
|
85
|
+
} ktp_worker_t;
|
86
|
+
|
87
|
+
typedef struct ktp_t {
|
88
|
+
void *shared;
|
89
|
+
void *(*func)(void*, int, void*);
|
90
|
+
int64_t index;
|
91
|
+
int n_workers, n_steps;
|
92
|
+
ktp_worker_t *workers;
|
93
|
+
pthread_mutex_t mutex;
|
94
|
+
pthread_cond_t cv;
|
95
|
+
} ktp_t;
|
96
|
+
|
97
|
+
static void *ktp_worker(void *data)
|
98
|
+
{
|
99
|
+
ktp_worker_t *w = (ktp_worker_t*)data;
|
100
|
+
ktp_t *p = w->pl;
|
101
|
+
while (w->step < p->n_steps) {
|
102
|
+
// test whether we can kick off the job with this worker
|
103
|
+
pthread_mutex_lock(&p->mutex);
|
104
|
+
for (;;) {
|
105
|
+
int i;
|
106
|
+
// test whether another worker is doing the same step
|
107
|
+
for (i = 0; i < p->n_workers; ++i) {
|
108
|
+
if (w == &p->workers[i]) continue; // ignore itself
|
109
|
+
if (p->workers[i].step <= w->step && p->workers[i].index < w->index)
|
110
|
+
break;
|
111
|
+
}
|
112
|
+
if (i == p->n_workers) break; // no workers with smaller indices are doing w->step or the previous steps
|
113
|
+
pthread_cond_wait(&p->cv, &p->mutex);
|
114
|
+
}
|
115
|
+
pthread_mutex_unlock(&p->mutex);
|
116
|
+
|
117
|
+
// working on w->step
|
118
|
+
w->data = p->func(p->shared, w->step, w->step? w->data : 0); // for the first step, input is NULL
|
119
|
+
|
120
|
+
// update step and let other workers know
|
121
|
+
pthread_mutex_lock(&p->mutex);
|
122
|
+
w->step = w->step == p->n_steps - 1 || w->data? (w->step + 1) % p->n_steps : p->n_steps;
|
123
|
+
if (w->step == 0) w->index = p->index++;
|
124
|
+
pthread_cond_broadcast(&p->cv);
|
125
|
+
pthread_mutex_unlock(&p->mutex);
|
126
|
+
}
|
127
|
+
pthread_exit(0);
|
128
|
+
}
|
129
|
+
|
130
|
+
void kt_pipeline(int n_threads, void *(*func)(void*, int, void*), void *shared_data, int n_steps)
|
131
|
+
{
|
132
|
+
ktp_t aux;
|
133
|
+
pthread_t *tid;
|
134
|
+
int i;
|
135
|
+
|
136
|
+
if (n_threads < 1) n_threads = 1;
|
137
|
+
aux.n_workers = n_threads;
|
138
|
+
aux.n_steps = n_steps;
|
139
|
+
aux.func = func;
|
140
|
+
aux.shared = shared_data;
|
141
|
+
aux.index = 0;
|
142
|
+
pthread_mutex_init(&aux.mutex, 0);
|
143
|
+
pthread_cond_init(&aux.cv, 0);
|
144
|
+
|
145
|
+
aux.workers = (ktp_worker_t*)calloc(n_threads, sizeof(ktp_worker_t));
|
146
|
+
for (i = 0; i < n_threads; ++i) {
|
147
|
+
ktp_worker_t *w = &aux.workers[i];
|
148
|
+
w->step = 0; w->pl = &aux; w->data = 0;
|
149
|
+
w->index = aux.index++;
|
150
|
+
}
|
151
|
+
|
152
|
+
tid = (pthread_t*)calloc(n_threads, sizeof(pthread_t));
|
153
|
+
for (i = 0; i < n_threads; ++i) pthread_create(&tid[i], 0, ktp_worker, &aux.workers[i]);
|
154
|
+
for (i = 0; i < n_threads; ++i) pthread_join(tid[i], 0);
|
155
|
+
free(tid); free(aux.workers);
|
156
|
+
|
157
|
+
pthread_mutex_destroy(&aux.mutex);
|
158
|
+
pthread_cond_destroy(&aux.cv);
|
159
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef KTHREAD_H
|
2
|
+
#define KTHREAD_H
|
3
|
+
|
4
|
+
#ifdef __cplusplus
|
5
|
+
extern "C" {
|
6
|
+
#endif
|
7
|
+
|
8
|
+
void kt_for(int n_threads, void (*func)(void*,long,int), void *data, long n);
|
9
|
+
void kt_pipeline(int n_threads, void *(*func)(void*, int, void*), void *shared_data, int n_steps);
|
10
|
+
|
11
|
+
#ifdef __cplusplus
|
12
|
+
}
|
13
|
+
#endif
|
14
|
+
|
15
|
+
#endif
|
@@ -0,0 +1,105 @@
|
|
1
|
+
/* The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2008, 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
|
+
/*
|
27
|
+
An example:
|
28
|
+
|
29
|
+
#include "kvec.h"
|
30
|
+
int main() {
|
31
|
+
kvec_t(int) array;
|
32
|
+
kv_init(array);
|
33
|
+
kv_push(int, array, 10); // append
|
34
|
+
kv_a(int, array, 20) = 5; // dynamic
|
35
|
+
kv_A(array, 20) = 4; // static
|
36
|
+
kv_destroy(array);
|
37
|
+
return 0;
|
38
|
+
}
|
39
|
+
*/
|
40
|
+
|
41
|
+
/*
|
42
|
+
2008-09-22 (0.1.0):
|
43
|
+
|
44
|
+
* The initial version.
|
45
|
+
|
46
|
+
*/
|
47
|
+
|
48
|
+
#ifndef AC_KVEC_H
|
49
|
+
#define AC_KVEC_H
|
50
|
+
|
51
|
+
#include <stdlib.h>
|
52
|
+
#include "kalloc.h"
|
53
|
+
|
54
|
+
#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
|
55
|
+
|
56
|
+
#define kvec_t(type) struct { size_t n, m; type *a; }
|
57
|
+
#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0)
|
58
|
+
#define kv_destroy(v) free((v).a)
|
59
|
+
#define kv_A(v, i) ((v).a[(i)])
|
60
|
+
#define kv_pop(v) ((v).a[--(v).n])
|
61
|
+
#define kv_size(v) ((v).n)
|
62
|
+
#define kv_max(v) ((v).m)
|
63
|
+
|
64
|
+
#define kv_resize(type, km, v, s) do { \
|
65
|
+
if ((v).m < (s)) { \
|
66
|
+
(v).m = (s); \
|
67
|
+
kv_roundup32((v).m); \
|
68
|
+
(v).a = (type*)krealloc((km), (v).a, sizeof(type) * (v).m); \
|
69
|
+
} \
|
70
|
+
} while (0)
|
71
|
+
|
72
|
+
#define kv_copy(type, km, v1, v0) do { \
|
73
|
+
if ((v1).m < (v0).n) kv_resize(type, (km), (v1), (v0).n); \
|
74
|
+
(v1).n = (v0).n; \
|
75
|
+
memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \
|
76
|
+
} while (0) \
|
77
|
+
|
78
|
+
#define kv_push(type, km, v, x) do { \
|
79
|
+
if ((v).n == (v).m) { \
|
80
|
+
(v).m = (v).m? (v).m<<1 : 2; \
|
81
|
+
(v).a = (type*)krealloc((km), (v).a, sizeof(type) * (v).m); \
|
82
|
+
} \
|
83
|
+
(v).a[(v).n++] = (x); \
|
84
|
+
} while (0)
|
85
|
+
|
86
|
+
#define kv_pushp(type, km, v, p) do { \
|
87
|
+
if ((v).n == (v).m) { \
|
88
|
+
(v).m = (v).m? (v).m<<1 : 2; \
|
89
|
+
(v).a = (type*)krealloc((km), (v).a, sizeof(type) * (v).m); \
|
90
|
+
} \
|
91
|
+
*(p) = &(v).a[(v).n++]; \
|
92
|
+
} while (0)
|
93
|
+
|
94
|
+
#define kv_reverse(type, v, start) do { \
|
95
|
+
if ((v).m > 0 && (v).n > (start)) { \
|
96
|
+
size_t __i, __end = (v).n - (start); \
|
97
|
+
type *__a = (v).a + (start); \
|
98
|
+
for (__i = 0; __i < __end>>1; ++__i) { \
|
99
|
+
type __t = __a[__end - 1 - __i]; \
|
100
|
+
__a[__end - 1 - __i] = __a[__i]; __a[__i] = __t; \
|
101
|
+
} \
|
102
|
+
} \
|
103
|
+
} while (0)
|
104
|
+
|
105
|
+
#endif
|
@@ -0,0 +1,110 @@
|
|
1
|
+
/* The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2008, 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
|
+
/*
|
27
|
+
An example:
|
28
|
+
|
29
|
+
#include "kvec.h"
|
30
|
+
int main() {
|
31
|
+
kvec_t(int) array;
|
32
|
+
kv_init(array);
|
33
|
+
kv_push(int, array, 10); // append
|
34
|
+
kv_a(int, array, 20) = 5; // dynamic
|
35
|
+
kv_A(array, 20) = 4; // static
|
36
|
+
kv_destroy(array);
|
37
|
+
return 0;
|
38
|
+
}
|
39
|
+
*/
|
40
|
+
|
41
|
+
/*
|
42
|
+
2008-09-22 (0.1.0):
|
43
|
+
|
44
|
+
* The initial version.
|
45
|
+
|
46
|
+
*/
|
47
|
+
|
48
|
+
#ifndef AC_KVEC_H
|
49
|
+
#define AC_KVEC_H
|
50
|
+
|
51
|
+
#include <stdlib.h>
|
52
|
+
|
53
|
+
#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
|
54
|
+
|
55
|
+
#define kvec_t(type) struct { size_t n, m; type *a; }
|
56
|
+
#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0)
|
57
|
+
#define kv_destroy(v) free((v).a)
|
58
|
+
#define kv_A(v, i) ((v).a[(i)])
|
59
|
+
#define kv_pop(v) ((v).a[--(v).n])
|
60
|
+
#define kv_size(v) ((v).n)
|
61
|
+
#define kv_max(v) ((v).m)
|
62
|
+
|
63
|
+
#define kv_resize(type, v, s) do { \
|
64
|
+
if ((v).m < (s)) { \
|
65
|
+
(v).m = (s); \
|
66
|
+
kv_roundup32((v).m); \
|
67
|
+
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \
|
68
|
+
} \
|
69
|
+
} while (0)
|
70
|
+
|
71
|
+
#define kv_copy(type, v1, v0) do { \
|
72
|
+
if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \
|
73
|
+
(v1).n = (v0).n; \
|
74
|
+
memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \
|
75
|
+
} while (0) \
|
76
|
+
|
77
|
+
#define kv_push(type, v, x) do { \
|
78
|
+
if ((v).n == (v).m) { \
|
79
|
+
(v).m = (v).m? (v).m<<1 : 2; \
|
80
|
+
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \
|
81
|
+
} \
|
82
|
+
(v).a[(v).n++] = (x); \
|
83
|
+
} while (0)
|
84
|
+
|
85
|
+
#define kv_pushp(type, v, p) do { \
|
86
|
+
if ((v).n == (v).m) { \
|
87
|
+
(v).m = (v).m? (v).m<<1 : 2; \
|
88
|
+
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \
|
89
|
+
} \
|
90
|
+
*(p) = &(v).a[(v).n++]; \
|
91
|
+
} while (0)
|
92
|
+
|
93
|
+
#define kv_a(type, v, i) ((v).m <= (size_t)(i)? \
|
94
|
+
((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \
|
95
|
+
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \
|
96
|
+
: (v).n <= (size_t)(i)? (v).n = (i) \
|
97
|
+
: 0), (v).a[(i)]
|
98
|
+
|
99
|
+
#define kv_reverse(type, v, start) do { \
|
100
|
+
if ((v).m > 0 && (v).n > (start)) { \
|
101
|
+
size_t __i, __end = (v).n - (start); \
|
102
|
+
type *__a = (v).a + (start); \
|
103
|
+
for (__i = 0; __i < __end>>1; ++__i) { \
|
104
|
+
type __t = __a[__end - 1 - __i]; \
|
105
|
+
__a[__end - 1 - __i] = __a[__i]; __a[__i] = __t; \
|
106
|
+
} \
|
107
|
+
} \
|
108
|
+
} while (0)
|
109
|
+
|
110
|
+
#endif
|