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

229 lines
5.3 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of 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
----
*/
#include <unistd.h> //todo Remove
#include "Include.h"
#include "LinearProgressEstimator.h"
using namespace nr2a;
Feed::Info::Info()
{
name = "feed";
signature = ARel::BasicType() + "(tuple(X)) -> "
+ "stream(tuple(X))";
appendSignature(NRel::BasicType() + "(tuple(X)) -> "
+ "stream(tuple(X))");
syntax = "_ feed";
meaning = "Produces a stream from a nested relation by scanning "
"the relation tuple by tuple.";
example = "query Documents feed project[Title] consume";
}
Feed::~Feed()
{
}
/*
The operator accepts "nrel2"[2] and "arel2"[2]. The output type is a tuple
stream whose tuple type equals the type of the relation's tuples.
*/
/*static*/ListExpr Feed::MapType(ListExpr args)
{
AutoWrite(args);
if (!nl->HasLength(args,1))
{
return listutils::typeError("One argument expected");
}
ListExpr relType = nl->First(args);
ListExpr result = nl->TheEmptyList();
if (Nr2aHelper::IsNestedRelation(relType))
{
ListExpr tupleType = nl->Second(relType);
result = nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()), tupleType);
}
else
{
result = listutils::typeError("Input is expected to be of type nrel2 "
"or arel2");
}
return result;
}
ValueMapping Feed::functions[] = { FeedArel, FeedNrel, NULL };
/*static*/int Feed::SelectFunction(ListExpr args)
{
return Nr2aHelper::DefaultSelect(nl->First(args));
}
/*
The relations are iterated on request until the stream is closed or the
relation is iterated to its end.
*/
/*static*/int Feed::FeedArel(Word* args, Word& result, int message,
Word& local, Supplier s)
{
int resultInt = 0;
result = qp->ResultStorage(s);
LocalInfoArel *info = (LocalInfoArel *)local.addr;
switch (message)
{
case OPEN:
{
ARel *arel = static_cast<ARel*>(args[0].addr);
ListExpr tupleType = nl->TheEmptyList();
if (qp->GetNoSons(s) == 1)
{
tupleType = qp->GetSupplierTypeExpr(s);
tupleType = nl->Second(tupleType);
}
ProgressInfo progressInfo;
progressInfo.Card = arel->GetTupleCount();
ARelIterator *iter = new ARelIterator(arel,0,0);
info = new LocalInfoArel(iter, args[0].addr, progressInfo);
local.addr = info;
}
break;
case REQUEST:
{
info->UnitReceived();
Tuple *t = NULL;
t = info->iter->getNextTuple();
if (t != NULL)
{
result.setAddr(t);
info->UnitProcessed();
resultInt = YIELD;
}
else
{
resultInt = CANCEL;
}
}
break;
case CLOSE:
if (local.addr)
{
delete info;
local.addr = NULL;
}
break;
}
return resultInt;
}
/*static*/int Feed::FeedNrel(Word* args, Word& result, int message,
Word& local, Supplier s)
{
result = qp->ResultStorage(s);
int resultInt = 0;
LocalInfoNrel *info = (LocalInfoNrel *)local.addr;
switch (message)
{
case OPEN:
{
ListExpr tupleType = nl->TheEmptyList();
NRel *nrel = static_cast<NRel*>(args[0].addr);
if (qp->GetNoSons(s) == 1)
{
tupleType = qp->GetSupplierTypeExpr(s);
tupleType = nl->Second(tupleType);
}
ProgressInfo progressInfo;
progressInfo.Card = nrel->GetTupleCount();
info = new LocalInfoNrel(nrel->getIterator(tupleType), args[0].addr,
progressInfo);
local.addr = info;
}
break;
case REQUEST:
{
info->UnitReceived();
Tuple *t = NULL;
t = info->iter->getNextTuple();
if (t != NULL)
{
result.setAddr(t);
resultInt = YIELD;
info->UnitProcessed();
}
else
{
resultInt = CANCEL;
}
}
break;
case CLOSE:
if (local.addr)
{
delete info;
local.addr = NULL;
}
break;
}
return resultInt;
}
CreateCostEstimation Feed::costEstimators[] =
{ GetCostEstimator<Feed::LocalInfoArel>,
GetCostEstimator<Feed::LocalInfoNrel> };
template <class T>
/*static*/ CostEstimation * Feed::GetCostEstimator()
{
return new LinearProgressEstimator<T>();
}
Feed::LocalInfoArel::LocalInfoArel(ARelIterator * iter,
void * predecessor, const ProgressInfo base)
: iter(iter)
{
//Intentionally left blank
}
Feed::LocalInfoArel::~LocalInfoArel()
{
delete iter;
}
Feed::LocalInfoNrel::LocalInfoNrel(NRelIterator * iter,
void * predecessor, const ProgressInfo base)
: iter(iter)
{
Nr2aLocalInfo<LinearProgressEstimator<LocalInfoNrel> >::base = base;
}
Feed::LocalInfoNrel::~LocalInfoNrel()
{
delete iter;
}