📄 batifthen.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 batifthen@a M.L. Kersten@+ BAT if-then-else multiplex expressions.The assembled code for IF-THEN-ELSE multiplex operations.Again we assume that the BAT arguments are aligned.@{@-@= ifthenGrpcommand batcalc.ifthen(b:bat[:oid,:bit], t:bat[:oid,:@1]) :bat[:oid,:@1] address CMDifThen_@1comment "If-then operation to assemble a conditional result ";command batcalc.ifthen(b:bat[:oid,:bit], v:@1) :bat[:oid,:@1] address CMDifThenCst_@1comment "Ifthen operation to assemble a conditional result ";command batcalc.ifthenelse(b:bat[:oid,:bit], v:@1,w:@1) :bat[:oid,:@1] address CMDifThenElseCst_@1comment "Ifthen operation to assemble a conditional result ";command batcalc.ifthenelse(b:bat[:oid,:bit], t:bat[:oid,:@1], e:bat[:oid,:@1]) :bat[:oid,:@1] address CMDifThenElse_@1comment "If-then-else operation to assemble a conditional result ";command batcalc.ifthenelse(b:bat[:oid,:bit], e:@1, t:bat[:oid,:@1]) :bat[:oid,:@1] address CMDifThenElseCst1_@1comment "If-then-else operation to assemble a conditional result ";command batcalc.ifthenelse(b:bat[:oid,:bit], t:bat[:any_1,:@1], e:@1) :bat[:oid,:@1] address CMDifThenElseCst2_@1comment "If-then-else operation to assemble a conditional result ";@mal @:ifthenGrp(bit)@ @:ifthenGrp(chr)@ @:ifthenGrp(str)@ @:ifthenGrp(oid)@ @:ifthenGrp(int)@ @:ifthenGrp(sht)@ @:ifthenGrp(lng)@ @:ifthenGrp(flt)@ @:ifthenGrp(dbl)@@- Implementation@include kprelude.mx@h#ifndef _BATIFTHEN_#define _BATIFTHEN_#include "gdk.h"#include "math.h"#include "mal_exception.h"#ifdef WIN32#ifndef LIBBATIFTHEN#define batifthen_export extern __declspec(dllimport)#else#define batifthen_export extern __declspec(dllexport)#endif#else#define batifthen_export extern#endif#endif /* _BATIFTHEN_ */@-A general assumption in all cases is the bats are synchronized on theirhead column. This is not checked and may be mis-used to deploy theimplementation for shifted window arithmetic as well.@= chkSize if( BATcount(@1) != BATcount(@2) ) throw(MAL, "batcalc.@3", "requires bats of identical size");@= wrapup if (!(bn->batDirty&2)) bn = BATsetaccess(bn, BAT_READ); *ret= bn->batCacheid; BBPkeepref(*ret); BBPreleaseref(b->batCacheid); return MAL_SUCCEED;@- IfThenElseThe conditional multiplex operations .@-The constant versions are typed by the parserString arguments call for an extra type casting. In combinationwith type resolution and runtime checks it provides a densedefinitoin.@= ifthencstImplbatifthen_export str CMDifThen_@1(int *ret, int *bid, int *tid);strCMDifThen_@1(int *ret, int *bid, int *tid) { BAT *b, *tb, *bn; @1 nilval= (@1) @1_nil, *val; BUN p,q; size_t xx; @:getBATdescriptor(bid,b,"batcalc.ifThen")@ @:getBATdescriptor(tid,tb,"batcalc.ifThen",BBPreleaseref(b->batCacheid))@ @:chkSize(b,tb,CMDifThen)@ if( BAThvoid(b)) bn= BATnew(TYPE_oid,TYPE_@1,BATcount(b)); else{ bn= BATnew(b->htype,TYPE_@1,BATcount(b)); } if( bn == 0 ) throw(MAL, "batcalc.ifThen","Can not create BAT"); bn->hsorted= b->hsorted; bn->tsorted= b->tsorted; BATloopFast(b, p, q, xx) { bit *t= (bit*) BUNtail(b,p); if( *(bit *) t == bit_nil) BUNfastins(bn, BUNhead(b,p), (ptr) & nilval); else if( *(bit *) t ) { val = (@1*) BUNtail(tb,BUNptr(tb,BUNindex(b,p))); BUNfastins(bn, BUNhead(b,p), val); } } BBPreleaseref(tb->batCacheid); @:wrapup@}batifthen_export str CMDifThenCst_@1(int *ret, int *bid, @1 *tid);str CMDifThenCst_@1(int *ret, int *bid, @1 *tid){ BAT *b, *bn; @1 nilval= (@1) @1_nil; BUN p,q; size_t xx; @:getBATdescriptor(bid,b,"batcalc.ifThen")@ @:resultBAT(@1,"batcalc.ifThen")@ if( BAThvoid(b)) bn= BATnew(TYPE_oid,TYPE_@1,BATcount(b)); else bn= BATnew(b->htype,TYPE_@1,BATcount(b)); if( bn == 0 ) throw(MAL, "batcalc.ifThen","Can not create BAT"); bn->hsorted= b->hsorted; bn->tsorted= b->tsorted; BATloopFast(b, p, q, xx) { ptr t = BUNtail(b,p); if( *(bit*) t== bit_nil) BUNfastins(bn,BUNhead(b,p), (ptr) & nilval); else if( *(bit*) t ) BUNfastins(bn,BUNhead(b,p),(ptr) tid); } @:wrapup@}batifthen_export str CMDifThenElseCst_@1(int *ret, int *bid, @1 *tid, @1 *eid);str CMDifThenElseCst_@1(int *ret, int *bid, @1 *tid, @1 *eid){ BAT *b, *bn; @1 nilval= (@1) @1_nil; @:getBATdescriptor(bid,b,"batcalc.ifThenElse")@ @:resultBAT(@1,"batcalc.ifThenElse")@ if( b->htype == TYPE_void && !ATOMvarsized(b->ttype)){ BUN p,q; @1 *o; size_t xx= BUNsize(b); o= (@1*) BUNtail(bn,BUNfirst(bn)); p= BUNtail(b,BUNfirst(b)); q= BUNtail(b,BUNlast(b)); while(p<q){ if( *(bit*) p== bit_nil) *o++ = (@1) @1_nil; else if( *(bit*) p ) *o++ = *tid; else *o++ = *eid; p += xx; } (bn)->batBuns->free += BATcount(b)*sizeof(@1); BATsetcount(bn, BATcount(b)); } else { BUN p,q; size_t xx; BATloopFast(b, p, q, xx) { bit t = *(bit*)BUNtail(b,p); if( t== bit_nil) BUNfastins(bn, BUNhead(b,p), (ptr) & nilval); else if( t ) BUNfastins(bn, BUNhead(b,p), (ptr) tid); else BUNfastins(bn, BUNhead(b,p), (ptr) eid); } } @:wrapup@}batifthen_export str CMDifThenElse_@1(int *ret, int *bid, int *tid, int *eid);strCMDifThenElse_@1(int *ret, int *bid, int *tid, int *eid){ BAT *b, *tb, *eb, *bn; @1 nilval= (@1) @1_nil; @:getBATdescriptor(bid,b,"batcalc.ifThenElse")@ @:getBATdescriptor(tid,tb,"batcalc.ifThenElse",BBPreleaseref(b->batCacheid);)@ @:getBATdescriptor(eid,eb,"batcalc.ifThenElse", BBPreleaseref(b->batCacheid); BBPreleaseref(tb->batCacheid);)@ @:chkSize(b,tb,ifThenElse)@ @:chkSize(b,eb,ifThenElse)@ @:resultBAT(@1,"batcalc.ifThenElse")@ if( b->htype == TYPE_void && !ATOMvarsized(b->ttype)){ BUN p,q; @1 *o, *t,*e; size_t px = BUNsize(b); size_t tx = BUNsize(tb); size_t ex = BUNsize(eb); o= (@1*) BUNtail(bn,BUNfirst(bn)); p= BUNtail(b,BUNfirst(b)); q= BUNtail(b,BUNlast(b)); t= (@1*) BUNtail(tb,BUNfirst(tb)); e= (@1*) BUNtail(eb,BUNfirst(eb)); while(p<q){ if( *(bit*) p== bit_nil) *o++ = (@1) @1_nil; else if( *(bit*) p ) *o++ = *t; else *o++ = *e; p+= px; t+=tx; e+=ex; } (bn)->batBuns->free += BATcount(b)*sizeof(@1); BATsetcount(bn, BATcount(b)); } else { BUN p,q; size_t xx; BATloopFast(b, p, q, xx) { bit t = *(bit*) BUNtail(b,p); int idx = BUNindex(b, p); if( t== bit_nil) BUNfastins(bn, BUNhead(b,p), (ptr) &nilval); else if( t ) BUNfastins(bn, BUNhead(b,p), BUNtail(tb, BUNptr(tb, idx))); else BUNfastins(bn, BUNhead(b,p), BUNtail(eb, BUNptr(eb, idx))); } } BBPreleaseref(tb->batCacheid); BBPreleaseref(eb->batCacheid); @:wrapup@}batifthen_export str CMDifThenElseCst1_@1(int *ret, int *bid, @1 *val, int *eid);strCMDifThenElseCst1_@1(int *ret, int *bid, @1 *val, int *eid){ BAT *b, *eb, *bn; @1 nilval= (@1) @1_nil; @:getBATdescriptor(bid,b,"batcalc.ifThenElse")@ @:getBATdescriptor(eid,eb,"batcalc.ifThenElse", BBPreleaseref(b->batCacheid);)@ @:chkSize(b,eb,ifThenElse)@ @:resultBAT(@1,"batcalc.ifThenElse")@ if( b->htype == TYPE_void && !ATOMvarsized(b->ttype)){ BUN p,q; @1 *o,*e; size_t px= BUNsize(b); size_t ex= BUNsize(eb); o= (@1*) BUNtail(bn,BUNfirst(bn)); p= BUNtail(b,BUNfirst(b)); q= BUNtail(b,BUNlast(b)); e= (@1*) BUNtail(eb,BUNfirst(eb)); while(p<q){ if( *(bit*) p== bit_nil) *o++ = (@1) @1_nil; else if( *(bit*) p ) *o++ = *val; else *o++ = *e; p+=px; e+=ex; } (bn)->batBuns->free += BATcount(b)*sizeof(@1); BATsetcount(bn, BATcount(b)); } else { BUN p,q; size_t xx; BATloopFast(b, p, q, xx) { bit t = *(bit*) BUNtail(b,p); int idx = BUNindex(b, p); if( t== bit_nil) BUNfastins(bn, BUNhead(b,p), (ptr) &nilval); else if( t ) BUNfastins(bn, BUNhead(b,p), (ptr) val); else BUNfastins(bn, BUNhead(b,p), BUNtail(eb, BUNptr(eb, idx))); } } BBPreleaseref(eb->batCacheid); @:wrapup@}batifthen_export str CMDifThenElseCst2_@1(int *ret, int *bid, int *tid, @1 *val);strCMDifThenElseCst2_@1(int *ret, int *bid, int *tid, @1 *val){ BAT *b, *tb, *bn; @1 nilval= (@1) @1_nil; @:getBATdescriptor(bid,b,"batcalc.ifThenElse")@ @:getBATdescriptor(tid,tb,"batcalc.ifThenElse",BBPreleaseref(b->batCacheid);)@ @:chkSize(b,tb,ifThenElse)@ @:resultBAT(@1,"batcalc.ifThenElse")@ if( b->htype == TYPE_void && !ATOMvarsized(b->ttype)){ BUN p,q; @1 *o,*t; size_t px= BUNsize(b); size_t tx= BUNsize(tb); o= (@1*) BUNtail(bn,BUNfirst(bn)); p= BUNtail(b,BUNfirst(b)); q= BUNtail(b,BUNlast(b)); t= (@1*) BUNtail(tb,BUNfirst(tb)); while(p<q){ if( *(bit*)p== bit_nil) *o++ = (@1) @1_nil; else if( *(bit*)p ) *o++ = *t; else *o++ = *val; p+=px; t+=tx; } (bn)->batBuns->free += BATcount(b)*sizeof(@1); BATsetcount(bn, BATcount(b)); } else { BUN p,q; size_t xx; BATloopFast(b, p, q, xx) { bit t = *(bit*) BUNtail(b,p); int idx = BUNindex(b, p); if( t== bit_nil) BUNfastins(bn, BUNhead(b,p), (ptr) &nilval); else if( t ) BUNfastins(bn, BUNhead(b,p), BUNtail(tb, BUNptr(tb, idx))); else BUNfastins(bn, BUNhead(b,p), val); } } BBPreleaseref(tb->batCacheid); @:wrapup@}@c#include "mal_config.h"#include "batifthen.h"@:ifthencstImpl(int)@@:ifthencstImpl(sht)@@:ifthencstImpl(lng)@@:ifthencstImpl(oid)@@:ifthencstImpl(flt)@@:ifthencstImpl(dbl)@@:ifthencstImpl(str)@@:ifthencstImpl(chr)@@:ifthencstImpl(bit)@@}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -