1 static char rcsid[] = "$Id: intlistpool.c 218147 2019-01-16 21:28:41Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5 
6 #include "intlistpool.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "mem.h"
10 #include "comp.h"
11 #include "list.h"
12 
13 #define CHUNKSIZE 16384
14 
15 #ifdef DEBUG
16 #define debug(x) x
17 #else
18 #define debug(x)
19 #endif
20 
21 /* For mechanics of memory allocation and deallocation */
22 #ifdef DEBUG1
23 #define debug1(x) x
24 #else
25 #define debug1(x)
26 #endif
27 
28 
29 #define T Intlistpool_T
30 struct T {
31   int nlistcells;
32   int listcellctr;
33   struct Intlist_T *listcellptr;
34   List_T chunks;
35 };
36 
37 void
Intlistpool_free_memory(T this)38 Intlistpool_free_memory (T this) {
39   List_T p;
40   struct Intlist_T *listcellptr;
41 
42   for (p = this->chunks; p != NULL; p = List_next(p)) {
43     listcellptr = (struct Intlist_T *) List_head(p);
44     FREE_KEEP(listcellptr);
45   }
46   List_free_keep(&this->chunks);
47 
48   this->nlistcells = 0;
49   this->listcellctr = 0;
50   this->chunks = NULL;
51   /* this->listcellptr = add_new_listcellchunk(this); */
52 
53   return;
54 }
55 
56 void
Intlistpool_free(T * old)57 Intlistpool_free (T *old) {
58   Intlistpool_free_memory(*old);
59   FREE_KEEP(*old);
60   return;
61 }
62 
63 
64 
65 
66 static struct Intlist_T *
add_new_chunk(T this)67 add_new_chunk (T this) {
68   struct Intlist_T *chunk;
69 
70   chunk = (struct Intlist_T *) MALLOC_KEEP(CHUNKSIZE*sizeof(struct Intlist_T));
71   this->chunks = List_push_keep(this->chunks,(void *) chunk);
72   debug1(printf("Adding a new chunk of listcells.  Ptr for listcell %d is %p\n",
73 	       this->nlistcells,chunk));
74 
75   this->nlistcells += CHUNKSIZE;
76   return chunk;
77 }
78 
79 T
Intlistpool_new(void)80 Intlistpool_new (void) {
81   T new = (T) MALLOC_KEEP(sizeof(*new));
82 
83   new->nlistcells = 0;
84   new->listcellctr = 0;
85   new->chunks = NULL;
86   /* new->listcellptr = add_new_listcellchunk(new); */
87 
88   return new;
89 }
90 
91 void
Intlistpool_reset(T this)92 Intlistpool_reset (T this) {
93   this->listcellctr = 0;
94   return;
95 }
96 
97 Intlist_T
Intlistpool_push(Intlist_T list,T this,int integer)98 Intlistpool_push (Intlist_T list, T this, int integer) {
99   Intlist_T listcell;
100   List_T p;
101   int n;
102 
103   if (this->listcellctr >= this->nlistcells) {
104     this->listcellptr = add_new_chunk(this);
105   } else if ((this->listcellctr % CHUNKSIZE) == 0) {
106     for (n = this->nlistcells - CHUNKSIZE, p = this->chunks;
107 	 n > this->listcellctr; p = p->rest, n -= CHUNKSIZE) ;
108     this->listcellptr = (struct Intlist_T *) p->first;
109     debug1(printf("Located listcell %d at %p\n",this->listcellctr,this->listcellptr));
110   }
111   listcell = this->listcellptr++;
112   this->listcellctr++;
113 
114   listcell->first = integer;
115   listcell->rest = list;
116 
117   return listcell;
118 }
119 
120 Intlist_T
Intlistpool_pop(Intlist_T list,int * integer)121 Intlistpool_pop (Intlist_T list, int *integer) {
122   Intlist_T head;
123 
124   if (list != NULL) {
125     head = list->rest;
126     *integer = list->first;
127     return head;
128   } else {
129     return list;
130   }
131 }
132 
133 
134 Intlist_T
Intlistpool_copy(Intlist_T source,T this)135 Intlistpool_copy (Intlist_T source, T this) {
136   Intlist_T dest = NULL;
137 
138   while (source != NULL) {
139     dest = Intlistpool_push(dest,this,/*orig*/source->first);
140     source = source->rest;
141   }
142   return Intlist_reverse(dest);
143 }
144 
145 Intlist_T
Intlistpool_copy_but_last(Intlist_T source,T this)146 Intlistpool_copy_but_last (Intlist_T source, T this) {
147   Intlist_T dest = NULL;
148 
149   if (source == NULL) {
150     return (Intlist_T) NULL;
151   } else {
152     while (source->rest != NULL) {
153       dest = Intlistpool_push(dest,this,/*orig*/source->first);
154       source = source->rest;
155     }
156     return Intlist_reverse(dest);
157   }
158 }
159 
160