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