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