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,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
|