📄 batextensions.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 batExtensions@v 2.0@a M.L.Kersten, P. Boncz@+ BAT ExtensionsThe kernel libraries are unaware of the MAL runtime semantics.This calls for declaring some operations in the MAL module sectionand register them in the kernel modules explicitly.A good example of this borderline case are BAT creation operations,which require a mapping of the type identifier to the underlyingimplementation type.Another example concerns the (un)pack operations, which directaccess the runtime stack to (push)pull the values needed.@malpattern bat.new(ht:any_1, tt:any_2, b:bat[:any_3,:any_4]) :bat[:any_1,:any_2] address CMDBATclonecomment "Creates a new empty transient BAT by cloning another";pattern bat.new(ht:any_1, tt:any_2) :bat[:any_1,:any_2] address CMDBATnewcomment "Creates a new empty transient BAT, with head- and tail-types as indicated.";pattern bat.new(ht:any_1, tt:any_2, size:int) :bat[:any_1,:any_2] address CMDBATnewintcomment "Creates a new BAT with sufficient space.";pattern bat.new(ht:any_1, tt:any_2, size:lng) :bat[:any_1,:any_2] address CMDBATnewcomment "Creates a new BAT and allocate space.";pattern bat.new(ht:oid, tt:any_2, size:int) :bat[:oid,:any_2] address CMDBATnewint;pattern bat.new(ht:oid, tt:any_2, size:lng) :bat[:oid,:any_2] address CMDBATnew;pattern bat.new(b:bat[:any_1,:any_2] ) :bat[:any_1,:any_2] address CMDBATnewDerived;pattern bat.new(b:bat[:any_1,:any_2], size:lng) :bat[:any_1,:any_2] address CMDBATnewDerived;command bat.new(nme:str):bat[:any_1,:any_2]address CMDBATderivedByNamecomment "Localize a bat by name and produce a variant";command bat.reduce(b:bat[:any_1,:any_2]):bat[:any_1,:any_2]address CMDBATreducecomment "Designate a BAT for which auxillary structures can be dropped";command bat.flush(b:bat[:any_1,:any_2]):voidaddress CMDBATflushcomment "Designate a BAT as not needed anymore";pattern bat.setGarbage(b:bat[:any_1,:any_2]):voidaddress CMDBATsetGarbagecomment "Designate a BAT as garbage";pattern bat.unpack(b:bat[:any_1,:any_2])(h:any_1,t:any_2)address CMDbatunpackcomment "Extract the first tuple from a bat";pattern bat.pack(h:any_1,t:any_2):bat[:any_1,:any_2]address CMDbatpackcomment "Pack a pair into a BAT"; @{@{@include prelude.mx@+ Implementation sectionIn most cases we pass a BAT identifier, which should be unifiedwith a BAT descriptor. Upon failure we can simply abort the function.@c#include "mal_config.h"#include "mal_box.h"#include "mal_client.h"#include "mal_interpreter.h"#include "bat5.h"#include "algebra.h"#ifdef WIN32#ifndef LIBBATEXTENSIONS#define be_export extern __declspec(dllimport)#else#define be_export extern __declspec(dllexport)#endif#else#define be_export extern#endifbe_export str CMDBATsetGarbage(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);be_export str CMDBATflush(int *res, int *bid);be_export str CMDBATreduce(int *ret, int *bid);be_export str CMDBATclone(MalBlkPtr m, MalStkPtr s, InstrPtr p);be_export str CMDBATnew(MalBlkPtr m, MalStkPtr s, InstrPtr p);be_export str CMDBATnewDerived(MalBlkPtr m, MalStkPtr s, InstrPtr p);be_export str CMDBATderivedByName(int *ret, str *nme);be_export str CMDBATnewint(MalBlkPtr m, MalStkPtr s, InstrPtr p);be_export str CMDBBPproject(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);be_export str CMDBBPprojectNil(int *ret, int *bid);be_export str CMDbatunpack(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);be_export str CMDbatpack(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);@-Access to a box calls for resolving the first parameterto a named box. The bbp box is automatically opened.@c#define OpenBox(X) \ box= findBox("bbp");\ if(box == 0 )\ box= openBox("bbp");\ if( box ==0) \ throw(MAL, "bbp." X,"box is not open");@- Operator implementationA BAT designated as garbage can be removed, provided wedo not keep additional references in the stack frameBe careful here not to remove persistent BATs.Note that we clear the dirty bit to ensure thatthe BAT is not written back to store before being freed.@cstrCMDBATsetGarbage(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci){ int *bid; BAT *b; (void) mb; bid = (int *) getArgValue(stk, pci, 1); if ((b = BATdescriptor(*bid)) == NULL) throw(MAL, "bbp.setGarbage", "Cannot access descriptor"); b->batDirty= FALSE; BBPunfix(b->batCacheid); if (*bid) BBPdecref(*bid,TRUE); *bid = 0; return MAL_SUCCEED;}strCMDBATflush(int *ret, int *bid){ BAT *b; if ((b = BATdescriptor(*bid)) == NULL) throw(MAL, "bbp.flush", "Cannot access descriptor"); /* use memory advice to release the BAT */ /* TO BE PROVIDED */ BBPunfix(b->batCacheid); if (*bid) BBPdecref(*bid,TRUE); *ret = 0; return MAL_SUCCEED;}strCMDBATreduce(int *ret, int *bid){ BAT *b; int old= GDKdebug; if ((b = BATdescriptor(*bid)) == NULL) throw(MAL, "bbp.reduce", "Cannot access descriptor"); /* reduce memory footprint by dropping hashes of non-persistent bats */ if( !VIEWparent(b) && b->batSharecnt==0){#ifdef TRACE_ADVICE if(b->hhash) printf("found hhash %s %d\n",BBP_logical(b->batCacheid), (int)(BATcount(b) * sizeof(hash_t))); if(b->thash) printf("found thash %s %d\n",BBP_logical(b->batCacheid), (int)(BATcount(b) * sizeof(hash_t)));#endif /* disable DeadBeef production */ GDKdebug &= ~33554432; HASHdestroy(b); } BBPkeepref(*ret=b->batCacheid); GDKdebug = old; return MAL_SUCCEED;}@+ BAT enhancementsThe code to enhance thekernel@cstrCMDBATclone(MalBlkPtr m, MalStkPtr s, InstrPtr p){ BAT *b; int bid = 0, cap, ht, tt; int *res; (void) m; bid = *(int *) getArgReference(s, p, 3); if ((b = BATdescriptor(bid)) == NULL) { throw(MAL, "bbp.new", "Cannot access descriptor"); } res = (int *) getArgReference(s, p, 0); ht = getArgType(m, p, 1); tt = getArgType(m, p, 2); cap = BATcount(b) + 64; BBPunfix(b->batCacheid); return (str) BKCnewBATint(res, &ht, &tt, &cap);}strCMDBATnew(MalBlkPtr m, MalStkPtr s, InstrPtr p){ int ht, tt; lng cap = 0; int *res; res = (int *) getArgReference(s, p, 0); ht = getArgType(m, p, 1); tt = getArgType(m, p, 2); if (p->argc > 3) cap = *(lng*) getArgReference(s, p, 3); if (ht == TYPE_any || tt == TYPE_any) throw(MAL, "bbp.new", "Explicit type required"); if (isaBatType(ht)) ht = TYPE_bat; if (isaBatType(tt)) tt = TYPE_bat; return (str) BKCnewBATlng(res, &ht, &tt, &cap);}strCMDBATnewDerived(MalBlkPtr m, MalStkPtr s, InstrPtr p){ int bid, ht, tt; int cap = 0; int *res; BAT *b; str msg; oid o; (void) m; res = (int *) getArgReference(s, p, 0); bid = *(int *) getArgReference(s, p, 1); if ((b = BATdescriptor(bid)) == NULL) { throw(MAL, "bbp.new", "Cannot access descriptor"); } if (bid > 0) { ht = b->htype; tt = b->ttype; } else { tt = b->htype; ht = b->ttype; } if (p->argc > 2) cap = *(int *) getArgReference(s, p, 2); else cap = BATcount(b); o = b->hseqbase; BBPunfix(b->batCacheid); res = (int *) getArgReference(s, p, 0); msg = (str) BKCnewBATint(res, &ht, &tt, &cap); if (msg == MAL_SUCCEED && ht == TYPE_void) { b = BATdescriptor(*res); BATseqbase(b, o); BBPunfix(b->batCacheid); } return msg;}strCMDBATderivedByName(int *ret, str *nme){ BAT *bn; int bid; bid = BBPindex(*nme); if (bid <= 0 || (bn = BATdescriptor(bid)) == 0) throw(MAL, "bbp.new", "Referenced BAT not found"); BBPincref(*ret = bn->batCacheid, TRUE); BBPunfix(bid); return MAL_SUCCEED;}strCMDBATnewint(MalBlkPtr m, MalStkPtr s, InstrPtr p){ int ht, tt; int cap = 0; int *res; res = (int *) getArgReference(s, p, 0); ht = getArgType(m, p, 1); tt = getArgType(m, p, 2); cap = *(int *) getArgReference(s, p, 3); res = (int *) getArgReference(s, p, 0); return (str) BKCnewBATint(res, &ht, &tt, &cap);}strCMDBBPproject(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci){ int *result, *bid, tt; ptr *p; BAT *b, *bn; result = (int *) getArgReference(stk, pci, 0); bid = (int *) getArgReference(stk, pci, 1); p = (ptr *) getArgReference(stk, pci, 2); tt = getArgType(mb, pci, 2); if ((b = BATdescriptor(*bid)) == NULL) { throw(MAL, "bbp.project", "Cannot access descriptor"); } if (tt >= TYPE_str) { if (p == 0 || *(str *) p == 0) p = (ptr *) str_nil; else p = *(ptr **) p; } bn = BATconst(b, tt, p); BBPunfix(b->batCacheid); if (bn) { *result = bn->batCacheid; BBPkeepref(bn->batCacheid); return MAL_SUCCEED; } throw(MAL, "bbp.project", "Cannot create the constant BAT");}strCMDBBPprojectNil(int *ret, int *bid){ BAT *b, *bn; if ((b = BATdescriptor(*bid)) == NULL) { throw(MAL, "bbp.project", "Cannot access descriptor"); } bn = BATconst(b, TYPE_void, (ptr) &int_nil); BBPunfix(b->batCacheid); if (bn) { *ret = bn->batCacheid; BBPkeepref(bn->batCacheid); return MAL_SUCCEED; } throw(MAL, "bbp.project", "Cannot create the constant BAT");}strCMDbatunpack(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci){ BAT *b; int bid; ptr p; ValPtr head, tail; bid = *(int *) getArgValue(stk, pci, 2); if ((b = BATdescriptor(bid)) == NULL) { throw(MAL, "bbp.unpack", "Cannot access descriptor"); } head = &stk->stk[pci->argv[0]]; tail = &stk->stk[pci->argv[1]]; p = BUNfirst(b); if (p) { VALinit(head, getArgType(mb, pci, 0), BUNhead(b, p)); VALinit(tail, getArgType(mb, pci, 1), BUNtail(b, p)); } BBPunfix(b->batCacheid); return MAL_SUCCEED;}strCMDbatpack(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci){ BAT *b; int *ret; int ht, tt; size_t cap = 0; ht = getArgType(mb, pci, 1); tt = getArgType(mb, pci, 2); ret = (int *) getArgReference(stk, pci, 0); if (ht == TYPE_any || tt == TYPE_any) throw(MAL, "bbp.new", "Explicit type required"); if (isaBatType(ht)) ht = TYPE_bat; if (isaBatType(tt)) tt = TYPE_bat; b = BATnew(ht, tt, cap); BUNins(b, (ptr) getArgValue(stk, pci, 1), getArgValue(stk, pci, 2), FALSE); if (!(b->batDirty&2)) b = BATsetaccess(b, BAT_READ); *ret = b->batCacheid; BBPkeepref(*ret); return MAL_SUCCEED;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -