📄 gdk_desc.mx
字号:
@' The contents of this file are subject to the MonetDB Public License@' Version 1.1 (the "License"); you may not use this file except in@' compliance with the License. You may obtain a copy of the License at@' http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html@'@' Software distributed under the License is distributed on an "AS IS"@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the@' License for the specific language governing rights and limitations@' under the License.@'@' The Original Code is the MonetDB Database System.@'@' The Initial Developer of the Original Code is CWI.@' Portions created by CWI are Copyright (C) 1997-2007 CWI.@' All Rights Reserved.@f gdk_desc@a Peter Boncz@v 1.0@+ BAT Descriptor VersionsChanges to the BAT descriptors cause problems, as persistentBATs with older descriptor versions may still be around. BAT versionsare marked in the first field of a BAT. We only recognize the current BATformat, all older versions are discarded (please use dump/restore).To solve networking problems we can convert between little-endian and big-endian formats. This problem is resolved using a lazy approach.Intel saves BATs in different format than Sun, but when one loads the other,they do on-the-fly conversions using the new routine @%BATconvert@.This routine uses little/big-endian conversion functionality newlyintroduced to the atom ADT (atomConvert and atomHeapConvert).@h#ifndef _GDK_DESC_H_#define _GDK_DESC_H_@+ BAT versionsThree BAT formats are currently supported:@h#define GDKversionOK(x) ((x)>=GDKLIBRARY_OLD && (x)<=GDKLIBRARY)@If BATs need to be added to an old BBP directory, we might needto save BATs in the old format. This is currently controlledby the below function:@We also use these numbers, which are always the first 16-bits of theBAT image, to check whether the image is in big endian or little endian format.@{@c#include "monetdb_config.h"#include "gdk.h"@+ BAT Conversion functionsThese functions save/load a BAT descriptor to/from disk.@hint BATsavedesc(BAT *b, str nme);BAT *BATloaddesc(str nme);@Convert a BAT that contains little-endian data into big endian (or vice versa).@hgdk_export BAT *BATconvert(BAT *b, int direction);@- defines@h@{typedef unsigned int normal_int;#define strcpy_COPY(x,y) strcpy(x,y);#define short_int_COPY(x) x#define normal_int_COPY(x) x#define normal_bat_COPY(x) x#define long_long_COPY(x) x#define normal_oid_COPY(x) x#define normal_sizet_COPY(x) x#define normal_hasht_COPY(x) x#define normal_BUN_COPY(x) x#define strcpy_SWAP(x,y)#define normal_bat_SWAP(x) ((bat) normal_int_SWAP((int) x))#if SIZEOF_OID == SIZEOF_INT#define normal_oid_SWAP(x) ((oid) normal_int_SWAP((int)x))#else#define normal_oid_SWAP(x) ((oid) long_long_SWAP((lng)x))#endif#if SIZEOF_SIZE_T == SIZEOF_INT#define normal_sizet_SWAP(x) ((size_t) normal_int_SWAP((int)x))#define normal_vart_SWAP(x) ((var_t) normal_int_SWAP((int)x))#define normal_hasht_SWAP(x) ((hash_t) normal_int_SWAP((int)x))#define normal_BUN_SWAP(x) ((BUN) normal_int_SWAP((int)x))#else#define normal_sizet_SWAP(x) ((size_t) long_long_SWAP((lng)x))#define normal_vart_SWAP(x) ((var_t) long_long_SWAP((lng)x))#define normal_hasht_SWAP(x) ((hash_t) long_long_SWAP((lng)x))#define normal_BUN_SWAP(x) ((BUN) long_long_SWAP((lng)x))#endif#endif /* _GDK_DESC_H_ */@}@+ implementations@- BATsavedesc@cintBATsavedesc(BAT *b, str nme){ BATstore *bs = (BATstore *) b; int ret = 0, fd = -1; DELTAsave(b); if (b->GDKversion == GDKLIBRARY) { char *hatm = (b->htype>=0)?ATOMname(b->htype): ATOMunknown_name(b->htype); char *tatm = (b->ttype>=0)?ATOMname(b->ttype): ATOMunknown_name(b->ttype); int hlen = (int) strlen(hatm) + 1; int tlen = (int) strlen(tatm) + 1; int hvar = b->hvarsized && (b->htype != TYPE_void); int tvar = b->tvarsized && (b->ttype != TYPE_void); if ((fd = GDKfdlocate(nme, "wb", "desc")) < 0 || write(fd, bs, sizeof(BATstore)) != sizeof(BATstore) || (hvar && write(fd, b->hheap, sizeof(Heap)) != sizeof(Heap)) || (tvar && write(fd, b->theap, sizeof(Heap)) != sizeof(Heap)) || (write(fd, &hlen, sizeof(int)) != sizeof(int)) || (write(fd, hatm, hlen ) != hlen) || (write(fd, &tlen, sizeof(int)) != sizeof(int)) || (write(fd, tatm, tlen ) != tlen)) { ret = -1; } if (fd >= 0) close(fd); } /* a saved bat could still be used so reset the delta status */ DELTAload(b); return (ret < 0) ? ret : 0;}@- BATloaddesc@cBAT *BATloaddesc(str nme){ long_str hatm; long_str tatm; BATstore *dst; BAT *b = NULL; int ver, fd = -1, hvar, tvar; ssize_t n; if ((fd = GDKfdlocate(nme, "rb+", "desc")) < 0) { GDKerror("BATloaddesc: cannot open desc file=%s\n", nme); return NULL; } dst = (BATstore *) GDKzalloc(sizeof(BATstore)); if (!dst) return NULL; if ((n = read(fd, dst, sizeof(BATstore)) != sizeof(BATstore)) ) { GDKerror("BATloaddesc: read error: name=%s, n=%d\n", nme, n); GDKfree(dst); close(fd); return NULL; } ver = dst->B.GDKversion; if (!GDKversionOK(ver)) { GDKerror("GDKload: incompatible version %d.\n", dst->B.GDKversion); GDKfree(dst); close(fd); return NULL; } b = (BAT *) dst; b->H = &dst->H; b->T = &dst->T; b->P = &dst->P; b->U = &dst->U; b->hident = b->tident = NULL; BATroles(b, NULL, NULL); b->batBuns = &b->U->buns; b->batBuns->base = NULL; b->batBuns->filename = NULL; b->hheap = b->theap = NULL; hvar = b->hvarsized && (b->htype != TYPE_void); tvar = b->tvarsized && (b->ttype != TYPE_void); if (hvar && ((b->hheap = (Heap*)GDKzalloc(sizeof(Heap))) == NULL || (n = read(fd, b->hheap, sizeof(Heap))) != sizeof(Heap) )) { GDKerror("BATloaddesc: read error: name=%s, n=%d\n", nme, n); if (b->hheap) GDKfree(b->hheap); GDKfree(dst); close(fd); return NULL; } if (tvar && ((b->theap = (Heap*)GDKzalloc(sizeof(Heap))) == NULL || (n = read(fd, b->theap, sizeof(Heap))) != sizeof(Heap) )) { GDKerror("BATloaddesc: read error: name=%s, n=%d\n", nme, n); if (b->hheap) GDKfree(b->hheap); if (b->theap) GDKfree(b->theap); GDKfree(dst); close(fd); return NULL; } if ( (read(fd, &ver, sizeof(int)) != sizeof(int)) || ver > BUFSIZ || (read(fd, hatm, ver) != ver) || (read(fd, &ver, sizeof(int)) != sizeof(int)) || ver > BUFSIZ || (read(fd, tatm, ver) != ver) ) { if (b->hheap) GDKfree(b->hheap); if (b->theap) GDKfree(b->theap); GDKfree(dst); close(fd); return NULL; } close(fd); /* mark atom as unknown if its not loaded jet */ if (!ATOMname(b->htype) || strcmp(ATOMname(b->htype), hatm) != 0) { int ht = ATOMindex(hatm); if (ht < 0 || BATatoms[ht].deleting) { ht = ATOMunknown_find(hatm); } b->htype = ht; } if (!ATOMname(b->ttype) || strcmp(ATOMname(b->ttype), tatm) != 0) { int tt = ATOMindex(tatm); if (tt < 0 || BATatoms[tt].deleting) { tt = ATOMunknown_find(tatm); } b->ttype = tt; } if (b->hheap) { b->hheap->base = NULL; b->hheap->filename = NULL; } if (b->theap) { b->theap->base = NULL; b->theap->filename = NULL; } /* probably need to allocate heaps here */ b->batCopiedtodisk = 1; b->batElmshift = BATelmshift(b); b->H->props = NULL; b->T->props = NULL; b->hhash = b->thash = NULL; return b;}@}@- big endian vs little endianThis function uses the byte order conversion ADT functionsto convert a little endian BAT to big endian (or vice versa).@{@= swap { @2 *_p = (@2*) @3, _i=*_p; *_p = @1_SWAP(_i); }@cstatic intbatswap(BAT *b, int direction){ void (*fcn) (ptr, int) = BATatoms[b->htype].atomConvert; BUN p, q; int xx; switch (ATOMstorage(b->htype)) { case TYPE_void: case TYPE_chr: case TYPE_bte: break; case TYPE_sht: DELloop(b, p, q, xx) @:swap(short_int,sht,BUNhloc(b,p))@ BATloopFast(b, p, q, xx) @:swap(short_int,sht,BUNhloc(b,p))@ break; case TYPE_int: case TYPE_flt: DELloop(b, p, q, xx) @:swap(normal_int,int,BUNhloc(b,p))@ BATloopFast(b, p, q, xx) @:swap(normal_int,int,BUNhloc(b,p))@ break; case TYPE_lng: case TYPE_dbl: DELloop(b, p, q, xx) @:swap(long_long,lng,BUNhloc(b,p))@ BATloopFast(b, p, q, xx) @:swap(long_long,lng,BUNhloc(b,p))@ break; default: ATOMheapConvert(b->htype, b->hheap, direction); DELloop(b, p, q, xx) { @:swap(normal_int,int,BUNhloc(b,p))@ if (fcn != NULL) (*fcn) (BUNhead(b, p), direction); } BATloopFast(b, p, q, xx) { @:swap(normal_int,int,BUNhloc(b,p))@ if (fcn != NULL) (*fcn) (BUNhead(b, p), direction); } } return TRUE;}BAT *BATconvert(BAT *b, int direction){ if (batswap(b, direction)) { if (!batswap(BATmirror(b), direction)) { batswap(b, direction == CONV_HTON ? CONV_NTOH : CONV_HTON); } } b->batDirty = 1; return b;}@}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -