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 | |
12 | sql_ref * |
13 | sql_ref_init(sql_ref *r) |
14 | { |
15 | r->refcnt = 1; |
16 | return r; |
17 | } |
18 | |
19 | int |
20 | sql_ref_inc(sql_ref *r) |
21 | { |
22 | assert(r->refcnt > 0); |
23 | return (++r->refcnt); |
24 | } |
25 | |
26 | int |
27 | sql_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 | |
36 | sql_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 | |
60 | sql_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 |
75 | void *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) |
84 | void *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 |
121 | void *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 | |
130 | void 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 |
142 | char *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 |
154 | char *sa_strdup( sql_allocator *sa, const char *s ) |
155 | { |
156 | return sa_strndup( sa, s, strlen(s)); |
157 | } |
158 | |
159 | char *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 | |
173 | size_t sa_size( sql_allocator *sa ) |
174 | { |
175 | return sa->usedmem; |
176 | } |
177 | |
178 | void |
179 | c_delete( const void *p ) |
180 | { |
181 | void *xp = (void*)p; |
182 | |
183 | GDKfree(xp); |
184 | } |
185 | |