Files
secondo/Algebras/CompiledExpressions/CompiledExpressionsAlgebra.cpp
2026-01-23 17:03:45 +08:00

1282 lines
34 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2004-2009, University in Hagen, Faculty of Mathematics
and Computer Science, Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
//paragraph [10] title: [{\Large \bf ] [}]
//paragraph [21] table1column: [\begin{quote}\begin{tabular}{l}] [\end{tabular}\end{quote}]
//paragraph [22] table2columns: [\begin{quote}\begin{tabular}{ll}] [\end{tabular}\end{quote}]
//paragraph [23] table3columns: [\begin{quote}\begin{tabular}{lll}] [\end{tabular}\end{quote}]
//paragraph [24] table4columns: [\begin{quote}\begin{tabular}{llll}] [\end{tabular}\end{quote}]
//[TOC] [\tableofcontents]
//[--------] [\hline]
//characters [1] verbatim: [$] [$]
//characters [2] formula: [$] [$]
//characters [3] capital: [\textsc{] [}]
//characters [4] teletype: [\texttt{] [}]
//[ae] [\"a]
//[oe] [\"o]
//[ue] [\"u]
//[ss] [{\ss}]
//[<=] [\leq]
//[#] [\neq]
//[tilde] [\verb|~|]
//[<] [$<$]
//[>] [$>$]
[10] Implementation file of the CompiledExpression Algebra
2016/2017 H.Brieschke created the new CompiledExpression Algebra
[TOC]
1 Overview
The ~Compiled Expression Algebra~ basically implements three operators,
Namely ~filter~, ~extend~, and ~executeQuery~. However, these
can not be used directly in a query, but are exchanged by the algebra
against the original operators during the query processing.
The ~filter~-operator corresponds to the ~filter~-operator from
the ~relation algebra~, the ~extend~-operator is the ~extend~-operator
from the ~ExtRelation algebra~, and the ~excecuteQuery-~operator is used
if the complete query could be compiled by this algebra.
2 Defines, includes, and constants
*/
#include <set>
#include "Operator.h"
#include "NestedList.h"
#include "ListUtils.h"
#include "Symbols.h"
#include "Trace.h"
#include "StandardTypes.h"
#include "QueryProcessor.h"
#include "Progress.h"
#include "Algebras/Relation-C++/RelationAlgebra.h"
#include "./CompiledExpressionsAlgebra.h"
#include "./CECompiler.h"
#include "./CECodeGenerator.h"
extern NestedList* nl;
extern QueryProcessor* qp;
extern AlgebraManager* am;
using namespace CompiledExpressions;
namespace CompiledExpressions {
/*
3 Class ~CEARuntimeError~
This class implements ~ERROR~-objects, which are required for the error treatment.
*/
CEARuntimeError::CEARuntimeError(std::string s) {
errMsg = s;
}
const char*
CEARuntimeError::what() const throw() {
return errMsg.c_str();
}
/*
4 The Operators of the ~Compiled Expressions Algebra~.
4.1 Operator ~filter~
This operator corrosponded to the ~filter-~operator in the ~Realation-Algebra~.
Only tuples, fulfilling a certain condition are passed on to the
output stream.
4.1.1 Type mapping function of operator ~filter~
Result type of filter operation.
---- ((stream (tuple x)) (map (tuple x) bool))
-> (stream (tuple x))
----
Type mapping function modified to show the possibility of getting
not only types but also arguments in the type mapping. This happens
when an operator
registers "UsesArgsinTypeMapping". Type list now has the form
---- ( (type1 arg1) (type2 arg2) )
----
that is
---- (
( (stream (tuple x)) arg1 )
( (map (tuple x) bool) arg2 )
)
----
*/
ListExpr
ceaFilterTypeMap( ListExpr args ) {
if(!nl->HasLength(args,2)) {
return listutils::typeError("two arguments expected");
}
if(!nl->HasLength(nl->First(args),2)) {
ErrorReporter::ReportError("the first argument "
" should be a (type, expression) pair");
return nl->TypeError();
}
if(!listutils::isTupleStream(nl->First(nl->First(args)))){
ErrorReporter::ReportError("first argument must be a stream of tuples");
return nl->TypeError();
}
if(!nl->HasLength(nl->Second(args),2)){
ErrorReporter::ReportError("the second argument "
" should be a (type, expression) pair");
return nl->TypeError();
}
ListExpr map = nl->First(nl->Second(args));
if(!listutils::isMap<1>(map)){ // checking for a single arg
ErrorReporter::ReportError("map: tuple -> bool expected as the"
" second argument");
return nl->TypeError();
}
ListExpr mapres = nl->Third(map);
if(!CcBool::checkType(mapres)){
ErrorReporter::ReportError("map is not a predicate");
return nl->TypeError();
}
if(!nl->Equal(nl->Second(nl->First(nl->First(args))), nl->Second(map))){
ErrorReporter::ReportError("map and tuple type are not consistent");
return nl->TypeError();
}
return nl->First(nl->First(args));
}
/*
4.1.2 Value mapping function of operator ~filter~
*/
#ifndef USE_PROGRESS
// standard version
int
ceaFilterValueMap( Word* args,
Word& result,
int message,
Word& local,
Supplier s ) {
switch ( message ) {
case OPEN:
qp->Open (args[0].addr);
return 0;
case REQUEST:
{
bool found = false;
Word elem;
Tuple* tuple = 0;
filterOp_t filterOp = (filterOp_t) args[1].addr;
qp->Request(args[0].addr, elem);
while (qp->Received(args[0].addr) && !found) {
tuple = (Tuple*)elem.addr;
found = filterOp(tuple);
if (!found) {
tuple->DeleteIfAllowed();
qp->Request(args[0].addr, elem);
}
}
if (found) {
result.setAddr(tuple);
return YIELD;
}
else
return CANCEL;
}
case CLOSE:
qp->Close(args[0].addr);
return 0;
}
return 0;
}
#else
//progress version
int
ceaFilterValueMap(Word* args,
Word& result,
int message,
Word& local,
Supplier s) {
CEAFilterLocalInfo* ptrCEAFLI;
switch ( message ) {
case OPEN: {
ptrCEAFLI = (CEAFilterLocalInfo*) local.addr;
if(ptrCEAFLI)
delete ptrCEAFLI;
ptrCEAFLI = new CEAFilterLocalInfo();
local.setAddr(ptrCEAFLI);
qp->Open(args[0].addr);
return 0;
}
case REQUEST: {
ptrCEAFLI = (CEAFilterLocalInfo*) local.addr;
bool found = false;
Word elem;
Tuple* tuple = 0;
filterOp_t filterOp = (filterOp_t) args[1].addr;
qp->Request(args[0].addr, elem);
while (qp->Received(args[0].addr) && !found) {
tuple = (Tuple*)elem.addr;
found = filterOp(tuple);
if (!found) {
tuple->DeleteIfAllowed();
qp->Request(args[0].addr, elem);
}
}
if (found) {
result.setAddr(tuple);
ptrCEAFLI->addReturned();
return YIELD;
} else {
ptrCEAFLI->setDone();
return CANCEL;
}
}
case CLOSE: {
qp->Close(args[0].addr);
return 0;
}
case CLOSEPROGRESS: {
ptrCEAFLI = (CEAFilterLocalInfo*) local.addr;
if (ptrCEAFLI) {
delete ptrCEAFLI;
local.setAddr(0);
}
return 0;
}
case REQUESTPROGRESS: {
ProgressInfo p1;
ProgressInfo* pRes;
const double uFilter = 0.01;
pRes = (ProgressInfo*) result.addr;
ptrCEAFLI = (CEAFilterLocalInfo*) local.addr;
if ( qp->RequestProgress(args[0].addr, &p1) ) {
pRes->CopySizes(p1);
if ( ptrCEAFLI ) {
//filter was started
if ( ptrCEAFLI->getDone() ) {
//arg stream exhausted, all known
pRes->Card = (double) ptrCEAFLI->getReturned();
pRes->Time = p1.Time + (double) ptrCEAFLI->getCurrent()
* qp->GetPredCost(s) * uFilter;
pRes->Progress = 1.0;
pRes->CopyBlocking(p1);
return YIELD;
}
if ( ptrCEAFLI->getReturned() >= enoughSuccessesSelection ) {
//stable state assumed now
pRes->Card = p1.Card *
( (double) ptrCEAFLI->getReturned()
/ (double) (ptrCEAFLI->getCurrent()));
pRes->Time = p1.Time + p1.Card * qp->GetPredCost(s) * uFilter;
if ( p1.BTime < 0.1 && pipelinedProgress )
//non-blocking,
//use pipelining
pRes->Progress = p1.Progress;
else
pRes->Progress = (p1.Progress * p1.Time
+ ptrCEAFLI->getCurrent()
* qp->GetPredCost(s)
* uFilter)
/ pRes->Time;
pRes->CopyBlocking(p1);
return YIELD;
}
}
//filter not yet started or not enough seen
pRes->Card = p1.Card * qp->GetSelectivity(s);
pRes->Time = p1.Time + p1.Card * qp->GetPredCost(s) * uFilter;
if ( p1.BTime < 0.1 && pipelinedProgress )
//non-blocking,
//use pipelining
pRes->Progress = p1.Progress;
else
pRes->Progress = (p1.Progress * p1.Time) / pRes->Time;
pRes->CopyBlocking(p1);
return YIELD;
} else
return CANCEL;
}
}
return 0;
}
/*
4.1.3 Class ~CEAFilterLocalInfo~
In the ~Progress~-Version used this class objects as data structure for the
progress informations.
The Constructor.
*/
CEAFilterLocalInfo::CEAFilterLocalInfo()
: current(0),
returned(0),
done(false) {}
/*
The Destructor.
*/
CEAFilterLocalInfo::~CEAFilterLocalInfo() {}
/*
The following methods are the ~get~er- and ~set~er-methods for these
private variables.
*/
void
CEAFilterLocalInfo::addCurrent() {
current++;
}
void
CEAFilterLocalInfo::addReturned() {
returned++;
}
void
CEAFilterLocalInfo::setDone() {
done = true;
}
int
CEAFilterLocalInfo::getCurrent() {
return current;
}
int
CEAFilterLocalInfo::getReturned() {
return returned;
}
bool
CEAFilterLocalInfo::getDone() {
return done;
}
#endif
/*
4.1.4 Specification of operator ~filter~
*/
const std::string ceaFilterSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" ) "
"( <text>((stream x) (map x bool)) -> "
"(stream x)</text--->"
"<text>_ filter [ fun ]</text--->"
"<text>Only tuples, fulfilling a certain "
"condition are passed on to the output "
"stream.</text--->"
"<text>query cities feed filter "
"[.population > 500000] consume</text--->"
") )";
/*
4.1.5 Definition of operator ~filter~
*/
Operator ceaOperatorFilter (
"filter", // name
ceaFilterSpec, // specification
ceaFilterValueMap, // value mapping
Operator::SimpleSelect, // trivial selection function
ceaFilterTypeMap // type mapping
);
/*
4.2 Operator ~extend~
This operator corrosponded to the ~extend-~operator in the ~ExtRealation-Algebra~.
Extends each input tuple by new attributes as specified in the parameter list.
4.2.1 Type mapping function of operator ~extend~
Type mapping for ~extend~ is
---- ((stream X) ((b1 (map x y1)) ... (bm (map x ym))))
-> (stream (tuple ((a1 x1) ... (an xn) (b1 y1) ... (bm ym)))))
where X = (tuple ((a1 x1) ... (an xn)))
----
*/
ListExpr
ceaExtendTypeMap( ListExpr args ) {
ListExpr errorInfo = nl->OneElemList(nl->SymbolAtom("ERROR"));
if(nl->ListLength(args)!=2){
ErrorReporter::ReportError("two elements expected");
return nl->TypeError();
}
ListExpr stream = nl->First(args);
if(!IsStreamDescription(stream)){
ErrorReporter::ReportError("first argument is not a tuple stream");
return nl->TypeError();
}
ListExpr tuple = nl->Second(stream);
ListExpr functions = nl->Second(args);
if(nl->ListLength(functions)<1){
ErrorReporter::ReportError("at least one function expected");
return nl->TypeError();
}
// copy attrlist to newattrlist
ListExpr attrList = nl->Second(nl->Second(stream));
ListExpr newAttrList = nl->OneElemList(nl->First(attrList));
ListExpr lastlistn = newAttrList;
attrList = nl->Rest(attrList);
while (!(nl->IsEmpty(attrList)))
{
lastlistn = nl->Append(lastlistn,nl->First(attrList));
attrList = nl->Rest(attrList);
}
// reset attrList
attrList = nl->Second(nl->Second(stream));
ListExpr typeList;
// check functions
std::set<std::string> usedNames;
while (!(nl->IsEmpty(functions)))
{
ListExpr function = nl->First(functions);
functions = nl->Rest(functions);
if(nl->ListLength(function)!=2){
ErrorReporter::ReportError("invalid extension found");
return nl->TypeError();
}
ListExpr name = nl->First(function);
ListExpr map = nl->Second(function);
std::string errormsg;
if(!listutils::isValidAttributeName(name, errormsg)){
return listutils::typeError(errormsg);
}
std::string namestr = nl->SymbolValue(name);
int pos = FindAttribute(attrList,namestr,typeList);
if(pos!=0){
ErrorReporter::ReportError("Attribute "+ namestr +
" already member of the tuple");
return nl->TypeError();
}
if(nl->ListLength(map)!=3){
ErrorReporter::ReportError("invalid function");
return nl->TypeError();
}
if(!nl->IsEqual(nl->First(map),Symbol::MAP())){
ErrorReporter::ReportError("invalid function");
return nl->TypeError();
}
ListExpr funResType = nl->Third(map);
if(!am->CheckKind(Kind::DATA(),funResType, errorInfo)){
ErrorReporter::ReportError("requested attribute " + namestr +
"not in kind DATA");
return nl->TypeError();
}
ListExpr funArgType = nl->Second(map);
if(!nl->Equal(funArgType, tuple)){
ErrorReporter::ReportError
("function type different to the tuple type");
return nl->TypeError();
}
if(usedNames.find(namestr)!=usedNames.end()){
ErrorReporter::ReportError("Name "+ namestr + "occurs twice");
return nl->TypeError();
}
usedNames.insert(namestr);
// append attribute
lastlistn = nl->Append(lastlistn, (nl->TwoElemList(name, funResType )));
}
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
nl->TwoElemList(nl->SymbolAtom(Tuple::BasicType()),
newAttrList));
}
/*
4.2.2 Value mapping function of operator ~extend~
*/
#ifndef USE_PROGRESS
// standard version
int
ceaExtendValueMap(Word* args,
Word& result,
int message,
Word& local,
Supplier s ) {
TupleType* resultTupleType;
switch (message)
{
case OPEN:
{
ListExpr resultType;
qp->Open(args[0].addr);
resultType = GetTupleResultType( s );
resultTupleType = new TupleType( nl->Second( resultType ) );
local.setAddr( resultTupleType );
return 0;
}
case REQUEST:
{
Supplier supplier1, supplier2, supplier3;
Tuple* tuple;
Word elem, value, tmpArgs;
ArgVectorPointer funargs;
int nooffun;
resultTupleType = (TupleType*)local.addr;
qp->Request(args[0].addr, elem);
if (qp->Received(args[0].addr)) {
tuple = (Tuple*)elem.addr;
Tuple* newTuple = new Tuple( resultTupleType );
for( int i = 0; i < tuple->GetNoAttributes(); i++ ) {
//cout << (void*) tuple << endl;
newTuple->CopyAttribute( i, tuple, i );
}
supplier1 = args[1].addr;
nooffun = qp->GetNoSons(supplier1);
for (int i=0; i < nooffun; i++) {
supplier2 = qp->GetSupplier(supplier1, i);
supplier3 = qp->GetSupplier(supplier2, 1);
if ((qp->getPtrCEQueryProcessor())->IsPointerNode( supplier3 )) {
//cout << "son [" << i << "] is a pointer." << endl;
qp->Request(supplier3, tmpArgs);
extendOp_t extendOp = (extendOp_t) tmpArgs.addr;
newTuple->PutAttribute( tuple->GetNoAttributes()+i,
(extendOp(tuple))->Clone());
} else {
//cout << "son [" << i << "] is a map function." << endl;
funargs = qp->Argument(supplier3);
((*funargs)[0]).setAddr(tuple);
qp->Request(supplier3,value);
newTuple->PutAttribute( tuple->GetNoAttributes()+i,
((Attribute*)value.addr)->Clone() );
}
}
tuple->DeleteIfAllowed();
result.setAddr(newTuple);
return YIELD;
} else
return CANCEL;
}
case CLOSE:
if(local.addr) {
((TupleType*)local.addr)->DeleteIfAllowed();
local.setAddr(0);
}
qp->Close(args[0].addr);
return 0;
}
return 0;
}
# else
// progress version
int
ceaExtendValueMap(Word* args,
Word& result,
int message,
Word& local,
Supplier s) {
Word t, value, tmpArgs;
Tuple* tuple;
Supplier supplier1, supplier2, supplier3;
int nooffun;
ArgVectorPointer funargs;
CEAExtendLocalInfo* ptrCEAELI;
switch (message)
{
case OPEN : {
ptrCEAELI = (CEAExtendLocalInfo*) local.addr;
if ( ptrCEAELI ) {
delete ptrCEAELI;
}
ptrCEAELI = new CEAExtendLocalInfo
(new TupleType(nl->Second(GetTupleResultType(s))),
50,
false,
qp->GetNoSons(args[1].addr));
local.setAddr(ptrCEAELI);
qp->Open(args[0].addr);
return 0;
}
case REQUEST : {
ptrCEAELI = (CEAExtendLocalInfo*) local.addr;
if(!ptrCEAELI){
return CANCEL;
}
qp->Request(args[0].addr,t);
if (qp->Received(args[0].addr))
{
tuple = (Tuple*)t.addr;
Tuple* newTuple = new Tuple( ptrCEAELI->getResultTupleType() );
ptrCEAELI->read++;
for( int i = 0; i < tuple->GetNoAttributes(); i++ ) {
//cout << (void*) tuple << endl;
newTuple->CopyAttribute( i, tuple, i );
}
supplier1 = args[1].addr;
nooffun = qp->GetNoSons(supplier1);
for (int i=0; i < nooffun;i++)
{
supplier2 = qp->GetSupplier(supplier1, i);
supplier3 = qp->GetSupplier(supplier2, 1);
if ((qp->getPtrCEQueryProcessor())->IsPointerNode( supplier3 )) {
//cout << "son [" << i << "] is a pointer." << endl;
qp->Request(supplier3, tmpArgs);
extendOp_t extendOp = (extendOp_t) tmpArgs.addr;
newTuple->PutAttribute( tuple->GetNoAttributes()+i,
(extendOp(tuple))->Clone());
} else {
//cout << "son [" << i << "] is a map function." << endl;
funargs = qp->Argument(supplier3);
((*funargs)[0]).setAddr(tuple);
qp->Request(supplier3,value);
newTuple->PutAttribute( tuple->GetNoAttributes()+i,
((Attribute*)value.addr)->Clone() );
}
if (ptrCEAELI->read <= ptrCEAELI->getStableValue())
{
ptrCEAELI->addAttrSizeTmp
(newTuple->GetSize(tuple->GetNoAttributes()+i),
i);
ptrCEAELI->addAttrSizeExtTmp
(newTuple->GetExtSize(tuple->GetNoAttributes()+i),
i);
}
}
tuple->DeleteIfAllowed();
result.setAddr(newTuple);
return YIELD;
}
else
return CANCEL;
}
case CLOSE : {
qp->Close(args[0].addr);
return 0;
}
case CLOSEPROGRESS : {
ptrCEAELI = (CEAExtendLocalInfo*) local.addr;
if ( ptrCEAELI ){
delete ptrCEAELI;
local.setAddr(0);
}
return 0;
}
case REQUESTPROGRESS : {
ptrCEAELI = (CEAExtendLocalInfo*) local.addr;
ProgressInfo p1;
ProgressInfo *pRes;
const double uExtend = 0.0034; //millisecs per tuple
const double vExtend = 0.0067; //millisecs per tuple and attribute
// see determination of constants in file ConstantsExtendStream
pRes = (ProgressInfo*) result.addr;
if ( !ptrCEAELI ) {
return CANCEL;
}
if ( qp->RequestProgress(args[0].addr, &p1) )
{
ptrCEAELI->sizesChanged = false;
if ( !ptrCEAELI->sizesInitialized )
{
ptrCEAELI->setNoOldAttrs(p1.noAttrs);
ptrCEAELI->noAttrs = ptrCEAELI->getNoOldAttrs()
+ ptrCEAELI->getNoNewAttrs();
ptrCEAELI->attrSize = new double[ptrCEAELI->noAttrs];
ptrCEAELI->attrSizeExt = new double[ptrCEAELI->noAttrs];
}
if ( !ptrCEAELI->sizesInitialized
|| p1.sizesChanged
|| ( ptrCEAELI->read >= ptrCEAELI->getStableValue()
&& !ptrCEAELI->getSizesFinal() ) ) {
ptrCEAELI->Size = 0.0;
ptrCEAELI->SizeExt = 0.0;
//old attrs
for (int i = 0; i < ptrCEAELI->getNoOldAttrs(); i++)
{
ptrCEAELI->attrSize[i] = p1.attrSize[i];
ptrCEAELI->attrSizeExt[i] = p1.attrSizeExt[i];
ptrCEAELI->Size += ptrCEAELI->attrSize[i];
ptrCEAELI->SizeExt += ptrCEAELI->attrSizeExt[i];
}
//new attrs
if ( ptrCEAELI->read < ptrCEAELI->getStableValue() )
{
for (int j = 0; j < ptrCEAELI->getNoNewAttrs(); j++)
{
ptrCEAELI->attrSize[j + ptrCEAELI->getNoOldAttrs()] = 12;
ptrCEAELI->attrSizeExt[j + ptrCEAELI->getNoOldAttrs()] = 12;
ptrCEAELI->Size += ptrCEAELI
->attrSize[j + ptrCEAELI->getNoOldAttrs()];
ptrCEAELI->SizeExt += ptrCEAELI
->attrSizeExt[j + ptrCEAELI
->getNoOldAttrs()];
}
}
else
{
for (int j = 0; j < ptrCEAELI->getNoNewAttrs(); j++)
{
ptrCEAELI->attrSize[j + ptrCEAELI->getNoOldAttrs()]
= ptrCEAELI->getAttrSizeTmp(j)
/ ptrCEAELI->getStableValue();
ptrCEAELI->attrSizeExt[j + ptrCEAELI->getNoOldAttrs()]
= ptrCEAELI->getAttrSizeExtTmp(j)
/ ptrCEAELI->getStableValue();
ptrCEAELI->Size += ptrCEAELI
->attrSize[j + ptrCEAELI
->getNoOldAttrs()];
ptrCEAELI->SizeExt += ptrCEAELI
->attrSizeExt[j + ptrCEAELI
->getNoOldAttrs()];
}
}
ptrCEAELI->sizesInitialized = true;
ptrCEAELI->sizesChanged = true;
}
//ensure sizes are updated only once for passing the threshold
if ( ptrCEAELI->read >= ptrCEAELI->getStableValue() )
ptrCEAELI->setSizesFinal(true);
pRes->Card = p1.Card;
pRes->CopySizes(ptrCEAELI);
pRes->Time = p1.Time
+ p1.Card
* (uExtend + ptrCEAELI->getNoNewAttrs() * vExtend);
if ( p1.BTime < 0.1 && pipelinedProgress ) //non-blocking,
//use pipelining
pRes->Progress = p1.Progress;
else
pRes->Progress =
(p1.Progress * p1.Time +
ptrCEAELI->read
* (uExtend + ptrCEAELI->getNoNewAttrs() * vExtend))
/ pRes->Time;
pRes->CopyBlocking(p1); //non-blocking operator
return YIELD;
} else {
return CANCEL;
}
}
}
return 0;
}
/*
4.2.3 Class ~CEAExtendLocalInfo~
In the ~Progress~-Version used this class objects as data structure for the
progress informations.
The Constructor.
*/
CEAExtendLocalInfo::CEAExtendLocalInfo(
TupleType* ptrTupleType,
int sv,
bool sf,
int nna)
: resultTupleType(ptrTupleType),
stableValue(sv),
sizesFinal(sf),
noOldAttrs(0),
noNewAttrs(nna) {
attrSizeTmp = new double[nna];
attrSizeExtTmp = new double[nna];
for (int i = 0; i < nna; i++) {
attrSizeTmp[i] = 0.0;
attrSizeExtTmp[i] = 0.0;
}
};
/*
The Destructor.
*/
CEAExtendLocalInfo::~CEAExtendLocalInfo() {
if(resultTupleType){
resultTupleType->DeleteIfAllowed();
}
if(attrSizeTmp){
delete [] attrSizeTmp;
}
if(attrSizeExtTmp){
delete [] attrSizeExtTmp;
}
}
/*
The following methods are the ~get~er- and ~set~er-methods for these
private variables.
*/
void
CEAExtendLocalInfo::setResultTupleType(TupleType* ptrTupleType) {
resultTupleType = ptrTupleType;
}
TupleType*
CEAExtendLocalInfo::getResultTupleType() {
return resultTupleType;
}
void
CEAExtendLocalInfo::setStableValue(int val) {
stableValue = val;
}
int
CEAExtendLocalInfo::getStableValue() {
return stableValue;
}
void
CEAExtendLocalInfo::setSizesFinal(bool sf) {
sizesFinal = sf;
}
bool
CEAExtendLocalInfo::getSizesFinal() {
return sizesFinal;
}
void
CEAExtendLocalInfo::setNoOldAttrs(int noa) {
noOldAttrs = noa;
}
int
CEAExtendLocalInfo::getNoOldAttrs() {
return noOldAttrs;
}
void
CEAExtendLocalInfo::setNoNewAttrs(int noa) {
noNewAttrs = noa;
}
int
CEAExtendLocalInfo::getNoNewAttrs() {
return noNewAttrs;
}
void
CEAExtendLocalInfo::setAttrSizeTmp(double asp, int idx) {
attrSizeTmp[idx] = asp;
}
void
CEAExtendLocalInfo::addAttrSizeTmp(double asp, int idx) {
attrSizeTmp[idx] += asp;
}
double
CEAExtendLocalInfo::getAttrSizeTmp(int idx) {
return attrSizeTmp[idx];
}
void
CEAExtendLocalInfo::setAttrSizeExtTmp(double asep, int idx) {
attrSizeExtTmp[idx] = asep;
}
void
CEAExtendLocalInfo::addAttrSizeExtTmp(double asep, int idx) {
attrSizeExtTmp[idx] += asep;
}
double
CEAExtendLocalInfo::getAttrSizeExtTmp(int idx) {
return attrSizeExtTmp[idx];
}
#endif
/*
4.2.4 Specification of operator ~extend~
*/
const std::string ceaExtendSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" ) "
"( <text>(stream(tuple(x)) x [(a1, (tuple(x)"
" -> d1)) ... (an, (tuple(x) -> dn))] -> "
"stream(tuple(x@[a1:d1, ... , an:dn])))"
"</text--->"
"<text>_ extend [funlist]</text--->"
"<text>Extends each input tuple by new "
"attributes as specified in the parameter"
" list.</text--->"
"<text>query ten feed extend [mult5 : "
".nr * 5, mod2 : .nr mod 2] consume"
"</text--->"
") )";
/*
4.2.5 Definition of operator ~extend~
*/
Operator ceaOperatorExtend (
"extend", // name
ceaExtendSpec, // specification
ceaExtendValueMap, // value mapping
Operator::SimpleSelect, // trivial selection function
ceaExtendTypeMap // type mapping
);
/*
4.3 Operator ~executeQuery~
This operator is used, if the complete query could be compiled by this algebra.
4.3.1 Type mapping function of operator ~executeQuery~
Since this operator can not be used directly in queries, there is no valid
type mappings. A type mapping error is always generated.
*/
ListExpr ceaExecuteQueryTypeMap( ListExpr args ) {
ErrorReporter::ReportError("this operator is not to be used in queries");
return nl->TypeError();
}
/*
4.3.2 Value mapping function of operator ~executeQuery~
*/
int
ceaExecuteQueryValueMap(Word* args,
Word& result,
int message,
Word& local,
Supplier s ) {
executeQueryOp_t executeQueryOp = (executeQueryOp_t) args[0].addr;
executeQueryOp(result, s);
return 0;
}
/*
4.3.3 Specification of operator ~executeQuery~
*/
const std::string ceaExecuteQuerySpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" ) "
"( <text>()</text--->"
"<text>executeQuery</text--->"
"<text>This Operator called only from Secondo-"
"System. Is not to use in querys.</text--->"
"<text>No Exapmle exist.</text--->) )";
/*
4.3.4 Definition of operator ~executeQuery~
*/
Operator ceaOperatorExecuteQuery (
"executeQuery", // name
ceaExecuteQuerySpec, // specification
ceaExecuteQueryValueMap, // value mapping
Operator::SimpleSelect, // trivial selection function
ceaExecuteQueryTypeMap // type mapping
);
/*
5 Class ~CompiledExpressionsAlgebra~
A new subclass ~CompiledExpressionsAlgebra~ of class ~Algebra~ is declared. The only
specialization with respect to class ~Algebra~ takes place within the
constructor: all type constructors and operators are registered at the actual algebra.
After declaring the new class, its only instance ~CompiledExpressionsAlgebra~ is defined.
Definition the static variables of the ~CompiledExpressionsAlgebra~-class.
*/
bool CompiledExpressionsAlgebra::ceaActiv = false;
CompiledExpressionsAlgebra* CompiledExpressionsAlgebra::instance = 0;
/*
This function gives a pointer to the ~CompiledExpressionsAlgebra~-Instance.
*/
CompiledExpressionsAlgebra*
CompiledExpressionsAlgebra::getInstance() {
if (!instance)
instance = new CompiledExpressions::CompiledExpressionsAlgebra();
return instance;
}
/*
This function delete the ~CompiledExpressionsAlgebra~-Instance.
*/
void
CompiledExpressionsAlgebra::deleteInstance() {
if (instance)
delete instance;
instance = 0;
}
/*
This function returned, if one instance of the ~CompiledExpressionsAlgebra~ are created.
*/
bool
CompiledExpressionsAlgebra::isActiv() {
return CompiledExpressionsAlgebra::ceaActiv;
}
/*
The Constructor.
*/
CompiledExpressionsAlgebra::CompiledExpressionsAlgebra()
: Algebra(),
thisAlgID(-1) {
AddOperator(&ceaOperatorFilter);
ceaOperatorFilter.SetUsesArgsInTypeMapping();
AddOperator(&ceaOperatorExtend);
AddOperator(&ceaOperatorExecuteQuery);
/*
Register operators which are able to handle progress messages
*/
#ifdef USE_PROGRESS
ceaOperatorFilter.EnableProgress();
ceaOperatorExtend.EnableProgress();
#endif
CompiledExpressionsAlgebra::ceaActiv = true;
}
/*
The Destructor.
*/
CompiledExpressionsAlgebra::~CompiledExpressionsAlgebra() {
instance = 0;
CECodeGenerator::deleteInstance();
CECompiler::deleteInstance();
}
/*
This function returned the algebra-ID from the algebramanager or 0, if the
algera is not loaded.
*/
int
CompiledExpressionsAlgebra::getThisAlgebraID() /*throw (CEARuntimeError)*/{
if (thisAlgID == -1)
thisAlgID = am->GetAlgebraId("CompiledExpressionsAlgebra");
if (thisAlgID == 0)
throw CEARuntimeError("The CompiledExpressionsAlgebra is not loaded.");
return thisAlgID;
}
/*
This function returned the operator-ID of the spezified operator name. If the operator is
not found, the function throws an error.
*/
int
CompiledExpressionsAlgebra::getOperatorID(std::string name)
/*throw (CEARuntimeError)*/ {
int idx = 0;
bool found = false;
while ( !found && idx < GetNumOps() ) {
if ( GetOperator(idx)->GetName() == name )
found = true;
else
idx++;
}
if (!found)
throw CEARuntimeError("Operator "
+ name
+ " not insert in this algebra.");
return idx;
}
}
/*
7 Initialization
Each algebra module needs an initialization function. The algebra manager
has a reference to this function if this algebra is included in the list
of required algebras, thus forcing the linker to include this module.
The algebra manager invokes this function to get a reference to the instance
of the algebra class and to provide references to the global nested list
container (used to store constructor, type, operator and object information)
and to the query processor.
The function has a C interface to make it possible to load the algebra
dynamically at runtime.
*/
#ifdef __cplusplus
extern "C"{
#endif
Algebra*
InitializeCompiledExpressionsAlgebra(NestedList* nlRef,
QueryProcessor* qpRef)
{
nl = nlRef;
qp = qpRef;
return CompiledExpressions::CompiledExpressionsAlgebra::getInstance();
}
#ifdef __cplusplus
}
#endif