1 static char rcsid[] = "$Id: matchpool.c 218147 2019-01-16 21:28:41Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5
6 #include "matchpool.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "mem.h"
10 #include "comp.h"
11 #include "matchdef.h"
12 #include "univinterval.h"
13
14
15 #define CHUNKSIZE 16384
16
17 #ifdef DEBUG
18 #define debug(x) x
19 #else
20 #define debug(x)
21 #endif
22
23 /* For mechanics of memory allocation and deallocation */
24 #ifdef DEBUG1
25 #define debug1(x) x
26 #else
27 #define debug1(x)
28 #endif
29
30
31 #define T Matchpool_T
32 struct T {
33 int nmatches;
34 int matchctr;
35 struct Match_T *matchptr;
36 List_T matchchunks;
37
38 int matchctr_save;
39 struct Match_T *matchptr_save;
40
41 int nlistcells;
42 int listcellctr;
43 struct List_T *listcellptr;
44 List_T listcellchunks;
45
46 int listcellctr_save;
47 struct List_T *listcellptr_save;
48 };
49
50 void
Matchpool_free_memory(T this)51 Matchpool_free_memory (T this) {
52 List_T p;
53 struct Match_T *matchptr;
54 struct List_T *listcellptr;
55
56 for (p = this->matchchunks; p != NULL; p = List_next(p)) {
57 matchptr = (struct Match_T *) List_head(p);
58 FREE_KEEP(matchptr);
59 }
60 List_free_keep(&this->matchchunks);
61 for (p = this->listcellchunks; p != NULL; p = List_next(p)) {
62 listcellptr = (struct List_T *) List_head(p);
63 FREE_KEEP(listcellptr);
64 }
65 List_free_keep(&this->listcellchunks);
66
67 this->nmatches = 0;
68 this->matchctr = 0;
69 this->matchchunks = NULL;
70 /* this->matchptr = add_new_matchchunk(this); */
71
72 this->nlistcells = 0;
73 this->listcellctr = 0;
74 this->listcellchunks = NULL;
75 /* this->listcellptr = add_new_listcellchunk(this); */
76
77 return;
78 }
79
80 void
Matchpool_free(T * old)81 Matchpool_free (T *old) {
82 Matchpool_free_memory(*old);
83 FREE_KEEP(*old);
84 return;
85 }
86
87
88
89
90
91 static struct Match_T *
add_new_matchchunk(T this)92 add_new_matchchunk (T this) {
93 struct Match_T *chunk;
94
95 chunk = (struct Match_T *) MALLOC_KEEP(CHUNKSIZE*sizeof(struct Match_T));
96 this->matchchunks = List_push_keep(this->matchchunks,(void *) chunk);
97 debug1(printf("Adding a new chunk of matches. Ptr for match %d is %p\n",
98 this->nmatches,chunk));
99
100 this->nmatches += CHUNKSIZE;
101 return chunk;
102 }
103
104 static struct List_T *
add_new_listcellchunk(T this)105 add_new_listcellchunk (T this) {
106 struct List_T *chunk;
107
108 chunk = (struct List_T *) MALLOC_KEEP(CHUNKSIZE*sizeof(struct List_T));
109 this->listcellchunks = List_push_keep(this->listcellchunks,(void *) chunk);
110 debug1(printf("Adding a new chunk of listcells. Ptr for listcell %d is %p\n",
111 this->nlistcells,chunk));
112
113 this->nlistcells += CHUNKSIZE;
114 return chunk;
115 }
116
117 T
Matchpool_new(void)118 Matchpool_new (void) {
119 T new = (T) MALLOC_KEEP(sizeof(*new));
120
121 new->nmatches = 0;
122 new->matchctr = 0;
123 new->matchchunks = NULL;
124 /* new->matchptr = add_new_matchchunk(new); */
125
126 new->nlistcells = 0;
127 new->listcellctr = 0;
128 new->listcellchunks = NULL;
129 /* new->listcellptr = add_new_listcellchunk(new); */
130
131 return new;
132 }
133
134 void
Matchpool_reset(T this)135 Matchpool_reset (T this) {
136 this->matchctr = 0;
137 this->listcellctr = 0;
138 return;
139 }
140
141 void
Matchpool_save(T this)142 Matchpool_save (T this) {
143 this->matchctr_save = this->matchctr;
144 this->matchptr_save = this->matchptr;
145 this->listcellctr_save = this->listcellctr;
146 this->listcellptr_save = this->listcellptr;
147 return;
148 }
149
150 void
Matchpool_restore(T this)151 Matchpool_restore (T this) {
152 this->matchctr = this->matchctr_save;
153 this->matchptr = this->matchptr_save;
154 this->listcellctr = this->listcellctr_save;
155 this->listcellptr = this->listcellptr_save;
156 return;
157 }
158
159 List_T
Matchpool_push(List_T list,T this,int querypos,int querylength,bool forwardp,bool fivep,Univcoord_T diagonal,Univ_IIT_T chromosome_iit)160 Matchpool_push (List_T list, T this, int querypos, int querylength, bool forwardp, bool fivep,
161 Univcoord_T diagonal, Univ_IIT_T chromosome_iit) {
162 List_T listcell;
163 Match_T match;
164 List_T p;
165 int n;
166 int index;
167
168 if (this->matchctr >= this->nmatches) {
169 this->matchptr = add_new_matchchunk(this);
170 } else if ((this->matchctr % CHUNKSIZE) == 0) {
171 for (n = this->nmatches - CHUNKSIZE, p = this->matchchunks;
172 n > this->matchctr; p = p->rest, n -= CHUNKSIZE) ;
173 this->matchptr = (struct Match_T *) p->first;
174 debug1(printf("Located match %d at %p\n",this->matchctr,this->matchptr));
175 }
176 match = this->matchptr++;
177 this->matchctr++;
178
179 match->querypos = querypos;
180 match->weight = 0.0; /* Will be entered later */
181 if ((match->forwardp = forwardp) == true) {
182 match->position = diagonal + querypos - querylength;
183 } else {
184 match->position = diagonal - querypos;
185 }
186 match->fivep = fivep;
187 match->npairings = 0;
188
189 if (chromosome_iit == NULL) {
190 match->chrnum = 0;
191 match->chrpos = match->position;
192 } else {
193 index = Univ_IIT_get_one(chromosome_iit,match->position,match->position);
194 match->chrpos = match->position - Univinterval_low(Univ_IIT_interval(chromosome_iit,index));
195 match->chrnum = index;
196 }
197
198 debug(
199 printf("Creating %d: %d %d %d %u\n",
200 this->matchctr-1,match->querypos,match->forwardp,match->fivep,match->position);
201 );
202
203 if (this->listcellctr >= this->nlistcells) {
204 this->listcellptr = add_new_listcellchunk(this);
205 } else if ((this->listcellctr % CHUNKSIZE) == 0) {
206 for (n = this->nlistcells - CHUNKSIZE, p = this->listcellchunks;
207 n > this->listcellctr; p = p->rest, n -= CHUNKSIZE) ;
208 this->listcellptr = (struct List_T *) p->first;
209 debug1(printf("Located listcell %d at %p\n",this->listcellctr,this->listcellptr));
210 }
211 listcell = this->listcellptr++;
212 this->listcellctr++;
213
214 listcell->first = (void *) match;
215 listcell->rest = list;
216
217 return listcell;
218 }
219
220 List_T
Matchpool_push_existing(List_T list,T this,Match_T match)221 Matchpool_push_existing (List_T list, T this, Match_T match) {
222 List_T listcell;
223 List_T p;
224 int n;
225
226 debug(
227 printf("Pushing: %d %d %d %u\n",
228 match->querypos,match->forwardp,match->fivep,match->position);
229 );
230
231 if (this->listcellctr >= this->nlistcells) {
232 this->listcellptr = add_new_listcellchunk(this);
233 } else if ((this->listcellctr % CHUNKSIZE) == 0) {
234 for (n = this->nlistcells - CHUNKSIZE, p = this->listcellchunks;
235 n > this->listcellctr; p = p->rest, n -= CHUNKSIZE) ;
236 this->listcellptr = (struct List_T *) p->first;
237 debug1(printf("Located listcell %d at %p\n",this->listcellctr,this->listcellptr));
238 }
239 listcell = this->listcellptr++;
240 this->listcellctr++;
241
242 listcell->first = (void *) match;
243 listcell->rest = list;
244
245 return listcell;
246 }
247
248
249 List_T
Matchpool_pop(List_T list,Match_T * x)250 Matchpool_pop (List_T list, Match_T *x) {
251 List_T head;
252
253 if (list != NULL) {
254 head = list->rest;
255 *x = (Match_T) list->first;
256 return head;
257 } else {
258 return list;
259 }
260 }
261
262
263 List_T
Matchpool_transfer(List_T dest,List_T source)264 Matchpool_transfer (List_T dest, List_T source) {
265 List_T p, next;
266 #ifdef DEBUG
267 Match_T match;
268 #endif
269
270 for (p = source; p != NULL; p = next) {
271 debug(
272 match = List_head(p);
273 printf("Transferring: %d %d %d %u\n",
274 match->querypos,match->forwardp,match->fivep,match->position);
275 );
276 next = p->rest;
277 p->rest = dest;
278 dest = p;
279 }
280 debug(printf("Done with transfer\n"));
281
282 return dest;
283 }
284
285