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/* This file should not be included in any file outside of this directory */
10
11#ifndef LIBGDK
12#error this file should not be included outside its source directory
13#endif
14
15/* persist hash heaps for persistent BATs */
16#define PERSISTENTHASH 1
17
18/* persist order index heaps for persistent BATs */
19#define PERSISTENTIDX 1
20
21#include "gdk_system_private.h"
22
23enum heaptype {
24 offheap,
25 varheap,
26 hashheap,
27 imprintsheap,
28 orderidxheap
29};
30
31#ifdef GDKLIBRARY_OLDDATE
32__hidden int cvtdate(int n)
33 __attribute__((__visibility__("hidden")));
34#endif
35
36__hidden gdk_return ATOMheap(int id, Heap *hp, size_t cap)
37 __attribute__((__warn_unused_result__))
38 __attribute__((__visibility__("hidden")));
39__hidden bool ATOMisdescendant(int id, int parentid)
40 __attribute__((__visibility__("hidden")));
41__hidden int ATOMunknown_find(const char *nme)
42 __attribute__((__warn_unused_result__))
43 __attribute__((__visibility__("hidden")));
44__hidden str ATOMunknown_name(int a)
45 __attribute__((__visibility__("hidden")));
46__hidden void ATOMunknown_clean(void)
47 __attribute__((__visibility__("hidden")));
48__hidden bool BATcheckhash(BAT *b)
49 __attribute__((__visibility__("hidden")));
50__hidden bool BATcheckimprints(BAT *b)
51 __attribute__((__visibility__("hidden")));
52__hidden gdk_return BATcheckmodes(BAT *b, bool persistent)
53 __attribute__((__warn_unused_result__))
54 __attribute__((__visibility__("hidden")));
55__hidden BAT *BATcreatedesc(oid hseq, int tt, bool heapnames, role_t role)
56 __attribute__((__visibility__("hidden")));
57__hidden void BATdelete(BAT *b)
58 __attribute__((__visibility__("hidden")));
59__hidden void BATdestroy(BAT *b)
60 __attribute__((__visibility__("hidden")));
61__hidden void BATfree(BAT *b)
62 __attribute__((__visibility__("hidden")));
63__hidden PROPrec *BATgetprop(BAT *b, enum prop_t idx)
64 __attribute__((__visibility__("hidden")));
65__hidden PROPrec * BATgetprop_nolock(BAT *b, enum prop_t idx)
66 __attribute__((__visibility__("hidden")));
67__hidden gdk_return BATgroup_internal(BAT **groups, BAT **extents, BAT **histo, BAT *b, BAT *s, BAT *g, BAT *e, BAT *h, bool subsorted)
68 __attribute__((__warn_unused_result__))
69 __attribute__((__visibility__("hidden")));
70__hidden Hash *BAThash_impl(BAT *b, BAT *s, const char *ext)
71 __attribute__((__visibility__("hidden")));
72__hidden void BATinit_idents(BAT *bn)
73 __attribute__((__visibility__("hidden")));
74__hidden BAT *BATload_intern(bat bid, bool lock)
75 __attribute__((__visibility__("hidden")));
76__hidden gdk_return BATmaterialize(BAT *b)
77 __attribute__((__warn_unused_result__))
78 __attribute__((__visibility__("hidden")));
79__hidden void BATrmprop(BAT *b, enum prop_t idx)
80 __attribute__((__visibility__("hidden")));
81__hidden void BATsetdims(BAT *b)
82 __attribute__((__visibility__("hidden")));
83__hidden void BATsetprop(BAT *b, enum prop_t idx, int type, const void *v)
84 __attribute__((__visibility__("hidden")));
85__hidden void BATsetprop_nolock(BAT *b, enum prop_t idx, int type, const void *v)
86 __attribute__((__visibility__("hidden")));
87__hidden gdk_return BBPcacheit(BAT *bn, bool lock)
88 __attribute__((__warn_unused_result__))
89 __attribute__((__visibility__("hidden")));
90void BBPdump(void) /* never called: for debugging only */
91 __attribute__((__cold__));
92__hidden void BBPexit(void)
93 __attribute__((__visibility__("hidden")));
94__hidden BAT *BBPgetdesc(bat i)
95 __attribute__((__visibility__("hidden")));
96__hidden gdk_return BBPinit(void)
97 __attribute__((__visibility__("hidden")));
98__hidden bat BBPinsert(BAT *bn)
99 __attribute__((__warn_unused_result__))
100 __attribute__((__visibility__("hidden")));
101__hidden int BBPselectfarm(role_t role, int type, enum heaptype hptype)
102 __attribute__((__visibility__("hidden")));
103__hidden void BBPunshare(bat b)
104 __attribute__((__visibility__("hidden")));
105__hidden BUN binsearch(const oid *restrict indir, oid offset, int type, const void *restrict vals, const char * restrict vars, int width, BUN lo, BUN hi, const void *restrict v, int ordering, int last)
106 __attribute__((__visibility__("hidden")));
107__hidden BUN binsearch_bte(const oid *restrict indir, oid offset, const bte *restrict vals, BUN lo, BUN hi, bte v, int ordering, int last)
108 __attribute__((__visibility__("hidden")));
109__hidden BUN binsearch_sht(const oid *restrict indir, oid offset, const sht *restrict vals, BUN lo, BUN hi, sht v, int ordering, int last)
110 __attribute__((__visibility__("hidden")));
111__hidden BUN binsearch_int(const oid *restrict indir, oid offset, const int *restrict vals, BUN lo, BUN hi, int v, int ordering, int last)
112 __attribute__((__visibility__("hidden")));
113__hidden BUN binsearch_lng(const oid *restrict indir, oid offset, const lng *restrict vals, BUN lo, BUN hi, lng v, int ordering, int last)
114 __attribute__((__visibility__("hidden")));
115#ifdef HAVE_HGE
116__hidden BUN binsearch_hge(const oid *restrict indir, oid offset, const hge *restrict vals, BUN lo, BUN hi, hge v, int ordering, int last)
117 __attribute__((__visibility__("hidden")));
118#endif
119__hidden BUN binsearch_flt(const oid *restrict indir, oid offset, const flt *restrict vals, BUN lo, BUN hi, flt v, int ordering, int last)
120 __attribute__((__visibility__("hidden")));
121__hidden BUN binsearch_dbl(const oid *restrict indir, oid offset, const dbl *restrict vals, BUN lo, BUN hi, dbl v, int ordering, int last)
122 __attribute__((__visibility__("hidden")));
123__hidden gdk_return BUNreplace(BAT *b, oid left, const void *right, bool force)
124 __attribute__((__warn_unused_result__))
125 __attribute__((__visibility__("hidden")));
126__hidden Heap *createOIDXheap(BAT *b, bool stable)
127 __attribute__((__visibility__("hidden")));
128__hidden void gdk_bbp_reset(void)
129 __attribute__((__visibility__("hidden")));
130__hidden gdk_return GDKextend(const char *fn, size_t size)
131 __attribute__((__warn_unused_result__))
132 __attribute__((__visibility__("hidden")));
133__hidden gdk_return GDKextendf(int fd, size_t size, const char *fn)
134 __attribute__((__warn_unused_result__))
135 __attribute__((__visibility__("hidden")));
136__hidden int GDKfdlocate(int farmid, const char *nme, const char *mode, const char *ext)
137 __attribute__((__visibility__("hidden")));
138__hidden FILE *GDKfilelocate(int farmid, const char *nme, const char *mode, const char *ext)
139 __attribute__((__visibility__("hidden")));
140__hidden FILE *GDKfileopen(int farmid, const char *dir, const char *name, const char *extension, const char *mode)
141 __attribute__((__visibility__("hidden")));
142__hidden char *GDKload(int farmid, const char *nme, const char *ext, size_t size, size_t *maxsize, storage_t mode)
143 __attribute__((__visibility__("hidden")));
144__hidden void GDKlog(_In_z_ _Printf_format_string_ FILE * fl, const char *format, ...)
145 __attribute__((__format__(__printf__, 2, 3)))
146 __attribute__((__visibility__("hidden")));
147__hidden gdk_return GDKmove(int farmid, const char *dir1, const char *nme1, const char *ext1, const char *dir2, const char *nme2, const char *ext2)
148 __attribute__((__warn_unused_result__))
149 __attribute__((__visibility__("hidden")));
150__hidden void *GDKmremap(const char *path, int mode, void *old_address, size_t old_size, size_t *new_size)
151 __attribute__((__visibility__("hidden")));
152__hidden gdk_return GDKmunmap(void *addr, size_t len)
153 __attribute__((__warn_unused_result__))
154 __attribute__((__visibility__("hidden")));
155__hidden gdk_return GDKremovedir(int farmid, const char *nme)
156 __attribute__((__warn_unused_result__))
157 __attribute__((__visibility__("hidden")));
158__hidden gdk_return GDKsave(int farmid, const char *nme, const char *ext, void *buf, size_t size, storage_t mode, bool dosync)
159 __attribute__((__warn_unused_result__))
160 __attribute__((__visibility__("hidden")));
161__hidden gdk_return GDKssort_rev(void *restrict h, void *restrict t, const void *restrict base, size_t n, int hs, int ts, int tpe)
162 __attribute__((__warn_unused_result__))
163 __attribute__((__visibility__("hidden")));
164__hidden gdk_return GDKssort(void *restrict h, void *restrict t, const void *restrict base, size_t n, int hs, int ts, int tpe)
165 __attribute__((__warn_unused_result__))
166 __attribute__((__visibility__("hidden")));
167__hidden gdk_return GDKunlink(int farmid, const char *dir, const char *nme, const char *extension)
168 __attribute__((__visibility__("hidden")));
169#ifdef NATIVE_WIN32
170__hidden void GDKwinerror(_In_z_ _Printf_format_string_ const char *format, ...)
171 __attribute__((__format__(__printf__, 1, 2)))
172 __attribute__((__visibility__("hidden")));
173#endif
174__hidden void HASHfree(BAT *b)
175 __attribute__((__visibility__("hidden")));
176__hidden bool HASHgonebad(BAT *b, const void *v)
177 __attribute__((__visibility__("hidden")));
178__hidden BUN HASHmask(BUN cnt)
179 __attribute__((__visibility__("hidden")));
180__hidden gdk_return HASHnew(Hash *h, int tpe, BUN size, BUN mask, BUN count)
181 __attribute__((__visibility__("hidden")));
182__hidden gdk_return HEAPalloc(Heap *h, size_t nitems, size_t itemsize)
183 __attribute__((__warn_unused_result__))
184 __attribute__((__visibility__("hidden")));
185__hidden gdk_return HEAPcopy(Heap *dst, Heap *src)
186 __attribute__((__warn_unused_result__))
187 __attribute__((__visibility__("hidden")));
188__hidden gdk_return HEAPdelete(Heap *h, const char *o, const char *ext)
189 __attribute__((__visibility__("hidden")));
190__hidden void HEAPfree(Heap *h, bool remove)
191 __attribute__((__visibility__("hidden")));
192__hidden gdk_return HEAPload(Heap *h, const char *nme, const char *ext, bool trunc)
193 __attribute__((__warn_unused_result__))
194 __attribute__((__visibility__("hidden")));
195__hidden void HEAP_recover(Heap *, const var_t *, BUN)
196 __attribute__((__visibility__("hidden")));
197__hidden gdk_return HEAPsave(Heap *h, const char *nme, const char *ext)
198 __attribute__((__warn_unused_result__))
199 __attribute__((__visibility__("hidden")));
200__hidden gdk_return HEAPshrink(Heap *h, size_t size)
201 __attribute__((__warn_unused_result__))
202 __attribute__((__visibility__("hidden")));
203__hidden int HEAPwarm(Heap *h)
204 __attribute__((__visibility__("hidden")));
205__hidden void IMPSfree(BAT *b)
206 __attribute__((__visibility__("hidden")));
207__hidden int IMPSgetbin(int tpe, bte bits, const char *restrict bins, const void *restrict v)
208 __attribute__((__visibility__("hidden")));
209#ifndef NDEBUG
210void IMPSprint(BAT *b) /* never called: for debugging only */
211 __attribute__((__cold__));
212#endif
213__hidden void MT_init_posix(void)
214 __attribute__((__visibility__("hidden")));
215__hidden void *MT_mremap(const char *path, int mode, void *old_address, size_t old_size, size_t *new_size)
216 __attribute__((__visibility__("hidden")));
217__hidden int MT_msync(void *p, size_t len)
218 __attribute__((__visibility__("hidden")));
219__hidden void OIDXfree(BAT *b)
220 __attribute__((__visibility__("hidden")));
221__hidden void persistOIDX(BAT *b)
222 __attribute__((__visibility__("hidden")));
223__hidden void PROPdestroy(BAT *b)
224 __attribute__((__visibility__("hidden")));
225__hidden gdk_return rangejoin(BAT *r1, BAT *r2, BAT *l, BAT *rl, BAT *rh, struct canditer *lci, struct canditer *rci, bool li, bool hi, bool anti, bool symmetric, BUN maxsize)
226 __attribute__((__warn_unused_result__))
227 __attribute__((__visibility__("hidden")));
228__hidden void strCleanHash(Heap *hp, bool rebuild)
229 __attribute__((__visibility__("hidden")));
230__hidden int strCmp(const char *l, const char *r)
231 __attribute__((__visibility__("hidden")));
232__hidden int strCmpNoNil(const unsigned char *l, const unsigned char *r)
233 __attribute__((__visibility__("hidden")));
234__hidden void strHeap(Heap *d, size_t cap)
235 __attribute__((__visibility__("hidden")));
236__hidden var_t strLocate(Heap *h, const char *v)
237 __attribute__((__visibility__("hidden")));
238__hidden var_t strPut(Heap *h, var_t *dst, const char *v)
239 __attribute__((__visibility__("hidden")));
240__hidden str strRead(str a, stream *s, size_t cnt)
241 __attribute__((__visibility__("hidden")));
242__hidden ssize_t strToStr(char **restrict dst, size_t *restrict len, const char *restrict src, bool external)
243 __attribute__((__visibility__("hidden")));
244__hidden gdk_return strWrite(const char *a, stream *s, size_t cnt)
245 __attribute__((__visibility__("hidden")));
246__hidden gdk_return unshare_string_heap(BAT *b)
247 __attribute__((__warn_unused_result__))
248 __attribute__((__visibility__("hidden")));
249__hidden void VIEWdestroy(BAT *b)
250 __attribute__((__visibility__("hidden")));
251__hidden gdk_return VIEWreset(BAT *b)
252 __attribute__((__warn_unused_result__))
253 __attribute__((__visibility__("hidden")));
254__hidden BAT *virtualize(BAT *bn)
255 __attribute__((__visibility__("hidden")));
256
257/* some macros to help print info about BATs when using ALGODEBUG */
258#define ALGOBATFMT "%s#" BUNFMT "@" OIDFMT "[%s]%s%s%s%s%s%s%s%s%s"
259#define ALGOBATPAR(b) BATgetId(b), \
260 BATcount(b), \
261 b->hseqbase, \
262 ATOMname(b->ttype), \
263 !b->batTransient ? "P" : isVIEW(b) ? "V" : "T", \
264 BATtdense(b) ? "D" : b->ttype == TYPE_void && b->tvheap ? "X" :"", \
265 b->tsorted ? "S" : "", \
266 b->trevsorted ? "R" : "", \
267 b->tkey ? "K" : "", \
268 b->tnonil ? "N" : "", \
269 b->thash ? "H" : "", \
270 b->torderidx ? "O" : "", \
271 b->timprints ? "I" : b->theap.parentid && BBP_cache(b->theap.parentid)->timprints ? "(I)" : ""
272/* use ALGOOPTBAT* when BAT is optional (can be NULL) */
273#define ALGOOPTBATFMT "%s%s" BUNFMT "%s" OIDFMT "%s%s%s%s%s%s%s%s%s%s%s%s"
274#define ALGOOPTBATPAR(b) \
275 b ? BATgetId(b) : "", \
276 b ? "#" : "", \
277 b ? BATcount(b) : 0, \
278 b ? "@" : "", \
279 b ? b->hseqbase : 0, \
280 b ? "[" : "", \
281 b ? ATOMname(b->ttype) : "", \
282 b ? "]" : "", \
283 b ? !b->batTransient ? "P" : isVIEW(b) ? "V" : "T" : "", \
284 b && BATtdense(b) ? "D" : b && b->ttype == TYPE_void && b->tvheap ? "X" :"", \
285 b && b->tsorted ? "S" : "", \
286 b && b->trevsorted ? "R" : "", \
287 b && b->tkey ? "K" : "", \
288 b && b->tnonil ? "N" : "", \
289 b && b->thash ? "H" : "", \
290 b && b->torderidx ? "O" : "", \
291 b ? b->timprints ? "I" : b->theap.parentid && BBP_cache(b->theap.parentid)->timprints ? "(I)" : "" : ""
292
293#define BBP_BATMASK (128 * SIZEOF_SIZE_T - 1)
294#define BBP_THREADMASK 63
295
296struct PROPrec {
297 enum prop_t id;
298 ValRecord v;
299 struct PROPrec *next; /* simple chain of properties */
300};
301
302struct Imprints {
303 bte bits; /* how many bits in imprints */
304 Heap imprints;
305 void *bins; /* pointer into imprints heap (bins borders) */
306 BUN *stats; /* pointer into imprints heap (stats per bin) */
307 void *imps; /* pointer into imprints heap (bit vectors) */
308 void *dict; /* pointer into imprints heap (dictionary) */
309 BUN impcnt; /* counter for imprints */
310 BUN dictcnt; /* counter for cache dictionary */
311};
312
313typedef struct {
314 MT_Lock swap;
315} batlock_t;
316
317typedef struct {
318 MT_Lock cache;
319 MT_Lock trim;
320 bat free;
321} bbplock_t;
322
323typedef char long_str[IDLENGTH]; /* standard GDK static string */
324
325#define MAXFARMS 32
326
327extern struct BBPfarm_t {
328 unsigned int roles; /* bitmask of allowed roles */
329 const char *dirname; /* farm directory */
330 FILE *lock_file;
331} BBPfarms[MAXFARMS];
332
333extern batlock_t GDKbatLock[BBP_BATMASK + 1];
334extern bbplock_t GDKbbpLock[BBP_THREADMASK + 1];
335extern size_t GDK_mmap_minsize_persistent; /* size after which we use memory mapped files for persistent heaps */
336extern size_t GDK_mmap_minsize_transient; /* size after which we use memory mapped files for transient heaps */
337extern size_t GDK_mmap_pagesize; /* mmap granularity */
338extern MT_Lock GDKnameLock;
339extern MT_Lock GDKthreadLock;
340extern MT_Lock GDKtmLock;
341
342#define BATcheck(tst, msg, err) \
343 do { \
344 if ((tst) == NULL) { \
345 if (strchr((msg), ':')) \
346 GDKerror("%s.\n", (msg)); \
347 else \
348 GDKerror("%s: BAT required.\n", (msg)); \
349 return (err); \
350 } \
351 } while (0)
352#define ERRORcheck(tst, msg, err) \
353 do { \
354 if (tst) { \
355 GDKerror(msg); \
356 return (err); \
357 } \
358 } while (0)
359
360#define GDKswapLock(x) GDKbatLock[(x)&BBP_BATMASK].swap
361#if SIZEOF_SIZE_T == 8
362#define threadmask(y) ((int) ((mix_int((unsigned int) y) ^ mix_int((unsigned int) (y >> 32))) & BBP_THREADMASK))
363#else
364#define threadmask(y) ((int) (mix_int(y) & BBP_THREADMASK))
365#endif
366#define GDKtrimLock(y) GDKbbpLock[y].trim
367#define GDKcacheLock(y) GDKbbpLock[y].cache
368#define BBP_free(y) GDKbbpLock[y].free
369
370/* extra space in front of strings in string heaps when hashash is set
371 * if at least (2*SIZEOF_BUN), also store length (heaps are then
372 * incompatible) */
373#define EXTRALEN ((SIZEOF_BUN + GDK_VARALIGN - 1) & ~(GDK_VARALIGN - 1))
374
375#if !defined(NDEBUG) && !defined(STATIC_CODE_ANALYSIS)
376/* see comment in gdk.h */
377#ifdef __GNUC__
378#define GDKmunmap(p, l) \
379 ({ void *_ptr = (p); \
380 size_t _len = (l); \
381 gdk_return _res = GDKmunmap(_ptr, _len); \
382 ALLOCDEBUG \
383 fprintf(stderr, \
384 "#GDKmunmap(%p,%zu) -> %u" \
385 " %s[%s:%d]\n", \
386 _ptr, _len, _res, \
387 __func__, __FILE__, __LINE__); \
388 _res; \
389 })
390#define GDKmremap(p, m, oa, os, ns) \
391 ({ \
392 const char *_path = (p); \
393 int _mode = (m); \
394 void *_oa = (oa); \
395 size_t _os = (os); \
396 size_t *_ns = (ns); \
397 size_t _ons = *_ns; \
398 void *_res = GDKmremap(_path, _mode, _oa, _os, _ns); \
399 ALLOCDEBUG \
400 fprintf(stderr, \
401 "#GDKmremap(%s,0x%x,%p,%zu,%zu > %zu) -> %p" \
402 " %s[%s:%d]\n", \
403 _path ? _path : "NULL", (unsigned) _mode, \
404 _oa, _os, _ons, *_ns, \
405 _res, \
406 __func__, __FILE__, __LINE__); \
407 _res; \
408 })
409#else
410static inline gdk_return
411GDKmunmap_debug(void *ptr, size_t len, const char *filename, int lineno)
412{
413 gdk_return res = GDKmunmap(ptr, len);
414 ALLOCDEBUG fprintf(stderr,
415 "#GDKmunmap(%p,%zu) -> %d [%s:%d]\n",
416 ptr, len, (int) res, filename, lineno);
417 return res;
418}
419#define GDKmunmap(p, l) GDKmunmap_debug((p), (l), __FILE__, __LINE__)
420static inline void *
421GDKmremap_debug(const char *path, int mode, void *old_address, size_t old_size, size_t *new_size, const char *filename, int lineno)
422{
423 size_t orig_new_size = *new_size;
424 void *res = GDKmremap(path, mode, old_address, old_size, new_size);
425 ALLOCDEBUG
426 fprintf(stderr,
427 "#GDKmremap(%s,0x%x,%p,%zu,%zu > %zu) -> %p"
428 " [%s:%d]\n",
429 path ? path : "NULL", mode,
430 old_address, old_size, orig_new_size, *new_size,
431 res,
432 filename, lineno);
433 return res;
434}
435#define GDKmremap(p, m, oa, os, ns) GDKmremap_debug(p, m, oa, os, ns, __FILE__, __LINE__)
436
437#endif
438#endif
439