1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9#include "monetdb_config.h"
10#include "sql_mem.h"
11
12sql_ref *
13sql_ref_init(sql_ref *r)
14{
15 r->refcnt = 1;
16 return r;
17}
18
19int
20sql_ref_inc(sql_ref *r)
21{
22 assert(r->refcnt > 0);
23 return (++r->refcnt);
24}
25
26int
27sql_ref_dec(sql_ref *r)
28{
29 assert(r->refcnt > 0);
30 return (--r->refcnt);
31}
32
33
34#define SA_BLOCK (64*1024)
35
36sql_allocator *sa_create(void)
37{
38 sql_allocator *sa = MNEW(sql_allocator);
39 if (sa == NULL) {
40 return NULL;
41 }
42 sa->size = 64;
43 sa->nr = 1;
44 sa->blks = NEW_ARRAY(char*,sa->size);
45 if (sa->blks == NULL) {
46 _DELETE(sa);
47 return NULL;
48 }
49 sa->blks[0] = NEW_ARRAY(char,SA_BLOCK);
50 sa->usedmem = SA_BLOCK;
51 if (sa->blks[0] == NULL) {
52 _DELETE(sa->blks);
53 _DELETE(sa);
54 return NULL;
55 }
56 sa->used = 0;
57 return sa;
58}
59
60sql_allocator *sa_reset( sql_allocator *sa )
61{
62 size_t i ;
63
64 for (i = 1; i<sa->nr; i++) {
65 _DELETE(sa->blks[i]);
66 }
67 sa->nr = 1;
68 sa->used = 0;
69 sa->usedmem = SA_BLOCK;
70 return sa;
71}
72
73#undef sa_realloc
74#undef sa_alloc
75void *sa_realloc( sql_allocator *sa, void *p, size_t sz, size_t oldsz )
76{
77 void *r = sa_alloc(sa, sz);
78
79 memcpy(r, p, oldsz);
80 return r;
81}
82
83#define round16(sz) ((sz+15)&~15)
84void *sa_alloc( sql_allocator *sa, size_t sz )
85{
86 char *r;
87 sz = round16(sz);
88 if (sz > (SA_BLOCK-sa->used)) {
89 r = GDKmalloc(sz > SA_BLOCK ? sz : SA_BLOCK);
90 if (r == NULL)
91 return NULL;
92 if (sa->nr >= sa->size) {
93 char **tmp;
94 sa->size *=2;
95 tmp = RENEW_ARRAY(char*,sa->blks,sa->size);
96 if (tmp == NULL) {
97 sa->size /= 2; /* undo */
98 return NULL;
99 }
100 sa->blks = tmp;
101 }
102 if (sz > SA_BLOCK) {
103 sa->blks[sa->nr] = sa->blks[sa->nr-1];
104 sa->blks[sa->nr-1] = r;
105 sa->nr ++;
106 sa->usedmem += sz;
107 } else {
108 sa->blks[sa->nr] = r;
109 sa->nr ++;
110 sa->used = sz;
111 sa->usedmem += SA_BLOCK;
112 }
113 } else {
114 r = sa->blks[sa->nr-1] + sa->used;
115 sa->used += sz;
116 }
117 return r;
118}
119
120#undef sa_zalloc
121void *sa_zalloc( sql_allocator *sa, size_t sz )
122{
123 void *r = sa_alloc(sa, sz);
124
125 if (r)
126 memset(r, 0, sz);
127 return r;
128}
129
130void sa_destroy( sql_allocator *sa )
131{
132 size_t i ;
133
134 for (i = 0; i<sa->nr; i++) {
135 GDKfree(sa->blks[i]);
136 }
137 GDKfree(sa->blks);
138 GDKfree(sa);
139}
140
141#undef sa_strndup
142char *sa_strndup( sql_allocator *sa, const char *s, size_t l)
143{
144 char *r = sa_alloc(sa, l+1);
145
146 if (r) {
147 memcpy(r, s, l);
148 r[l] = 0;
149 }
150 return r;
151}
152
153#undef sa_strdup
154char *sa_strdup( sql_allocator *sa, const char *s )
155{
156 return sa_strndup( sa, s, strlen(s));
157}
158
159char *sa_strconcat( sql_allocator *sa, const char *s1, const char *s2 )
160{
161 size_t l1 = strlen(s1);
162 size_t l2 = strlen(s2);
163 char *r = sa_alloc(sa, l1+l2+1);
164
165 if (l1)
166 memcpy(r, s1, l1);
167 if (l2)
168 memcpy(r+l1, s2, l2);
169 r[l1+l2] = 0;
170 return r;
171}
172
173size_t sa_size( sql_allocator *sa )
174{
175 return sa->usedmem;
176}
177
178void
179c_delete( const void *p )
180{
181 void *xp = (void*)p;
182
183 GDKfree(xp);
184}
185