1 static char rcsid[] = "$Id: cellpool.c 218147 2019-01-16 21:28:41Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5 
6 #include "cellpool.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>		/* For memcpy */
10 #include "assert.h"
11 #include "mem.h"
12 
13 
14 #define CHUNKSIZE 10000
15 
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 /* For popping */
31 #ifdef DEBUG2
32 #define debug2(x) x
33 #else
34 #define debug2(x)
35 #endif
36 
37 
38 #define T Cellpool_T
39 struct T {
40   int nobjects;
41   int objectctr;
42   struct Cell_T *objectptr;
43   List_T objectchunks;
44 
45   int nlistcells;
46   int listcellctr;
47   struct List_T *listcellptr;
48   List_T listcellchunks;
49 };
50 
51 void
Cellpool_free_memory(T this)52 Cellpool_free_memory (T this) {
53   List_T p;
54   struct Cell_T *objectptr;
55   struct List_T *listcellptr;
56 
57   for (p = this->objectchunks; p != NULL; p = List_next(p)) {
58     objectptr = (struct Cell_T *) List_head(p);
59     FREE_KEEP(objectptr);
60   }
61   List_free_keep(&this->objectchunks);
62   for (p = this->listcellchunks; p != NULL; p = List_next(p)) {
63     listcellptr = (struct List_T *) List_head(p);
64     FREE_KEEP(listcellptr);
65   }
66   List_free_keep(&this->listcellchunks);
67 
68   this->nobjects = 0;
69   this->objectctr = 0;
70   this->objectchunks = NULL;
71   /* this->objectptr = add_new_objectchunk(this); */
72 
73   this->nlistcells = 0;
74   this->listcellctr = 0;
75   this->listcellchunks = NULL;
76   /* this->listcellptr = add_new_listcellchunk(this); */
77 
78   return;
79 }
80 
81 void
Cellpool_free(T * old)82 Cellpool_free (T *old) {
83   Cellpool_free_memory(*old);
84   FREE_KEEP(*old);
85   return;
86 }
87 
88 
89 void
Cellpool_report_memory(T this)90 Cellpool_report_memory (T this) {
91   printf("Cellpool has %d pairchunks and %d listcellchunks\n",
92 	 List_length(this->objectchunks),List_length(this->listcellchunks));
93   return;
94 }
95 
96 
97 static struct Cell_T *
add_new_objectchunk(T this)98 add_new_objectchunk (T this) {
99   struct Cell_T *chunk;
100 
101   chunk = (struct Cell_T *) MALLOC_KEEP(CHUNKSIZE*sizeof(struct Cell_T));
102   this->objectchunks = List_push_keep(this->objectchunks,(void *) chunk);
103   debug1(printf("Adding a new chunk of objects.  Ptr for object %d is %p\n",
104 		this->nobjects,chunk));
105 
106   this->nobjects += CHUNKSIZE;
107 
108   return chunk;
109 }
110 
111 static struct List_T *
add_new_listcellchunk(T this)112 add_new_listcellchunk (T this) {
113   struct List_T *chunk;
114 
115   chunk = (struct List_T *) MALLOC_KEEP(CHUNKSIZE*sizeof(struct List_T));
116   this->listcellchunks = List_push_keep(this->listcellchunks,(void *) chunk);
117   debug1(printf("Adding a new chunk of listcells.  Ptr for listcell %d is %p\n",
118 	       this->nlistcells,chunk));
119 
120   this->nlistcells += CHUNKSIZE;
121 
122   return chunk;
123 }
124 
125 T
Cellpool_new(void)126 Cellpool_new (void) {
127   T new = (T) MALLOC_KEEP(sizeof(*new));
128 
129   new->nobjects = 0;
130   new->objectctr = 0;
131   new->objectchunks = NULL;
132   /* new->objectptr = add_new_objectchunk(new); */
133 
134   new->nlistcells = 0;
135   new->listcellctr = 0;
136   new->listcellchunks = NULL;
137   /* new->listcellptr = add_new_listcellchunk(new); */
138 
139   return new;
140 }
141 
142 void
Cellpool_reset(T this)143 Cellpool_reset (T this) {
144   this->objectctr = 0;
145   this->listcellctr = 0;
146   return;
147 }
148 
149 List_T
Cellpool_push(List_T list,T this,int rootposition,int endposition,int querypos,int hit,bool fwdp,int score)150 Cellpool_push (List_T list, T this, int rootposition, int endposition,
151 	       int querypos, int hit, bool fwdp, int score) {
152   List_T listcell;
153   Cell_T new;
154   List_T p;
155   int n;
156 
157   if (this->objectctr >= this->nobjects) {
158     this->objectptr = add_new_objectchunk(this);
159   } else if ((this->objectctr % CHUNKSIZE) == 0) {
160     for (n = this->nobjects - CHUNKSIZE, p = this->objectchunks;
161 	 n > this->objectctr; p = p->rest, n -= CHUNKSIZE) ;
162     this->objectptr = (struct Cell_T *) p->first;
163     debug1(printf("Located object %d at %p\n",this->objectctr,this->objectptr));
164   }
165   new = this->objectptr++;
166   this->objectctr++;
167 
168 
169   new->rootposition = rootposition;
170   new->endposition = endposition;
171   new->querypos = querypos;
172   new->hit = hit;
173   new->fwdp = fwdp;
174   new->score = score;
175   new->pushedp = false;
176 
177 
178   if (this->listcellctr >= this->nlistcells) {
179     this->listcellptr = add_new_listcellchunk(this);
180   } else if ((this->listcellctr % CHUNKSIZE) == 0) {
181     for (n = this->nlistcells - CHUNKSIZE, p = this->listcellchunks;
182 	 n > this->listcellctr; p = p->rest, n -= CHUNKSIZE) ;
183     this->listcellptr = (struct List_T *) p->first;
184     debug1(printf("Located listcell %d at %p\n",this->listcellctr,this->listcellptr));
185   }
186   listcell = this->listcellptr++;
187   this->listcellctr++;
188 
189   listcell->first = (void *) new;
190   listcell->rest = list;
191 
192   return listcell;
193 }
194 
195 
196 
197 /* Note: this does not free the list cell */
198 List_T
Cellpool_pop(List_T list,Cell_T * x)199 Cellpool_pop (List_T list, Cell_T *x) {
200   List_T head;
201 
202   if (list != NULL) {
203     head = list->rest;
204     *x = (Cell_T) list->first;
205     return head;
206   } else {
207     return list;
208   }
209 }
210 
211 
212