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