1 static char rcsid[] = "$Id: hitlistpool.c 218195 2019-01-17 13:53:13Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5 
6 #include "hitlistpool.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "mem.h"
10 
11 
12 /* Same as Listpool_T.  Currently used for lists of Stage3end_T and
13    Stage3pair_T objects */
14 
15 
16 #define CHUNKSIZE 16384
17 
18 #ifdef DEBUG
19 #define debug(x) x
20 #else
21 #define debug(x)
22 #endif
23 
24 /* For mechanics of memory allocation and deallocation */
25 #ifdef DEBUG1
26 #define debug1(x) x
27 #else
28 #define debug1(x)
29 #endif
30 
31 
32 #define T Hitlistpool_T
33 struct T {
34   int nlistcells;
35   int listcellctr;
36   struct List_T *listcellptr;
37   List_T chunks;
38 };
39 
40 void
Hitlistpool_free_memory(T this)41 Hitlistpool_free_memory (T this) {
42   List_T p;
43   struct List_T *listcellptr;
44 
45   for (p = this->chunks; p != NULL; p = List_next(p)) {
46     listcellptr = (struct List_T *) List_head(p);
47     FREE_KEEP(listcellptr);
48   }
49   List_free_keep(&this->chunks);
50 
51   this->nlistcells = 0;
52   this->listcellctr = 0;
53   this->chunks = NULL;
54   /* this->listcellptr = add_new_listcellchunk(this); */
55 
56   return;
57 }
58 
59 void
Hitlistpool_free(T * old)60 Hitlistpool_free (T *old) {
61   Hitlistpool_free_memory(*old);
62   FREE_KEEP(*old);
63   return;
64 }
65 
66 
67 
68 static struct List_T *
add_new_chunk(T this)69 add_new_chunk (T this) {
70   struct List_T *chunk;
71 
72   chunk = (struct List_T *) MALLOC_KEEP(CHUNKSIZE*sizeof(struct List_T));
73   this->chunks = List_push_keep(this->chunks,(void *) chunk);
74   debug1(printf("Adding a new chunk of listcells.  Ptr for listcell %d is %p\n",
75 	       this->nlistcells,chunk));
76 
77   this->nlistcells += CHUNKSIZE;
78   return chunk;
79 }
80 
81 T
Hitlistpool_new(void)82 Hitlistpool_new (void) {
83   T new = (T) MALLOC_KEEP(sizeof(*new));
84 
85   new->nlistcells = 0;
86   new->listcellctr = 0;
87   new->chunks = NULL;
88   /* new->listcellptr = add_new_listcellchunk(new); */
89 
90   return new;
91 }
92 
93 void
Hitlistpool_reset(T this)94 Hitlistpool_reset (T this) {
95   this->listcellctr = 0;
96   return;
97 }
98 
99 #ifdef DEBUG_HITLISTPOOL
100 List_T
Hitlist_push_actual(List_T list,T this,void * contents,const char * file,int line)101 Hitlist_push_actual (List_T list, T this, void *contents,
102 		     const char *file, int line) {
103   List_T listcell;
104   List_T p;
105   int n;
106 
107   if (this->listcellctr >= this->nlistcells) {
108     this->listcellptr = add_new_chunk(this);
109   } else if ((this->listcellctr % CHUNKSIZE) == 0) {
110     for (n = this->nlistcells - CHUNKSIZE, p = this->chunks;
111 	 n > this->listcellctr; p = p->rest, n -= CHUNKSIZE) ;
112     this->listcellptr = (struct List_T *) p->first;
113     debug1(printf("Located listcell %d at %p\n",this->listcellctr,this->listcellptr));
114   }
115   listcell = this->listcellptr++;
116   this->listcellctr++;
117 
118   listcell->first = contents;
119   listcell->rest = list;
120 
121   printf("Allocating %p to %p -- Malloc of 1 bytes requested from %s:%d\n",
122 	 listcell,listcell,file,line);
123   return listcell;
124 }
125 
126 #else
127 List_T
Hitlist_push(List_T list,T this,void * contents)128 Hitlist_push (List_T list, T this, void *contents) {
129   List_T listcell;
130   List_T p;
131   int n;
132 
133   if (this->listcellctr >= this->nlistcells) {
134     this->listcellptr = add_new_chunk(this);
135   } else if ((this->listcellctr % CHUNKSIZE) == 0) {
136     for (n = this->nlistcells - CHUNKSIZE, p = this->chunks;
137 	 n > this->listcellctr; p = p->rest, n -= CHUNKSIZE) ;
138     this->listcellptr = (struct List_T *) p->first;
139     debug1(printf("Located listcell %d at %p\n",this->listcellctr,this->listcellptr));
140   }
141   listcell = this->listcellptr++;
142   this->listcellctr++;
143 
144   listcell->first = contents;
145   listcell->rest = list;
146 
147   return listcell;
148 }
149 #endif
150 
151 
152 #ifdef DEBUG_HITLISTPOOL
153 void
Hitlist_free_actual(List_T * old,const char * file,int line)154 Hitlist_free_actual (List_T *old, const char *file, int line) {
155   List_T p;
156 
157   for (p = *old; p != NULL; p = List_next(p)) {
158     printf("Freeing %p in standard pool at %s:%d\n",p,file,line);
159   }
160   *old = (List_T) NULL;
161   return;
162 }
163 
164 #elif !defined(HAVE_INLINE)
165 void
Hitlist_free(List_T * old)166 Hitlist_free (List_T *old) {
167   *old = (List_T) NULL;
168   return;
169 }
170 #endif
171 
172 List_T
Hitlist_pop(List_T list,void ** contents)173 Hitlist_pop (List_T list, void **contents) {
174   List_T head;
175 
176   if (list != NULL) {
177     head = list->rest;
178     *contents = list->first;
179     return head;
180   } else {
181     return list;
182   }
183 }
184 
185 
186 List_T
Hitlist_copy(List_T source,T this)187 Hitlist_copy (List_T source, T this) {
188   List_T dest = NULL;
189 
190   while (source != NULL) {
191     dest = Hitlist_push(dest,this,/*orig*/source->first);
192     source = source->rest;
193   }
194   return List_reverse(dest);
195 }
196 
197 
198