Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "sql_mem.h"
15 :
16 : #define SA_BLOCK (64*1024)
17 :
18 : sql_ref *
19 3248377 : sql_ref_init(sql_ref *r)
20 : {
21 3248377 : r->refcnt = 1;
22 3248377 : return r;
23 : }
24 :
25 : int
26 579363 : sql_ref_inc(sql_ref *r)
27 : {
28 579363 : assert(r->refcnt > 0);
29 579363 : return (++r->refcnt);
30 : }
31 :
32 : int
33 1227425 : sql_ref_dec(sql_ref *r)
34 : {
35 1227425 : assert(r->refcnt > 0);
36 1227425 : return (--r->refcnt);
37 : }
38 :
39 : typedef struct freed_t {
40 : struct freed_t *n;
41 : size_t sz;
42 : } freed_t;
43 :
44 : static void
45 70362 : sa_destroy_freelist( freed_t *f )
46 : {
47 78546 : while(f) {
48 8184 : freed_t *n = f->n;
49 8184 : GDKfree(f);
50 8184 : f = n;
51 : }
52 70362 : }
53 :
54 : static void
55 179628 : sa_free(sql_allocator *pa, void *blk)
56 : {
57 179628 : assert(!pa->pa);
58 : size_t i;
59 :
60 43515442 : for(i = 0; i < pa->nr; i++) {
61 43515442 : if (pa->blks[i] == blk)
62 : break;
63 : }
64 179628 : assert (i < pa->nr);
65 2177568 : for (; i < pa->nr-1; i++)
66 1997940 : pa->blks[i] = pa->blks[i+1];
67 179628 : pa->nr--;
68 :
69 179628 : size_t sz = GDKmallocated(blk);
70 179628 : if (sz > (SA_BLOCK + 32)) {
71 100 : _DELETE(blk);
72 : } else {
73 179528 : freed_t *f = blk;
74 179528 : f->n = pa->freelist;
75 179528 : f->sz = sz;
76 :
77 179528 : pa->freelist = f;
78 : }
79 179628 : }
80 :
81 : static void *
82 171344 : sa_use_freed(sql_allocator *pa, size_t sz)
83 : {
84 171344 : (void)sz;
85 :
86 171344 : freed_t *f = pa->freelist;
87 171344 : pa->freelist = f->n;
88 171344 : return f;
89 : }
90 :
91 : sql_allocator *
92 273101 : sa_create(sql_allocator *pa)
93 : {
94 273101 : sql_allocator *sa = (pa)?SA_NEW(pa, sql_allocator):MNEW(sql_allocator);
95 273099 : if (sa == NULL)
96 : return NULL;
97 273099 : eb_init(&sa->eb);
98 273098 : sa->pa = pa;
99 273098 : sa->size = 64;
100 273098 : sa->nr = 1;
101 273098 : sa->blks = pa?SA_NEW_ARRAY(pa, char*, sa->size):NEW_ARRAY(char*, sa->size);
102 273098 : sa->freelist = NULL;
103 273098 : if (sa->blks == NULL) {
104 0 : if (!pa)
105 0 : _DELETE(sa);
106 0 : return NULL;
107 : }
108 273098 : sa->blks[0] = pa?SA_NEW_ARRAY(pa, char, SA_BLOCK):NEW_ARRAY(char, SA_BLOCK);
109 273099 : sa->usedmem = SA_BLOCK;
110 273099 : if (sa->blks[0] == NULL) {
111 0 : if (!pa)
112 0 : _DELETE(sa->blks);
113 0 : if (!pa)
114 0 : _DELETE(sa);
115 0 : return NULL;
116 : }
117 273099 : sa->used = 0;
118 273099 : return sa;
119 : }
120 :
121 1828840 : sql_allocator *sa_reset( sql_allocator *sa )
122 : {
123 1828840 : size_t i ;
124 :
125 1882566 : for (i = 1; i<sa->nr; i++) {
126 53724 : if (!sa->pa)
127 0 : _DELETE(sa->blks[i]);
128 : else
129 53724 : sa_free(sa->pa, sa->blks[i]);
130 : }
131 1828842 : sa->nr = 1;
132 1828842 : sa->used = 0;
133 1828842 : sa->usedmem = SA_BLOCK;
134 1828842 : return sa;
135 : }
136 :
137 : #undef sa_realloc
138 : #undef sa_alloc
139 : void *
140 34 : sa_realloc( sql_allocator *sa, void *p, size_t sz, size_t oldsz )
141 : {
142 34 : void *r = sa_alloc(sa, sz);
143 :
144 34 : if (r)
145 34 : memcpy(r, p, oldsz);
146 34 : return r;
147 : }
148 :
149 : #define round16(sz) ((sz+15)&~15)
150 : void *
151 240205872 : sa_alloc( sql_allocator *sa, size_t sz )
152 : {
153 240205872 : char *r;
154 240205872 : sz = round16(sz);
155 240205872 : if (sz > (SA_BLOCK-sa->used)) {
156 491258 : if (sa->pa)
157 53947 : r = SA_NEW_ARRAY(sa->pa,char,(sz > SA_BLOCK ? sz : SA_BLOCK));
158 437311 : else if (sz <= SA_BLOCK && sa->freelist) {
159 171344 : r = sa_use_freed(sa, SA_BLOCK);
160 : } else
161 265967 : r = GDKmalloc(sz > SA_BLOCK ? sz : SA_BLOCK);
162 491264 : if (r == NULL) {
163 0 : if (sa->eb.enabled)
164 0 : eb_error(&sa->eb, "out of memory", 1000);
165 : return NULL;
166 : }
167 491264 : if (sa->nr >= sa->size) {
168 942 : char **tmp;
169 942 : size_t osz = sa->size;
170 942 : sa->size *=2;
171 942 : if (sa->pa)
172 20 : tmp = SA_RENEW_ARRAY(sa->pa, char*, sa->blks, sa->size, osz);
173 : else
174 922 : tmp = RENEW_ARRAY(char*, sa->blks, sa->size);
175 942 : if (tmp == NULL) {
176 0 : sa->size /= 2; /* undo */
177 0 : if (sa->eb.enabled)
178 0 : eb_error(&sa->eb, "out of memory", 1000);
179 0 : if (!sa->pa)
180 0 : GDKfree(r);
181 0 : return NULL;
182 : }
183 942 : sa->blks = tmp;
184 : }
185 491264 : if (sz > SA_BLOCK) {
186 214 : sa->blks[sa->nr] = sa->blks[sa->nr-1];
187 214 : sa->blks[sa->nr-1] = r;
188 214 : sa->nr ++;
189 214 : sa->usedmem += sz;
190 : } else {
191 491050 : sa->blks[sa->nr] = r;
192 491050 : sa->nr ++;
193 491050 : sa->used = sz;
194 491050 : sa->usedmem += SA_BLOCK;
195 : }
196 : } else {
197 239714614 : r = sa->blks[sa->nr-1] + sa->used;
198 239714614 : sa->used += sz;
199 : }
200 : return r;
201 : }
202 :
203 : #undef sa_zalloc
204 10004197 : void *sa_zalloc( sql_allocator *sa, size_t sz )
205 : {
206 10004197 : void *r = sa_alloc(sa, sz);
207 :
208 10004099 : if (r)
209 10004099 : memset(r, 0, sz);
210 10004099 : return r;
211 : }
212 :
213 196266 : void sa_destroy( sql_allocator *sa )
214 : {
215 196266 : if (sa->pa) {
216 125904 : sa_reset(sa);
217 125904 : sa_free(sa->pa, sa->blks[0]);
218 125904 : return;
219 : }
220 :
221 70362 : sa_destroy_freelist(sa->freelist);
222 398406 : for (size_t i = 0; i<sa->nr; i++) {
223 328044 : GDKfree(sa->blks[i]);
224 : }
225 70362 : GDKfree(sa->blks);
226 70362 : GDKfree(sa);
227 : }
228 :
229 : #undef sa_strndup
230 23365947 : char *sa_strndup( sql_allocator *sa, const char *s, size_t l)
231 : {
232 23365947 : char *r = sa_alloc(sa, l+1);
233 :
234 23365682 : if (r) {
235 23365682 : memcpy(r, s, l);
236 23365682 : r[l] = 0;
237 : }
238 23365682 : return r;
239 : }
240 :
241 : #undef sa_strdup
242 18124194 : char *sa_strdup( sql_allocator *sa, const char *s )
243 : {
244 18124194 : return sa_strndup( sa, s, strlen(s));
245 : }
246 :
247 42020 : char *sa_strconcat( sql_allocator *sa, const char *s1, const char *s2 )
248 : {
249 42020 : size_t l1 = strlen(s1);
250 42020 : size_t l2 = strlen(s2);
251 42020 : char *r = sa_alloc(sa, l1+l2+1);
252 :
253 42020 : if (l1)
254 42020 : memcpy(r, s1, l1);
255 42020 : if (l2)
256 42020 : memcpy(r+l1, s2, l2);
257 42020 : r[l1+l2] = 0;
258 42020 : return r;
259 : }
260 :
261 0 : size_t sa_size( sql_allocator *sa )
262 : {
263 0 : return sa->usedmem;
264 : }
265 :
266 : void
267 0 : c_delete( const void *p )
268 : {
269 0 : void *xp = (void*)p;
270 :
271 0 : GDKfree(xp);
272 0 : }
|