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

1935 lines
52 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2009, University in Hagen
Faculty of Mathematic 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
----
*/
#include "TBTree.h"
#include "NestedList.h"
#include "ListUtils.h"
#include "QueryProcessor.h"
#include "StandardTypes.h"
#include "Algebras/Relation-C++/RelationAlgebra.h"
#include "Algebras/FText/FTextAlgebra.h"
#include "Symbols.h"
extern NestedList* nl;
extern QueryProcessor* qp;
using namespace std;
namespace tbtree {
/*
1 Type Contructor
*/
ListExpr TBTreeProperty(){
return nl->TwoElemList(
nl->FiveElemList(
nl->StringAtom("Signature"),
nl->StringAtom("Example Type List"),
nl->StringAtom("List Rep"),
nl->StringAtom("Example List"),
nl->StringAtom("Remarks")),
nl->FiveElemList(
nl->TextAtom(" -> SIMPLE"),
nl->TextAtom(" (tbtree attrlist ai aj)"),
nl->TextAtom("(tbtree attrlist idname unitname)"),
nl->TextAtom("(rbtree ((id int) (up upoint)) id up)"),
nl->TextAtom(" alpha state"))
);
}
bool CheckTBTree(ListExpr type, ListExpr& ErrorInfo){
if(nl->ListLength(type)!=4){
ErrorReporter::ReportError("invalid list length");
return false;
}
ListExpr tbtree = nl->First(type);
ListExpr attrList = nl->Second(type);
ListExpr idName = nl->Third(type);
ListExpr upName = nl->Fourth(type);
if(!nl->IsEqual(tbtree,TBTree::BasicType())){
ErrorReporter::ReportError("symbol tbtree not found");
return false;
}
if(!listutils::isAttrList(attrList)){
ErrorReporter::ReportError("not an attrlist");
return false;
}
if(nl->AtomType(idName)!=SymbolType || nl->AtomType(upName)!=SymbolType ){
ErrorReporter::ReportError("invalid attribute names");
return false;
}
string idname = nl->SymbolValue(idName);
string upname = nl->SymbolValue(upName);
ListExpr dummy;
if(!listutils::findAttribute(attrList, idname, dummy)){
ErrorReporter::ReportError("idname not in attrlist");
return false;
}
if(!listutils::findAttribute(attrList, upname, dummy)){
ErrorReporter::ReportError("upname not in attrlist");
return false;
}
return true;
}
ListExpr OutTBTree(ListExpr typeInfo, Word value){
TBTree* t = static_cast<TBTree*>(value.addr);
return nl->TextAtom(t->toString());
}
Word InTBTree( ListExpr typeInfo, ListExpr value,
int errorPos, ListExpr& errorInfo, bool& correct ) {
correct = false;
return SetWord(Address(0));
}
Word CreateTBTree( const ListExpr typeInfo ){
return new TBTree(4000);
}
void DeleteTBTree( const ListExpr typeInfo, Word& w ){
TBTree* tree = static_cast<TBTree*>(w.addr);
tree->deleteFile();
delete tree;
}
bool OpenTBTree( SmiRecord& valueRecord,
size_t& offset,
const ListExpr typeInfo,
Word& value ){
SmiFileId fileid;
valueRecord.Read( &fileid, sizeof( SmiFileId ), offset );
offset += sizeof( SmiFileId );
SmiRecordId rid;
valueRecord.Read( &rid, sizeof( SmiRecordId ), offset );
offset += sizeof( SmiRecordId );
TBTree* tree = new TBTree(fileid, rid);
value.setAddr(tree);
return true;
}
void CloseTBTree( const ListExpr typeInfo, Word& w ){
TBTree* tree = static_cast<TBTree*>(w.addr);
delete tree;
w.setAddr(0);
}
bool SaveTBTree( SmiRecord& valueRecord,
size_t& offset,
const ListExpr typeInfo,
Word& value ){
TBTree* tree = static_cast<TBTree*>(value.addr);
SmiFileId fileId = tree->getFileId();
valueRecord.Write( &fileId, sizeof( SmiFileId ), offset );
offset += sizeof( SmiFileId );
SmiRecordId headerId = tree->getHeaderId();
valueRecord.Write(&headerId, sizeof(SmiRecordId), offset);
offset += sizeof( SmiRecordId );
return true;
}
/*
The procedure is similar as in RTree
first copy sons of a node, when all entries are written into the file,
the node is put into the file
*/
SmiRecordId TBTree::DFVisit_TBtree(TBTree* tbtree_in,
tbtree::BasicNode<3>* node)
{
if(node->isLeaf()){
SmiRecordId recordid;
recordid = saveNode(*node);
return recordid;
}else{
tbtree::InnerNode<3,InnerInfo>* innernode =
dynamic_cast<InnerNode<3,InnerInfo>*>(node);
tbtree::InnerNode<3,InnerInfo>* new_n =
new tbtree::InnerNode<3,InnerInfo>(innerMin,innerMax);
for(int i = 0;i < innernode->entryCount();i++){
const Entry<3,InnerInfo>* e = innernode->getEntry(i);
tbtree::BasicNode<3>* n =
tbtree_in->getNode(e->getInfo().getPointer());
SmiRecordId recid;
recid = DFVisit_TBtree(tbtree_in,n);
new_n->insert(Entry<3,InnerInfo>(e->getBox(),recid));
delete n;
}
SmiRecordId recordid;
recordid = saveNode(*new_n);
delete new_n;
return recordid;
}
}
/*
Copy the input TBtree to the current one
*/
void TBTree::Clone(TBTree* tbtree_in)
{
SmiRecordId root_id = tbtree_in->getRootId();
tbtree::BasicNode<3>* rootnode = tbtree_in->getNode(root_id);
root_id = DFVisit_TBtree(tbtree_in,rootnode);
noEntries = tbtree_in->entryCount();
noNodes = tbtree_in->nodeCount();
level = tbtree_in->getHeight();
noLeafNodes = tbtree_in->leafnodeCount();
box = tbtree_in->getBox();
rootId = root_id;
delete rootnode;
}
/*
~Clone~-function
*/
Word CloneTBTree( const ListExpr typeInfo, const Word& w ){
////////////new implementation ////////////////////////
TBTree* tbtree = static_cast<TBTree*>(w.addr);
TBTree* new_tbtree = new TBTree(4000);
new_tbtree->Clone(tbtree);
return SetWord( new_tbtree);
/// original implementation ///////////////
// return SetWord( Address(0) );
}
void* CastTBTree( void* addr) {
return ( 0 );
}
int SizeOfTBTree() {
return 0;
}
TypeConstructor tbtreetc( TBTree::BasicType(),
TBTreeProperty,
OutTBTree,
InTBTree,
0,
0,
CreateTBTree,
DeleteTBTree,
OpenTBTree,
SaveTBTree,
CloseTBTree,
CloneTBTree,
CastTBTree,
SizeOfTBTree,
CheckTBTree );
/*
2 Operators
*/
/*
2.1 ~createtbtree~
2.1.1 Type Mapping
rel(tuple(... (int id) ... (up upoint) ...) x id x up -> tbtree(...)
*/
ListExpr createtbtreeTM(ListExpr args){
if(nl->ListLength(args)!=3){
ErrorReporter::ReportError("wong number of arguments (3 required)");
return nl->TypeError();
}
ListExpr rel = nl->First(args);
ListExpr id = nl->Second(args);
ListExpr up = nl->Third(args);
if(!listutils::isRelDescription(rel)){
ErrorReporter::ReportError("first argument must be an tuple rel");
return nl->TypeError();
}
if(nl->AtomType(id)!=SymbolType || nl->AtomType(up)!=SymbolType){
ErrorReporter::ReportError("second and third argument must be an "
"attribute name ");
return nl->TypeError();
}
ListExpr type;
ListExpr attrList = nl->Second(nl->Second(rel));
string ids = nl->SymbolValue(id);
int index1;
if(!(index1=listutils::findAttribute(attrList,ids, type))){
ErrorReporter::ReportError("attribute " +ids +
"not an attribute of the relation ");
return nl->TypeError();
}
if(!nl->IsEqual(type,CcInt::BasicType())){
ErrorReporter::ReportError("attribute " +ids +
" has to be an int");
return nl->TypeError();
}
string ups = nl->SymbolValue(up);
int index2;
if(!(index2=listutils::findAttribute(attrList,ups, type))){
ErrorReporter::ReportError("attribute " +ups +
"not an attribute of the relation ");
return nl->TypeError();
}
if(!nl->IsEqual(type,temporalalgebra::UPoint::BasicType())){
ErrorReporter::ReportError("attribute " +ups +
" has to be a upoint");
return nl->TypeError();
}
ListExpr tree = nl->FourElemList(
nl->SymbolAtom(TBTree::BasicType()),
attrList,
id,
up);
return nl->ThreeElemList(
nl->SymbolAtom(Symbol::APPEND()),
nl->TwoElemList(
nl->IntAtom(index1),
nl->IntAtom(index2)),
tree);
}
/*
2.1.2 Specification
*/
const string createtbtreeSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>rel(tuple(...(id int)...(up upoint)...) x "
"id x up -> tbtree(...)</text--->"
"<text> _ createtbtree[_ _]</text--->"
"<text>creates a tbtree from the elements in the relation </text--->"
"<text>query UnitTrains createtbtree[Id, UTrip] </text--->"
"<text>The elements in the relation must be in temporal"
" order for a single trip</text--->"
") )";
/*
2.1.3 Value Mapping
*/
int createtbtreeVM(Word* args, Word& result, int message,
Word& local, Supplier s){
result = qp->ResultStorage(s);
TBTree* tree = static_cast<TBTree*>(result.addr);
Relation* rel = static_cast<Relation*>(args[0].addr);
GenericRelationIterator* iter = rel->MakeScan();
int index1 = (static_cast<CcInt*>(args[3].addr))->GetIntval() - 1;
int index2 = (static_cast<CcInt*>(args[4].addr))->GetIntval() - 1;
Tuple* tuple;
while((tuple = iter->GetNextTuple())){
CcInt* id = static_cast<CcInt*>(tuple->GetAttribute(index1));
temporalalgebra::UPoint* up =
static_cast<temporalalgebra::UPoint*>
(tuple->GetAttribute(index2));
TupleId tid = tuple->GetTupleId();
if(id->IsDefined() && up->IsDefined() && tid){
tree->insert(*up,id->GetIntval(), tid);
} else {
std::cerr << "undefined id, up or invalid tuple id" << endl;
}
tuple->DeleteIfAllowed();
}
delete iter;
return 0;
}
/*
2.1.4 Operator instance
*/
Operator createtbtree (
"createtbtree", // name
createtbtreeSpec, // specification
createtbtreeVM, // value mapping
Operator::SimpleSelect, // trivial selection function
createtbtreeTM);
/*
2.2 Info operators
2.2.1 Type mapping
*/
ListExpr TBTree2Int(ListExpr args){
if(nl->ListLength(args)!=1){
ErrorReporter::ReportError("invalid number of arguments");
return nl->TypeError();
}
ListExpr errorInfo = listutils::emptyErrorInfo();
if(CheckTBTree(nl->First(args), errorInfo)){
return nl->SymbolAtom(CcInt::BasicType());
}
ErrorReporter::ReportError("TBTree expected");
return nl->TypeError();
}
/*
2.2.2 Specifications
*/
const string tbentriesSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) -> int </text--->"
"<text> tbentries(_) </text--->"
"<text>returns the number of entries stored in the tb tree </text--->"
"<text>query tbentries(UnitTrains createtbtree[Id, UTrip]) </text--->"
"<text></text--->"
") )";
const string tbnodesSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) -> int </text--->"
"<text> tbnodes(_) </text--->"
"<text>returns the number of nodes stored in the tb tree </text--->"
"<text>query tbnodes(UnitTrains createtbtree[Id, UTrip]) </text--->"
"<text></text--->"
") )";
const string tbleafnodesSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) -> int </text--->"
"<text> tbleafnodes(_) </text--->"
"<text>returns the number of leaf nodes stored in the tb tree </text--->"
"<text>query tbleafnodes(UnitTrains createtbtree[Id, UTrip]) </text--->"
"<text></text--->"
") )";
const string tblevelSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) -> int </text--->"
"<text> tblevel(_) </text--->"
"<text>returns the level of the tb tree </text--->"
"<text>query level(UnitTrains createtbtree[Id, UTrip]) </text--->"
"<text></text--->"
") )";
/*
2.2.3 Value Mappings
*/
int tbentriesVM(Word* args, Word& result, int message,
Word& local, Supplier s){
TBTree* t = static_cast<TBTree*>(args[0].addr);
result = qp->ResultStorage(s);
CcInt* r = static_cast<CcInt*>(result.addr);
r->Set(true, t->entryCount());
return 0;
}
int tbnodesVM(Word* args, Word& result, int message,
Word& local, Supplier s){
TBTree* t = static_cast<TBTree*>(args[0].addr);
result = qp->ResultStorage(s);
CcInt* r = static_cast<CcInt*>(result.addr);
r->Set(true, t->nodeCount());
return 0;
}
int tbleafnodesVM(Word* args, Word& result, int message,
Word& local, Supplier s){
TBTree* t = static_cast<TBTree*>(args[0].addr);
result = qp->ResultStorage(s);
CcInt* r = static_cast<CcInt*>(result.addr);
r->Set(true, t->leafnodeCount());
return 0;
}
int tblevelVM(Word* args, Word& result, int message,
Word& local, Supplier s){
TBTree* t = static_cast<TBTree*>(args[0].addr);
result = qp->ResultStorage(s);
CcInt* r = static_cast<CcInt*>(result.addr);
r->Set(true, t->getHeight());
return 0;
}
/*
2.2.4 Operator definitions
*/
Operator tbentries (
"tbentries", // name
tbentriesSpec, // specification
tbentriesVM, // value mapping
Operator::SimpleSelect, // trivial selection function
TBTree2Int);
Operator tbnodes (
"tbnodes", // name
tbnodesSpec, // specification
tbnodesVM, // value mapping
Operator::SimpleSelect, // trivial selection function
TBTree2Int);
Operator tbleafnodes (
"tbleafnodes", // name
tbleafnodesSpec, // specification
tbleafnodesVM, // value mapping
Operator::SimpleSelect, // trivial selection function
TBTree2Int);
Operator tblevel (
"tblevel", // name
tblevelSpec, // specification
tblevelVM, // value mapping
Operator::SimpleSelect, // trivial selection function
TBTree2Int);
/*
2.4 getnodes
2.4.1 Auxiliary class
*/
template<unsigned Dim>
class AllSelector{
public:
bool operator()(BasicNode<Dim> * n) const{
return true;
}
};
/*
2.4.2 Type Mapping
*/
ListExpr getnodesTM(ListExpr args){
if(nl->ListLength(args)!=1){
ErrorReporter::ReportError("invalid number of arguments");
return nl->TypeError();
}
ListExpr errorInfo = listutils::emptyErrorInfo();
if(CheckTBTree(nl->First(args), errorInfo)){
return nl->TwoElemList(
nl->SymbolAtom(Symbol::STREAM()),
nl->TwoElemList(
nl->SymbolAtom(Tuple::BasicType()),
nl->Cons(
nl->TwoElemList(
nl->SymbolAtom("Id"),
nl->SymbolAtom(CcInt::BasicType())),
nl->SixElemList(
nl->TwoElemList(
nl->SymbolAtom("ParentId"),
nl->SymbolAtom(CcInt::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("Level"),
nl->SymbolAtom(CcInt::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("IsLeaf"),
nl->SymbolAtom(CcBool::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("Entries"),
nl->SymbolAtom(CcInt::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("Box"),
nl->SymbolAtom(Rectangle<3>::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("Cov"),
nl->SymbolAtom(CcInt::BasicType()))))));
}
ErrorReporter::ReportError("TBTree expected");
return nl->TypeError();
}
/*
2.4.2 Specification
*/
const string getnodesSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) -> stream(tuple(...)) </text--->"
"<text> getnodes(_) </text--->"
"<text>returns the nodes contained in the tree </text--->"
"<text>query getnodes(UnitTrains createtbtree[Id, UTrip]) count</text--->"
"<text></text--->"
") )";
/*
2.4.3 Value Mapping
2.4.3.1 LocalInfo
*/
class GetnodesLocalInfo{
public:
GetnodesLocalInfo(TBTree* t,
const ListExpr tupleType,
const AllSelector<3>& s,
const NoPruner<InnerNode<3, InnerInfo> >& p): ds(t,s,p){
tt = new TupleType(tupleType);
}
~GetnodesLocalInfo(){
tt->DeleteIfAllowed();
ds.finish();
}
DepthSearch<TBTree,
InnerNode<3, InnerInfo>,
3, AllSelector<3> ,
NoPruner<InnerNode<3, InnerInfo> >
> ds;
TupleType* tt;
};
/*
2.4.3.1 Value Mapping function
*/
int getnodesVM(Word* args, Word& result, int message,
Word& local, Supplier s){
switch (message){
case OPEN:{
if(local.addr){
delete static_cast<GetnodesLocalInfo*>(local.addr);
}
AllSelector<3> as;
TBTree* t = static_cast<TBTree*>(args[0].addr);
NoPruner<InnerNode<3, InnerInfo> > p;
local.addr = new GetnodesLocalInfo(t,
nl->Second(GetTupleResultType(s)), as,p );
return 0;
}
case REQUEST: {
if(!local.addr){
return CANCEL;
}
GetnodesLocalInfo* li = static_cast<GetnodesLocalInfo*>(local.addr);
IteratorElement<3> next;
if(!li->ds.next(next)){
return CANCEL;
}
TBTree* t = static_cast<TBTree*>(args[0].addr);
Tuple* res = new Tuple(li->tt);
res->PutAttribute(0, new CcInt(true, next.getOwnId()));
res->PutAttribute(1, new CcInt(true, next.getParentId()));
res->PutAttribute(2, new CcInt(true, next.getLevel()));
res->PutAttribute(3, new CcBool(true, next.getNode()->isLeaf()));
res->PutAttribute(4, new CcInt(true, next.getNode()->entryCount()));
res->PutAttribute(5, new Rectangle<3>(next.getNode()->getBox()));
BasicNode<3>* node = t->getNode(next.getOwnId());
res->PutAttribute(6, new CcInt(true,t->getcoverage(node)));
delete node;
next.deleteNode();
result.setAddr(res);
return YIELD;
}
case CLOSE: {
if(local.addr){
delete static_cast<GetnodesLocalInfo*>(local.addr);
local.setAddr(0);
}
return 0;
}
default: assert(false);
return 0;
}
}
/*
2.4.4 Operator Instance
*/
Operator getnodes (
"getnodes", // name
getnodesSpec, // specification
getnodesVM, // value mapping
Operator::SimpleSelect, // trivial selection function
getnodesTM);
/*
2.5. Operator getFileInfo
2.5.1 Type Mapping
*/
ListExpr TBTree2Text(ListExpr args){
if(nl->ListLength(args)!=1){
ErrorReporter::ReportError("invalid number of arguments");
return nl->TypeError();
}
ListExpr errorInfo = listutils::emptyErrorInfo();
if(CheckTBTree(nl->First(args), errorInfo)){
return nl->SymbolAtom(FText::BasicType());
}
ErrorReporter::ReportError("TBTree expected");
return nl->TypeError();
}
/*
2.5.2 Specification
*/
const string getFileInfoSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) -> text </text--->"
"<text> getFileIndo(_) </text--->"
"<text> returns information about the underlying file </text--->"
"<text>query getFileInfo(UnitTrains createtbtree[Id, UTrip]) </text--->"
"<text></text--->"
") )";
/*
2.5.2 Value Mapping
*/
int getFileInfoVM(Word* args, Word& result, int message,
Word& local, Supplier s)
{
result = qp->ResultStorage(s);
FText* restext = static_cast<FText*>(result.addr);
TBTree* tree = (TBTree*)(args[0].addr);
SmiStatResultType resVector(0);
if ( (tree != 0) && tree->getFileStats(resVector) ){
string resString = "[[\n";
for(SmiStatResultType::iterator i = resVector.begin();
i != resVector.end(); ){
resString += "\t[['" + i->first + "'],['" + i->second + "']]";
if(++i != resVector.end()){
resString += ",\n";
} else {
resString += "\n";
}
}
resString += "]]";
restext->Set(true, resString);
} else {
restext->Set(false,"");
}
return 0;
};
/*
2.5.2 Operator Instance
*/
Operator getFileInfo (
"getFileInfo", // name
getFileInfoSpec, // specification
getFileInfoVM, // value mapping
Operator::SimpleSelect, // trivial selection function
TBTree2Text);
/*
2.6 getEntries
2.4.1 Auxiliary class
*/
template<unsigned Dim>
class LeafSelector{
public:
bool operator()(BasicNode<Dim> * n) const{
return n->isLeaf();
}
};
/*
2.6.2 Type Mapping
*/
ListExpr getentriesTM(ListExpr args){
if(nl->ListLength(args)!=1){
ErrorReporter::ReportError("invalid number of arguments");
return nl->TypeError();
}
ListExpr errorInfo = listutils::emptyErrorInfo();
if(CheckTBTree(nl->First(args), errorInfo)){
return nl->TwoElemList(
nl->SymbolAtom(Symbol::STREAM()),
nl->TwoElemList(
nl->SymbolAtom(Tuple::BasicType()),
nl->ThreeElemList(
nl->TwoElemList(
nl->SymbolAtom("TupleId"),
nl->SymbolAtom(CcInt::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("TrjId"),
nl->SymbolAtom(CcInt::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("Box"),
nl->SymbolAtom(Rectangle<3>::BasicType())))));
}
ErrorReporter::ReportError("TBTree expected");
return nl->TypeError();
}
ListExpr getallentriesTM(ListExpr args){
if(nl->ListLength(args)!=1){
ErrorReporter::ReportError("invalid number of arguments");
return nl->TypeError();
}
ListExpr errorInfo = listutils::emptyErrorInfo();
if(CheckTBTree(nl->First(args), errorInfo)){
return nl->TwoElemList(
nl->SymbolAtom(Symbol::STREAM()),
nl->TwoElemList(
nl->SymbolAtom(Tuple::BasicType()),
nl->FourElemList(
nl->TwoElemList(
nl->SymbolAtom("TupleId"),
nl->SymbolAtom(CcInt::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("TrjId"),
nl->SymbolAtom(CcInt::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("Box"),
nl->SymbolAtom(Rectangle<3>::BasicType())),
nl->TwoElemList(
nl->SymbolAtom("Nodeid"),
nl->SymbolAtom(CcInt::BasicType())))));
}
ErrorReporter::ReportError("TBTree expected");
return nl->TypeError();
}
/*
2.6.2 Specification
*/
const string getentriesSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) -> stream(tuple(...)) </text--->"
"<text> getentries(_) </text--->"
"<text>returns the leaf entries contained in the tree </text--->"
"<text>query getentries(UnitTrains createtbtree[Id, UTrip]) count</text--->"
"<text></text--->"
") )";
const string getallentriesSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) -> stream(tuple(...)) </text--->"
"<text> getentries(_) </text--->"
"<text>returns the entries contained in the tree </text--->"
"<text>query getallentries(UnitTrains createtbtree[Id, UTrip])"
" count</text--->"
"<text></text--->"
") )";
/*
2.6.3 Value Mapping
2.6.3.1 LocalInfo
*/
class GetentriesLocalInfo{
public:
GetentriesLocalInfo(TBTree* t,
const ListExpr tupleType,
const LeafSelector<3>& s,
const NoPruner<InnerNode<3, InnerInfo> >& p):
ds(t,s,p), node(0), pos(0){
tt = new TupleType(tupleType);
}
~GetentriesLocalInfo(){
tt->DeleteIfAllowed();
ds.finish();
if(node){
delete node;
}
}
Tuple* next(){
if(!node){
getNextNode();
} else if(pos==node->entryCount()){
getNextNode();
}
if(!node){
return 0;
} else {
const Entry<3, TBLeafInfo>* e = node->getEntry(pos);
pos++;
Tuple* res = new Tuple(tt);
res->PutAttribute(0, new CcInt(true, e->getInfo().getTupleId()));
res->PutAttribute(1, new CcInt(true, node->getTrjId()));
res->PutAttribute(2, new Rectangle<3>(e->getBox()));
return res;
}
}
Tuple* newnext(){
if(!node){
getNextNode();
} else if(pos==node->entryCount()){
getNextNode();
}
if(!node){
return 0;
} else {
static unsigned int index = 0;
const Entry<3, TBLeafInfo>* e = node->getEntry(pos);
int nodeid;
nodeid = vpath[index].getOwnId();
index++;
if(index == vpath.size()) {
pos++;
index = 0;
}
Tuple* res = new Tuple(tt);
res->PutAttribute(0, new CcInt(true, e->getInfo().getTupleId()));
res->PutAttribute(1, new CcInt(true, node->getTrjId()));
res->PutAttribute(2, new Rectangle<3>(e->getBox()));
res->PutAttribute(3, new CcInt(true,nodeid));
return res;
}
}
private:
void getNextNode(){
if(node){
delete node;
node = 0;
}
pos = 0;
IteratorElement<3> next;
if(ds.next(next)){
assert(next.getNode()->isLeaf());
node = dynamic_cast<TBLeafNode<3,
TBLeafInfo>*>(next.getNode());
pos = 0;
////////store path ///////////
path = ds.getPath();
vpath.clear();
while(!path.empty()){
vpath.push_back(path.top());
path.pop();
}
////////////////////////////
}
}
DepthSearch<TBTree,
InnerNode<3, InnerInfo>,
3, LeafSelector<3>,
NoPruner<InnerNode<3, InnerInfo> >
> ds;
TupleType* tt;
TBLeafNode<3, TBLeafInfo>* node;
int pos;
stack<PathElement<3> > path;
vector<PathElement<3> > vpath;
};
/*
2.6.3.1 Value Mapping function
*/
int getentriesVM(Word* args, Word& result, int message,
Word& local, Supplier s){
switch (message){
case OPEN:{
if(local.addr){
delete static_cast<GetentriesLocalInfo*>(local.addr);
}
LeafSelector<3> as;
TBTree* t = static_cast<TBTree*>(args[0].addr);
NoPruner<InnerNode<3, InnerInfo> > p;
local.addr = new GetentriesLocalInfo(t,
nl->Second(GetTupleResultType(s)), as, p);
return 0;
}
case REQUEST: {
if(!local.addr){
return CANCEL;
}
GetentriesLocalInfo* li =
static_cast<GetentriesLocalInfo*>(local.addr);
Tuple* res = li->next();
result.addr = res;
return res?YIELD: CANCEL;
}
case CLOSE: {
if(local.addr){
delete static_cast<GetentriesLocalInfo*>(local.addr);
local.setAddr(0);
}
return 0;
}
default: assert(false);
return 0;
}
}
int getallentriesVM(Word* args, Word& result, int message,
Word& local, Supplier s){
switch (message){
case OPEN:{
if(local.addr){
delete static_cast<GetentriesLocalInfo*>(local.addr);
}
LeafSelector<3> as;
TBTree* t = static_cast<TBTree*>(args[0].addr);
NoPruner<InnerNode<3, InnerInfo> > p;
local.addr = new GetentriesLocalInfo(t,
nl->Second(GetTupleResultType(s)), as, p);
return 0;
}
case REQUEST: {
if(!local.addr){
return CANCEL;
}
GetentriesLocalInfo* li =
static_cast<GetentriesLocalInfo*>(local.addr);
Tuple* res = li->newnext();
result.addr = res;
return res?YIELD: CANCEL;
}
case CLOSE: {
if(local.addr){
delete static_cast<GetentriesLocalInfo*>(local.addr);
local.setAddr(0);
}
return 0;
}
default: assert(false);
return 0;
}
}
/*
2.6.4 Operator Instance
*/
Operator getentries (
"getentries", // name
getentriesSpec, // specification
getentriesVM, // value mapping
Operator::SimpleSelect, // trivial selection function
getentriesTM);
Operator getallentries (
"getallentries", // name
getallentriesSpec, // specification
getallentriesVM, // value mapping
Operator::SimpleSelect, // trivial selection function
getallentriesTM);
/*
2.7 windowIntersectsS
2.7.1 Type Mapping
*/
ListExpr windowintersectsSTM(ListExpr args){
if(nl->ListLength(args)!=2){
ErrorReporter::ReportError("invalid number of arguments");
return nl->TypeError();
}
if(!nl->IsEqual(nl->Second(args), Rectangle<2>::BasicType()) &&
!nl->IsEqual(nl->Second(args), Rectangle<3>::BasicType())){
ErrorReporter::ReportError("second argument must be a rectangle");
return nl->TypeError();
}
ListExpr errorInfo = listutils::emptyErrorInfo();
if(CheckTBTree(nl->First(args), errorInfo)){
return nl->TwoElemList(
nl->SymbolAtom(Symbol::STREAM()),
nl->TwoElemList(
nl->SymbolAtom(Tuple::BasicType()),
nl->OneElemList(
nl->TwoElemList(
nl->SymbolAtom("id"),
nl->SymbolAtom(TupleIdentifier::BasicType())))));
}
ErrorReporter::ReportError("TBTree expected as first arg");
return nl->TypeError();
}
/*
2.6.2 Specification
*/
const string windowintersectsSSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) x rect | rect3 -> stream(tuple((id tid))) </text--->"
"<text> _ windowintersectsS[_]</text--->"
"<text>Returns the ids of the entries intersecting w </text--->"
"<text>query (UnitTrains createtbtree[Id, UTrip]) "
"windowinterscetsS[b] count</text--->"
"<text></text--->"
") )";
/*
2.7.3 Value Mapping
2.7.3.1 LocalInfo
*/
class WindowintersectsSLocalInfo{
public:
WindowintersectsSLocalInfo(TBTree* t,
const LeafSelector<3>& s,
const IntersectsPruner<3, InnerNode<3, InnerInfo> >& p,
const ListExpr ttlist,
Relation* rel1 = 0)
: ds(t,s,p), node(0), pos(0), rel(rel1) {
tt = new TupleType(ttlist);
rect = p.getBox();
}
~WindowintersectsSLocalInfo(){
if(tt){
tt->DeleteIfAllowed();
}
ds.finish();
if(node){
delete node;
}
}
Tuple* next(){
assert(rel==0);
if(!node){
getNextNode();
}
while(node){
while(pos<node->entryCount()){
const Entry<3, TBLeafInfo>* e = node->getEntry(pos);
pos++;
if(rect.Intersects(e->getBox())){
Tuple* res = new Tuple(tt);
res->PutAttribute(0, new TupleIdentifier(true,
e->getInfo().getTupleId()));
return res;
}
}
getNextNode();
}
return 0;
}
Tuple* nextTuple(){
assert(rel);
if(!node){
getNextNode();
}
while(node){
while(pos<node->entryCount()){
const Entry<3, TBLeafInfo>* e = node->getEntry(pos);
pos++;
if(rect.Intersects(e->getBox())){
Tuple* res = rel->GetTuple(e->getInfo().getTupleId(), false);
return res;
}
}
getNextNode();
}
return 0;
}
private:
void getNextNode(){
if(node){
delete node;
node = 0;
}
pos = 0;
IteratorElement<3> next;
if(ds.next(next)){
assert(next.getNode()->isLeaf());
node = dynamic_cast<TBLeafNode<3,
TBLeafInfo>*>(next.getNode());
}
}
DepthSearch<TBTree,
InnerNode<3, InnerInfo>,
3, LeafSelector<3>,
IntersectsPruner<3, InnerNode<3, InnerInfo> >
> ds;
TBLeafNode<3, TBLeafInfo>* node;
int pos;
Relation* rel;
Rectangle<3> rect;
TupleType* tt;
};
/*
2.7.3.2 Value Mapping function
*/
int windowintersectsS_3dVM(Word* args, Word& result, int message,
Word& local, Supplier s){
switch (message){
case OPEN:{
if(local.addr){
delete static_cast<WindowintersectsSLocalInfo*>(local.addr);
local.addr=0;
}
Rectangle<3>* rect3 = static_cast<Rectangle<3>*>(args[1].addr);
if(!rect3->IsDefined()){
return 0;
}
LeafSelector<3> as;
TBTree* t = static_cast<TBTree*>(args[0].addr);
IntersectsPruner<3, InnerNode<3, InnerInfo> > p(*rect3);
local.addr = new WindowintersectsSLocalInfo(t, as, p,
nl->Second(GetTupleResultType(s)));
return 0;
}
case REQUEST: {
if(!local.addr){
return CANCEL;
}
WindowintersectsSLocalInfo* li =
static_cast<WindowintersectsSLocalInfo*>(local.addr);
Tuple* res = li->next();
result.addr = res;
return res?YIELD: CANCEL;
}
case CLOSE: {
if(local.addr){
delete static_cast<WindowintersectsSLocalInfo*>(local.addr);
local.setAddr(0);
}
return 0;
}
default: assert(false);
return 0;
}
}
int windowintersectsS_2dVM(Word* args, Word& result, int message,
Word& local, Supplier s){
switch (message){
case OPEN:{
if(local.addr){
delete static_cast<WindowintersectsSLocalInfo*>(local.addr);
local.addr=0;
}
Rectangle<2>* rect = static_cast<Rectangle<2>*>(args[1].addr);
if(!rect->IsDefined()){
return 0;
}
LeafSelector<3> as;
TBTree* t = static_cast<TBTree*>(args[0].addr);
Rectangle<3> box = t->getBox();
if(!box.IsDefined()){
return 0;
}
double min[3];
double max[3];
min[0] = rect->MinD(0);
min[1] = rect->MinD(1);
min[2] = box.MinD(2);
max[0] = rect->MaxD(0);
max[1] = rect->MaxD(1);
max[2] = box.MaxD(2);
Rectangle<3> rect3(true, min, max);
IntersectsPruner<3, InnerNode<3, InnerInfo> > p(rect3);
local.addr = new WindowintersectsSLocalInfo(t, as, p,
nl->Second(GetTupleResultType(s)));
return 0;
}
case REQUEST: {
if(!local.addr){
return CANCEL;
}
WindowintersectsSLocalInfo* li =
static_cast<WindowintersectsSLocalInfo*>(local.addr);
Tuple* res = li->next();
result.addr = res;
return res?YIELD: CANCEL;
}
case CLOSE: {
if(local.addr){
delete static_cast<WindowintersectsSLocalInfo*>(local.addr);
local.setAddr(0);
}
return 0;
}
default: assert(false);
return 0;
}
}
/*
2.7.4 Selection Function
*/
int windowintersectsSSelect(ListExpr args){
if(nl->IsEqual(nl->Second(args),Rectangle<2>::BasicType())){
return 0;
} else {
return 1;
}
}
/*
2.7.5 Value Mapping Array
*/
ValueMapping windowintersectsSVM[] = {
windowintersectsS_2dVM,
windowintersectsS_3dVM};
/*
2.7.6 Operator Instance
*/
Operator windowintersectsS (
"windowintersectsS", // name
windowintersectsSSpec, // specification
2,
windowintersectsSVM, // value mapping
windowintersectsSSelect,
windowintersectsSTM);
/*
2.8 Operator getBox
2.8.1 Type mapping
*/
ListExpr getBoxTM(ListExpr args){
if(nl->ListLength(args)!=1){
ErrorReporter::ReportError("invalid number of arguments");
return nl->TypeError();
}
ListExpr errorInfo = listutils::emptyErrorInfo();
if(CheckTBTree(nl->First(args), errorInfo)){
return nl->SymbolAtom(Rectangle<3>::BasicType());
}
ErrorReporter::ReportError("TBTree expected");
return nl->TypeError();
}
/*
2.8.2 Specification
*/
const string getBoxSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) -> rect3 </text--->"
"<text> getBox(_) </text--->"
"<text>returns bounding box of the tree </text--->"
"<text>query getBox(UnitTrains createtbtree[Id, UTrip]) </text--->"
"<text></text--->"
") )";
/*
2.8.3 Value Mapping
*/
int getBoxVM(Word* args, Word& result, int message,
Word& local, Supplier s){
TBTree* t = static_cast<TBTree*>(args[0].addr);
result = qp->ResultStorage(s);
Rectangle<3>* r = static_cast<Rectangle<3>*>(result.addr);
*r = t->getBox();
return 0;
}
/*
2.8.4 Operator definitions
*/
Operator getBox (
"getBox", // name
getBoxSpec, // specification
getBoxVM, // value mapping
Operator::SimpleSelect, // trivial selection function
getBoxTM);
/*
2.9 windowIntersects
2.9.1 Type Mapping
*/
ListExpr windowintersectsTM(ListExpr args){
if(nl->ListLength(args)!=3){
ErrorReporter::ReportError("invalid number of arguments");
return nl->TypeError();
}
if(!nl->IsEqual(nl->Third(args), Rectangle<2>::BasicType()) &&
!nl->IsEqual(nl->Third(args), Rectangle<3>::BasicType())){
ErrorReporter::ReportError("second argument must be a rectangle");
return nl->TypeError();
}
ListExpr errorInfo = listutils::emptyErrorInfo();
if(CheckTBTree(nl->First(args), errorInfo) &&
listutils::isRelDescription(nl->Second(args))){
ListExpr tbal = nl->Second(nl->First(args));
ListExpr relal = nl->Second(nl->Second(nl->Second(args)));
if(!nl->Equal(tbal, relal)){
ErrorReporter::ReportError("types of tbtree and relation differ");
return nl->TypeError();
}
return nl->TwoElemList(
nl->SymbolAtom(Symbol::STREAM()),
nl->TwoElemList(
nl->SymbolAtom(Tuple::BasicType()),
relal));
}
ErrorReporter::ReportError("tbtree x rel x rect | rect3 expected");
return nl->TypeError();
}
/*
2.9.2 Specification
*/
const string windowintersectsSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>tbtree(...) x rel x rect | rect3 -> stream(tuple((...))) </text--->"
"<text> _ _ windowintersects[_]</text--->"
"<text>returns the tuple indexed by the tree"
" intersecting the rectangle</text--->"
"<text>query (UnitTrains createtbtree[Id, UTrip]) "
"UnitTrains windowintersect[b] count</text--->"
"<text></text--->"
") )";
/*
2.9.3 Value Mapping functions
*/
int windowintersects_3dVM(Word* args, Word& result, int message,
Word& local, Supplier s){
switch (message){
case OPEN:{
if(local.addr){
delete static_cast<WindowintersectsSLocalInfo*>(local.addr);
local.addr=0;
}
Relation* rel = static_cast<Relation*>(args[1].addr);
Rectangle<3>* rect3 = static_cast<Rectangle<3>*>(args[2].addr);
if(!rect3->IsDefined()){
return 0;
}
LeafSelector<3> as;
TBTree* t = static_cast<TBTree*>(args[0].addr);
IntersectsPruner<3, InnerNode<3, InnerInfo> > p(*rect3);
local.addr = new WindowintersectsSLocalInfo(t, as, p,
nl->Second(GetTupleResultType(s)),
rel);
return 0;
}
case REQUEST: {
if(!local.addr){
return CANCEL;
}
WindowintersectsSLocalInfo* li =
static_cast<WindowintersectsSLocalInfo*>(local.addr);
Tuple* res = li->nextTuple();
result.addr = res;
return res?YIELD: CANCEL;
}
case CLOSE: {
if(local.addr){
delete static_cast<WindowintersectsSLocalInfo*>(local.addr);
local.setAddr(0);
}
return 0;
}
default: assert(false);
return 0;
}
}
int windowintersects_2dVM(Word* args, Word& result, int message,
Word& local, Supplier s){
switch (message){
case OPEN:{
if(local.addr){
delete static_cast<WindowintersectsSLocalInfo*>(local.addr);
local.addr=0;
}
Relation* rel = static_cast<Relation*>(args[1].addr);
Rectangle<2>* rect = static_cast<Rectangle<2>*>(args[2].addr);
if(!rect->IsDefined()){
return 0;
}
LeafSelector<3> as;
TBTree* t = static_cast<TBTree*>(args[0].addr);
Rectangle<3> box = t->getBox();
if(!box.IsDefined()){
return 0;
}
double min[3];
double max[3];
min[0] = rect->MinD(0);
min[1] = rect->MinD(1);
min[2] = box.MinD(2);
max[0] = rect->MaxD(0);
max[1] = rect->MaxD(1);
max[2] = box.MaxD(2);
Rectangle<3> rect3(true, min, max);
IntersectsPruner<3, InnerNode<3, InnerInfo> > p(rect3);
local.addr = new WindowintersectsSLocalInfo(t, as, p,
nl->Second(GetTupleResultType(s)),
rel);
return 0;
}
case REQUEST: {
if(!local.addr){
return CANCEL;
}
WindowintersectsSLocalInfo* li =
static_cast<WindowintersectsSLocalInfo*>(local.addr);
Tuple* res = li->nextTuple();
result.addr = res;
return res?YIELD: CANCEL;
}
case CLOSE: {
if(local.addr){
delete static_cast<WindowintersectsSLocalInfo*>(local.addr);
local.setAddr(0);
}
return 0;
}
default: assert(false);
return 0;
}
}
/*
2.7.4 Selection Function
*/
int windowintersectsSelect(ListExpr args){
if(nl->IsEqual(nl->Third(args),Rectangle<2>::BasicType())){
return 0;
} else {
return 1;
}
}
/*
2.7.5 Value Mapping Array
*/
ValueMapping windowintersectsVM[] = {
windowintersects_2dVM,
windowintersects_3dVM};
/*
2.7.6 Operator Instance
*/
Operator windowintersects (
"windowintersects", // name
windowintersectsSpec, // specification
2,
windowintersectsVM, // value mapping
windowintersectsSelect,
windowintersectsTM);
/*
2.8 ~bulkloadtbtree~
2.8.1 Type Mapping
stream(tuple(... (int id) ... (up upoint) ...(T tid) ...) x id x up x T -> tbtree(...)
*/
ListExpr bulkloadtbtreeTM(ListExpr args){
if(nl->ListLength(args)!=4){
ErrorReporter::ReportError("wong number of arguments (3 required)");
return nl->TypeError();
}
ListExpr stream = nl->First(args);
ListExpr id = nl->Second(args);
ListExpr up = nl->Third(args);
ListExpr tid = nl->Fourth(args);
if(!listutils::isTupleStream(stream)){
ErrorReporter::ReportError("first argument must be an tuple stream");
return nl->TypeError();
}
if(nl->AtomType(id)!=SymbolType || nl->AtomType(up)!=SymbolType ||
nl->AtomType(tid)!=SymbolType ){
ErrorReporter::ReportError("second,third, and fouth argument must be an "
"attribute name ");
return nl->TypeError();
}
ListExpr type;
ListExpr attrList = nl->Second(nl->Second(stream));
string ids = nl->SymbolValue(id);
int index1;
if(!(index1=listutils::findAttribute(attrList,ids, type))){
ErrorReporter::ReportError("attribute " +ids +
"not an attribute of the relation ");
return nl->TypeError();
}
if(!nl->IsEqual(type,CcInt::BasicType())){
ErrorReporter::ReportError("attribute " +ids +
" has to be an int");
return nl->TypeError();
}
string ups = nl->SymbolValue(up);
int index2;
if(!(index2=listutils::findAttribute(attrList,ups, type))){
ErrorReporter::ReportError("attribute " +ups +
"not an attribute of the relation ");
return nl->TypeError();
}
if(!nl->IsEqual(type,temporalalgebra::UPoint::BasicType())){
ErrorReporter::ReportError("attribute " +ups +
" has to be a upoint");
return nl->TypeError();
}
string tids = nl->SymbolValue(tid);
int index3;
if(!(index3=listutils::findAttribute(attrList,tids, type))){
ErrorReporter::ReportError("attribute " + tids +
"not an attribute of the relation ");
return nl->TypeError();
}
if(!nl->IsEqual(type,TupleIdentifier::BasicType())){
ErrorReporter::ReportError("attribute " +tids +
" has to be a tid");
return nl->TypeError();
}
ListExpr tree = nl->FourElemList(
nl->SymbolAtom(TBTree::BasicType()),
attrList,
id,
up);
return nl->ThreeElemList(
nl->SymbolAtom(Symbol::APPEND()),
nl->ThreeElemList(
nl->IntAtom(index1),
nl->IntAtom(index2),
nl->IntAtom(index3)),
tree);
}
/*
2.8.2 Specification
*/
const string bulkloadtbtreeSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" "
"\"Example\" \"Comment\" ) "
"(<text>stream(tuple(...(id int)...(up upoint)...) x "
"id x up x tid -> tbtree(...)</text--->"
"<text> _ bulkloadtbtree[_ _ _]</text--->"
"<text>creates a tbtree from the elements in the stream</text--->"
"<text>query UnitTrains feed addid bulkloadtbtree[Id, UTrip, TID]</text--->"
"<text>The elements in the stream must be ordered by tid / time</text--->"
") )";
/*
2.8.3 Value Mapping
*/
int bulkloadtbtreeVM(Word* args, Word& result, int message,
Word& local, Supplier s){
result = qp->ResultStorage(s);
TBTree* tree = static_cast<TBTree*>(result.addr);
int index1 = (static_cast<CcInt*>(args[4].addr))->GetIntval() - 1;
int index2 = (static_cast<CcInt*>(args[5].addr))->GetIntval() - 1;
int index3 = (static_cast<CcInt*>(args[6].addr))->GetIntval() -1;
Tuple* tuple;
Word wTuple(Address(0));
qp->Open(args[0].addr);
qp->Request(args[0].addr, wTuple);
CcInt lastId(false); // last trajectory id
TBLeafNode<3, TBLeafInfo>* currentLeaf(0);
while(qp->Received(args[0].addr)){
tuple = static_cast<Tuple*>(wTuple.addr);
// get required information
CcInt* id = static_cast<CcInt*>(tuple->GetAttribute(index1));
temporalalgebra::UPoint* up = static_cast<temporalalgebra::UPoint*>
(tuple->GetAttribute(index2));
TupleIdentifier* tid =
static_cast<TupleIdentifier*>(tuple->GetAttribute(index3));
if(id->IsDefined() && up->IsDefined() && tid->IsDefined()){
Entry<3, TBLeafInfo> e(up->BoundingBox(), tid->GetTid());
if(currentLeaf){
if(currentLeaf->getTrjId()!= id->GetIntval()){
// start next trajectory
int lid = 0;
if(lastId.IsDefined()){
lid = lastId.GetIntval();
}
tree->insertLeaf(*currentLeaf, lid);
lastId.SetDefined(false);
currentLeaf->deleteEntries();
assert(currentLeaf->entryCount()==0);
currentLeaf->setNext(0);
currentLeaf->setTrjId(id->GetIntval());
currentLeaf->insert(e);
} else { // same trajectory
if(currentLeaf->entryCount() < currentLeaf->getMax()){
currentLeaf->insert(e);
} else { // same trajectory but full
int lid = 0;
if(lastId.IsDefined()){
lid = lastId.GetIntval();
}
SmiRecordId pred = tree->insertLeaf(*currentLeaf,
(SmiRecordId)lid);
lastId.Set(true,pred);
currentLeaf->deleteEntries();
assert(currentLeaf->entryCount()==0);
currentLeaf->setNext(0);
currentLeaf->insert(e);
}
}
} else { // no current leaf available
currentLeaf = tree->getEmptyLeaf(tid->GetTid());
currentLeaf->insert(e);
}
} else {
std::cerr << "undefined id, up or invalid tuple id" << endl;
}
tuple->DeleteIfAllowed();
qp->Request(args[0].addr, wTuple);
}
if(currentLeaf){
int lid = 0;
if(lastId.IsDefined()){
lid = lastId.GetIntval();
}
tree->insertLeaf(*currentLeaf, lid);
delete currentLeaf;
}
qp->Close(args[0].addr);
return 0;
}
/*
2.1.4 Operator instance
*/
Operator bulkloadtbtree (
"bulkloadtbtree", // name
bulkloadtbtreeSpec, // specification
bulkloadtbtreeVM, // value mapping
Operator::SimpleSelect, // trivial selection function
bulkloadtbtreeTM);
} // end of namespace tbtree
/*
3 Algebra Creation
*/
class TBTreeAlgebra : public Algebra {
public:
TBTreeAlgebra() : Algebra() {
AddTypeConstructor( &tbtree::tbtreetc );
AddOperator(&tbtree::createtbtree);
AddOperator(&tbtree::tbentries);
AddOperator(&tbtree::tbnodes);
AddOperator(&tbtree::tbleafnodes);
AddOperator(&tbtree::tblevel);
AddOperator(&tbtree::getnodes);
AddOperator(&tbtree::getFileInfo);
AddOperator(&tbtree::getentries);
AddOperator(&tbtree::windowintersectsS);
AddOperator(&tbtree::getBox);
AddOperator(&tbtree::windowintersects);
AddOperator(&tbtree::bulkloadtbtree);
AddOperator(&tbtree::getallentries);
}
};
extern "C"
Algebra*
InitializeTBTreeAlgebra( NestedList* nlRef, QueryProcessor* qpRef ) {
nl = nlRef;
qp = qpRef;
return (new TBTreeAlgebra);
}