⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opt_multiplex.mx

📁 一个内存数据库的源代码这是服务器端还有客户端
💻 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 opt_multiplex@a M. Kersten@- Multiplex CompilationThe MonetDB operator multiplex concept has been pivotal toeasily apply any scalar function to elements in a containers.Any operator @sc{cmd} came with its multiplex variant [@sc{cmd}].Given the signature @sc{cmd(T1,..,Tn) : Tr}, it could beapplied also as@sc{[CMD](bat[:any_1,:T1],...,bat[any_1,Tn]) :bat[any_1,Tr]}.The semantics of the multiplex is to perform thenatural join on all bat-valued parameters, and to execute the CMD for each combination of matching tuples. All results are collected in a result BAT. All but one argument may be replaced by a scalar value.The generic solution to the multiplex operators is to translatethem to a MAL loop. A snippet of its behaviour:@verbatim    b:= bat.new(:int,:int);    bat.insert(b,1,1);    c:bat[:int,:int]:= optimizer.multiplex("calc.+",b,1);@end verbatimThe current implementation requires the target type to be mentionedexplicitly. The result of the optimizer is:@verbatim    b := bat.new(:int,:int);    bat.insert(b,1,1);    _8 := bat.new(:int,:int);barrier (_11,_12,_13):= bat.newIterator(b);    _15 := calc.+(_13,1);    bat.insert(_8,_12,_15);    redo (_11,_12,_13):= bat.hasMoreElements(b);catch MALException;	#ignore any error    redo (_11,_12,_13):= bat.hasMoreElements(b);exit MALException;exit (_11,_12,_13);    c := _8;@end verbatim@-[WARNING] the semantics does not align precisely with M4.For, in search for efficientoperators we assume aligned BATs and the script version doesnot deal with duplicates in the head of the bats.[/WARNING]@{@malpattern optimizer.multiplex(CMD:str, a:any...):anyaddress OPTmultiplexcomment "Compiler for multiplexed instructions.";@h#ifndef _OPT_MULTIPLEX_H_#define _OPT_MULTIPLEX_H_#include "mal.h"#include "mal_builder.h"#include "opt_prelude.h"#include "opt_support.h"#endif /* _OPT_MULTIPLEX_H_ */@+ Code generationThe MAL block is replaced by a new one, with the multiplexcode in place.The subsequent call to the typechecker ensures we end up witha valid program.@c#include "mal_config.h"#include "opt_multiplex.h"#include "mal_interpreter.h"@-The generic solution to the multiplex operators is to translatethem to a MAL loop. The call optimizer.multiplex(CMD,A1,...An) introduces the following codestructure:@verbatim	resB:= bat.new(A1);barrier (mloop,h,t):= bat.newIterator(A1);	$1:= algebra.find(A1,h); 	$2:= A2;	# in case of constant?	...	cr:= mod.CMD($1,...,$n);	bat.insert(resB,h,cr);	redo (mloop,h,t):= bat.hasMoreElements(A1);end mloop;@end verbatimThe algorithm consists of two phases: phase one deals withcollecting the relevant information, phase two is the actualcode construction.@cstatic strOPTexpandMultiplex(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci){	int i = 2, k, mloop, resB, iter = 0, cr;	int hvar, tvar;	str mod, fcn;	str msg = MAL_SUCCEED;	int alias[MAXARG];	InstrPtr q;	int ht, tt;	(void) stk;	mod = VALget(&getVar(mb, getArg(pci, 1))->value);	mod = putName(mod,strlen(mod));	fcn = VALget(&getVar(mb, getArg(pci, 2))->value);	fcn = putName(fcn,strlen(fcn));	/* search the iterator bat */	iter = getArg(pci, 3);	for (i = 3; i < pci->argc; i++)		if (isaBatType(getArgType(mb, pci, i))) {			iter = getArg(pci, i);			break;		}#ifdef DEBUG_OPT_MULTIPLEX	printf("calling the optimize multiplex script routine\n");	printFunction(GDKout,mb,LIST_MAL_ALL);	printf("multiplex against operator %d %s\n",iter, getTypeName(getVarType(mb,iter)));	printInstruction(GDKout,mb,pci,LIST_MAL_ALL);#endif@-Beware, the operator constant (arg=1) is passed along as well,because in the end we issue a recursive function call that shouldfind the actual arguments at the proper place of the callee.@c	/* resB := new(refBat) */	q = newFcnCall(mb, batRef, newRef);	resB = getArg(q, 0);	if (isAnyExpression(getArgType(mb, pci, 0)))		msg = createException(MAL, "optimizer.multiplex", "Target type is missing");	ht = getHeadType(getArgType(mb, pci, 0));	tt = getTailType(getArgType(mb, pci, 0));	setVarType(mb, getArg(q, 0), newBatType(ht, tt));	q = pushNil(mb, q, ht);	freezeVarType(mb,getArg(q,q->argc-1));	q = pushNil(mb, q, tt);	freezeVarType(mb,getArg(q,q->argc-1));	/* barrier (mloop,h,r) := newIterator(refBat); */	q = newFcnCall(mb, batRef, "newIterator");	q->barrier = BARRIERsymbol;	getArg(q, 0) = mloop = newTmpVariable(mb, TYPE_lng);	hvar = newTmpVariable(mb, TYPE_any);	pushReturn(mb, q, hvar);	tvar = newTmpVariable(mb, TYPE_any);	pushReturn(mb, q, tvar);	pushArgument(mb, q, iter);	/* $1:= bat.find(Ai,h) or constant */	alias[i] = tvar;	for (i++; i < pci->argc; i++)		if (isaBatType(getArgType(mb, pci, i))) {			q = newFcnCall(mb, algebraRef, "find");			alias[i] = newTmpVariable(mb, getTailType(getArgType(mb, pci, i)));			getArg(q, 0) = alias[i];			pushArgument(mb, q, getArg(pci, i));			pushArgument(mb, q, hvar);		}	/* cr:= mod.CMD($1,...,$n); */	q = newFcnCall(mb, mod, fcn);	cr = getArg(q, 0) = newTmpVariable(mb, TYPE_any);	for (i = 3; i < pci->argc; i++)		if (isaBatType(getArgType(mb, pci, i))) {			pushArgument(mb, q, alias[i]);		} else {			q = pushArgument(mb, q, getArg(pci, i));		}	/* insert(resB,h,cr);  	   not append(resB, cr); the head type (oid) may dynamically change */		q = newFcnCall(mb, batRef, insertRef);	pushArgument(mb, q, resB);	pushArgument(mb, q, hvar);	pushArgument(mb, q, cr);/* redo (mloop,h,r):= hasMoreElements(refBat); */	q = newFcnCall(mb, batRef, "hasMoreElements");	q->barrier = REDOsymbol;	getArg(q, 0) = mloop;	pushReturn(mb, q, hvar);	pushReturn(mb, q, tvar);	pushArgument(mb, q, iter);/* catch   MALException and ignore them  and replace value with nil*/	q = newInstruction(mb,CATCHsymbol);	k = newVariable(mb, GDKstrdup(exceptionToString(MAL)), TYPE_str);	getVar(mb,k)->isudftype = 1;	pushReturn(mb, q, k);	pushInstruction(mb, q);/* redo (mloop,h,r):= hasMoreElements(refBat); *//* ignore the error and continue */	q = newFcnCall(mb, batRef, "hasMoreElements");	q->barrier = REDOsymbol;	getArg(q, 0) = mloop;	pushReturn(mb, q, hvar);	pushReturn(mb, q, tvar);	pushArgument(mb, q, iter);/* finalized the catch block */	q= newInstruction(mb,EXITsymbol);	pushReturn(mb,q,k);	pushInstruction(mb,q);	q = newAssignment(mb);	q->barrier = EXITsymbol;	getArg(q, 0) = mloop;	pushReturn(mb, q, hvar);	pushReturn(mb, q, tvar);	q = newAssignment(mb);	getArg(q, 0) = getArg(pci, 0);	pushArgument(mb, q, resB);	return msg;}@-This optimizer is directly called for the current routine.It is more a code generator then an optimizer per se.@hopt_export str OPTmultiplex(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);@cstrOPTmultiplex(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci){	InstrPtr *old, p;	int i,j, limit,doit= 0, init=0;	lng clk=GDKusec();	(void) stk;	(void) pci;	old = mb->stmt;	limit = mb->stop;	for (i = 0; i < limit; i++) {		p = old[i];		if (getModuleId(p) == optimizerRef && getFunctionId(p) == multiplexRef) {			if(init==0){				newMalBlkStmt(mb, mb->stop);				for(j= 0; j<i; j++)					pushInstruction(mb,old[j]);				init++;			}			OPTexpandMultiplex(mb, stk, p);			/* freeInstruction(p);*/			doit++;		} else		if( init )			pushInstruction(mb, p);	}	if( init){		GDKfree(old);		optimizerCheck(mb, "optimizer.multiplex", doit, GDKusec() - clk,OPT_CHECK_ALL);	}	return MAL_SUCCEED;}@}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -