1440 lines
37 KiB
C++
1440 lines
37 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
|
|
----
|
|
|
|
//paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}]
|
|
//paragraph [10] Footnote: [{\footnote{] [}}]
|
|
//[->] [$\rightarrow$]
|
|
//[TOC] [\tableofcontents]
|
|
//[_] [\_]
|
|
|
|
FileIndexAlgebra
|
|
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include "Algebra.h"
|
|
#include "NestedList.h"
|
|
#include "QueryProcessor.h"
|
|
#include "SecondoSystem.h"
|
|
#include "Attribute.h"
|
|
#include "Symbols.h"
|
|
#include "Algebras/TupleIdentifier/TupleIdentifier.h"
|
|
#include "StandardTypes.h"
|
|
#include "Algebras/Spatial/SpatialAlgebra.h"
|
|
#include "ListUtils.h"
|
|
#include "Stream.h"
|
|
#include "Algebras/Rectangle/RectangleAlgebra.h"
|
|
#include "Algebras/FText/FTextAlgebra.h"
|
|
#include "Algebras/TupleIdentifier/TupleIdentifier.h"
|
|
#include "Algebras/MMRTree/MMRTreeAlgebra.h"
|
|
#include "MMRTree.h"
|
|
#include "RTreeNode.h"
|
|
#include "RTree.h"
|
|
#include "RTreeIterator.h"
|
|
#include "Algebras/Spatial/SpatialAlgebra.h"
|
|
#include <fstream>
|
|
#include "Cache/LruCache.h"
|
|
#include "BPTree/BPTreeOperators.h"
|
|
#include <stdexcept>
|
|
|
|
extern NestedList* nl;
|
|
extern QueryProcessor* qp;
|
|
extern AlgebraManager *am;
|
|
|
|
using listutils::isTupleStream;
|
|
using std::exception;
|
|
|
|
using namespace std;
|
|
|
|
namespace fialgebra {
|
|
|
|
// detects dimension of a tree
|
|
// stored in a file
|
|
int checkDimension(const char* fileName){
|
|
ifstream stream(fileName, ifstream::binary | ifstream::ate);
|
|
if ( !stream.good() ) {
|
|
stream.close();
|
|
throw runtime_error( "File couldn't be opened: " + string(fileName) );
|
|
}
|
|
else {
|
|
size_t pageSize = WinUnix::getPageSize(),
|
|
length = min<size_t>(pageSize, stream.tellg());
|
|
|
|
stream.seekg(0, ios::beg);
|
|
|
|
char* bytes = new char[length];
|
|
|
|
stream.read( bytes, length );
|
|
stream.close();
|
|
|
|
RTreeHeader* header = new RTreeHeader(bytes, length, pageSize, 1);
|
|
size_t dimension = header->GetDimension();
|
|
delete header;
|
|
|
|
return (int)dimension;
|
|
} // else
|
|
}
|
|
|
|
|
|
/* supporting function: Checks the header
|
|
* of an RTree.
|
|
* */
|
|
|
|
|
|
template<int dim>
|
|
bool checkHeader(string& fileName, string& errMsg){
|
|
errMsg ="";
|
|
|
|
/* open function also checks whether this is
|
|
* a valid rtree which has been passed in the file*/
|
|
|
|
RTree<dim>* rt1 = RTree<dim>::Open(fileName.c_str(), 1);
|
|
size_t rootId = 0;
|
|
|
|
|
|
rootId = rt1->GetHeader()->GetRoot();
|
|
|
|
delete rt1;
|
|
|
|
// Wenn die RootNode-ID 0 ist, ist der Baum leer
|
|
if ( rootId == 0 ){
|
|
errMsg= "RTree is empty" ;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
There are no attributes in this algebra
|
|
|
|
Operators implementation
|
|
|
|
TypeMapping Functions
|
|
|
|
operator ~fwindowintersects~
|
|
|
|
*/
|
|
|
|
|
|
ListExpr fWindowIntersectTM(ListExpr args){
|
|
// args: ((text 'ix_rtree.bin') (rect (rect (1 1 1 1))))
|
|
|
|
//check number of arguments
|
|
if (!nl->HasLength(args, 2))
|
|
return listutils::typeError("wrong number of aruments");
|
|
|
|
|
|
ListExpr fileArg = nl->First(args);
|
|
//the list is coded as (<type> <query part>)
|
|
if(!nl->HasLength(fileArg, 2)){
|
|
return listutils::typeError("internal error");
|
|
}
|
|
//first arguments must be of a type string or text
|
|
if (!CcString::checkType(nl->First(fileArg)) &&
|
|
!FText::checkType(nl->First(fileArg))){
|
|
return listutils::typeError("file name as argument expected");
|
|
}
|
|
|
|
ListExpr fn = nl->Second(fileArg);
|
|
if(!((nl->AtomType(fn) == TextType)
|
|
|| (nl->AtomType(fn) == StringType))){
|
|
return listutils::typeError("file name not constant");
|
|
}
|
|
|
|
// read file name
|
|
string fileName;
|
|
if(nl->AtomType(fn) == TextType){
|
|
fileName = nl->Text2String(fn);
|
|
}
|
|
if(nl->AtomType(fn) == StringType){
|
|
fileName = nl->StringValue(fn);
|
|
}
|
|
|
|
//second arguments must be of a type
|
|
//Rectangle<dim> (dim={1, 2, 3, 4, 8})
|
|
//or SPATIAL2D or SPATIAL3D
|
|
ListExpr argRect = nl->Second(args);
|
|
bool ok = false;
|
|
string errMsg;
|
|
|
|
if (listutils::isKind(nl->First(argRect), Kind::SPATIAL1D())){
|
|
ok = checkHeader<1>(fileName, errMsg);
|
|
}
|
|
if (listutils::isKind(nl->First(argRect), Kind::SPATIAL2D())){
|
|
ok = checkHeader<2>(fileName, errMsg);
|
|
}
|
|
if (listutils::isKind(nl->First(argRect), Kind::SPATIAL3D())){
|
|
ok = checkHeader<3>(fileName, errMsg);
|
|
}
|
|
if (listutils::isKind(nl->First(argRect), Kind::SPATIAL4D())){
|
|
ok = checkHeader<4>(fileName, errMsg);
|
|
}
|
|
if (listutils::isKind(nl->First(argRect), Kind::SPATIAL8D())){
|
|
ok = checkHeader<8>(fileName, errMsg);
|
|
}
|
|
|
|
if(!ok){
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
return nl->TwoElemList(
|
|
listutils::basicSymbol<Stream<TupleIdentifier> >(),
|
|
listutils::basicSymbol<TupleIdentifier>() );
|
|
}
|
|
|
|
|
|
/*
|
|
Operator createfrtree
|
|
|
|
*/
|
|
|
|
ListExpr createfrtreeTM(ListExpr args){
|
|
string err = "stream(Tuple(X)) x string x a_i1 x a_i2 x int expected";
|
|
|
|
if(!nl->HasLength(args,5)){
|
|
return listutils::typeError(err);
|
|
}
|
|
|
|
if (!Stream<Tuple>::checkType(nl->First(args))){
|
|
return listutils::typeError("Error in first argument."
|
|
"Stream of tuples expected.");
|
|
}
|
|
|
|
if (!CcString::checkType(nl->Second(args)) &&
|
|
!FText::checkType(nl->Second(args)))
|
|
return listutils::typeError("Error in second argument. "
|
|
"string or text expected.");
|
|
|
|
if(!listutils::isSymbol(nl->Third(args))){
|
|
return listutils::typeError("Error in third argument. "
|
|
"Attribute name expected.");
|
|
}
|
|
|
|
if(!listutils::isSymbol(nl->Fourth(args))){
|
|
return listutils::typeError("Error in fourth argument. "
|
|
"Attribute name expected");
|
|
}
|
|
|
|
if(!CcInt::checkType(nl->Fifth(args))){
|
|
return listutils::typeError("Error in fifth argument. "
|
|
"int as argument expected.");
|
|
}
|
|
|
|
string name1 = nl->SymbolValue(nl->Third(args));
|
|
ListExpr attrList = nl->Second(nl->Second(nl->First(args)));
|
|
ListExpr type1;
|
|
int index1 = listutils::findAttribute(attrList, name1, type1);
|
|
if(index1==0){
|
|
return listutils::typeError("Attribute " + name1 + " unknown in tuple");
|
|
}
|
|
|
|
if(!listutils::isKind(type1, Kind::SPATIAL1D())
|
|
&& !listutils::isKind(type1, Kind::SPATIAL2D())
|
|
&& !listutils::isKind(type1, Kind::SPATIAL3D())
|
|
&& !listutils::isKind(type1, Kind::SPATIAL4D())
|
|
&& !listutils::isKind(type1, Kind::SPATIAL8D()))
|
|
{
|
|
return listutils::typeError("Attribute " + name1 + " not of kind" +
|
|
"SPATIAL1D, SPATIAL2D, SPATIAL3D, SPATIAL4D " +
|
|
"or SPATIAL8D");
|
|
}
|
|
|
|
string name2 = nl->SymbolValue(nl->Fourth(args));
|
|
ListExpr type2;
|
|
int index2 = listutils::findAttribute(attrList, name2, type2);
|
|
if(index2==0){
|
|
return listutils::typeError("Attribute " + name2 + " unknown in tuple");
|
|
}
|
|
if(!TupleIdentifier::checkType(type2) ){
|
|
return listutils::typeError("Attribute " + name2 +
|
|
" not of type " + TupleIdentifier::BasicType());
|
|
}
|
|
|
|
return nl->ThreeElemList(nl->SymbolAtom(Symbols::APPEND()),
|
|
nl->TwoElemList(nl->IntAtom(index1 - 1),
|
|
nl->IntAtom(index2 - 1)),
|
|
nl->First(args));
|
|
}
|
|
|
|
//end of TM for Operator createfrtree//////////
|
|
|
|
|
|
|
|
//Operator: insertfrtree///////////////////////
|
|
|
|
ListExpr InsertfrtreeTM(ListExpr args){
|
|
NList type(args);
|
|
if (!type.hasLength(4))
|
|
{
|
|
return NList::typeError("Expecting four arguments.");
|
|
}
|
|
|
|
NList streamType = type.first().first();
|
|
if (!isTupleStream(streamType.listExpr()))
|
|
{
|
|
return NList::typeError("Error in first argument! "
|
|
"Stream of tuples expected.");
|
|
}
|
|
|
|
NList pathType = type.second().first();
|
|
bool isPathText;
|
|
if (CcString::checkType(pathType.listExpr()))
|
|
{
|
|
isPathText = false;
|
|
}
|
|
else if (FText::checkType(pathType.listExpr()))
|
|
{
|
|
isPathText = true;
|
|
}
|
|
else
|
|
{
|
|
return NList::typeError("Error in second argument! "
|
|
"String or text expected!");
|
|
}
|
|
|
|
NList indexAttrNameType = type.third().first();
|
|
if (!indexAttrNameType.isSymbol())
|
|
{
|
|
return NList::typeError("Error in third argument! "
|
|
"Attribute name expected. "
|
|
"Perhaps the attribute's name may be the name "
|
|
"of a Secondo object!");
|
|
}
|
|
string indexAttrName = indexAttrNameType.str();
|
|
|
|
ListExpr attributeList = streamType.second().second().listExpr(),
|
|
attrType = nl->Empty();
|
|
|
|
int indexAttrIndex = FindAttribute(attributeList, indexAttrName, attrType);
|
|
indexAttrIndex--;
|
|
if (indexAttrIndex < 0)
|
|
{
|
|
return NList::typeError("Error in third argument!"
|
|
"Attribute name '" + indexAttrName +
|
|
"' not found!");
|
|
}
|
|
|
|
|
|
|
|
NList idAttrNameType = type.fourth().first();
|
|
if (!idAttrNameType.isSymbol())
|
|
{
|
|
return NList::typeError("Error in fourth argument! "
|
|
"Attribute name expected. "
|
|
"Perhaps the attribute's name may be the name "
|
|
"of a Secondo object!");
|
|
}
|
|
string idAttrName = idAttrNameType.str();
|
|
attrType = nl->Empty();
|
|
|
|
int idAttrIndex = FindAttribute(attributeList, idAttrName, attrType);
|
|
idAttrIndex--;
|
|
if (idAttrIndex < 0)
|
|
{
|
|
return NList::typeError("Error in fourth argument!"
|
|
"Attribute name '" + indexAttrName +
|
|
"' not found!");
|
|
}
|
|
|
|
string path = type.second().second().str();
|
|
char* pathCopy = new char[path.length() + 1];
|
|
memcpy(pathCopy, path.c_str(), path.length() + 1);
|
|
delete [] pathCopy;
|
|
|
|
return NList(NList(Symbol::APPEND()),
|
|
NList(NList(isPathText),
|
|
NList(indexAttrIndex),
|
|
NList(idAttrIndex)),
|
|
streamType).listExpr();
|
|
}
|
|
|
|
//end of TM for Operator insertfrtree//////
|
|
|
|
//Operator deletefrtree/////////////////////////////////////////////////////
|
|
ListExpr deletefrtreeTM(ListExpr args){
|
|
//identical to insertfrtree
|
|
return InsertfrtreeTM(args);
|
|
}
|
|
//end of TM for Operator deletefrtree//////////
|
|
|
|
// TM for frebuildtree //////////////////
|
|
|
|
|
|
ListExpr rebuildfrtreeTM( ListExpr args )
|
|
{
|
|
string dat1;
|
|
string dat2;
|
|
string err = "string/text x string/text";
|
|
if (!nl->HasLength( args, 2 )) {
|
|
return listutils::typeError(err + ": wrong number of arguments");
|
|
}
|
|
ListExpr arg1 = nl->First(args);
|
|
ListExpr arg2 = nl->Second(args);
|
|
// Check first argument (name of source file)
|
|
//if ( !( CcString::checkType(args.first().first())
|
|
if ( !( CcString::checkType(nl->First(arg1))
|
|
|| FText::checkType(nl->First(arg1)))) {
|
|
return NList::typeError(err + ": First argument is not string or text!");
|
|
}
|
|
if ( !( nl -> AtomType(nl->Second(arg1)) == StringType
|
|
|| nl -> AtomType(nl->Second(arg1)) == TextType) ) {
|
|
return NList::typeError(err + ": First argument is not string or text!");
|
|
}
|
|
if ( nl -> AtomType(nl->Second(arg1)) == StringType ) {
|
|
dat1 = nl->StringValue(nl->Second(arg1));
|
|
}
|
|
if ( nl -> AtomType(nl->Second(arg1)) == TextType ) {
|
|
dat1 = nl->Text2String(nl->Second(arg1));
|
|
}
|
|
|
|
/*
|
|
if (dat1.substr(dat1.size()-5, 4) != ".bin") {
|
|
return NList::typeError(err + ": First argument hasn't extension .bin!");
|
|
}
|
|
*/
|
|
// Check if source file exists and can be opened
|
|
std::ifstream file01;
|
|
file01.open(dat1.c_str());
|
|
if (!file01) {
|
|
return NList::typeError(err + ": First file couldn't be opened!");
|
|
} else {
|
|
file01.close();
|
|
}
|
|
|
|
// Check if source file contains R-Tree
|
|
// creation of a dummy tree with dim = 1
|
|
/* RTree<1>* r1 = RTree<1>::OpenRebuild(dat1.c_str(), 50);
|
|
if ((r1->GetHeader())->GetMarker() != '1') {
|
|
return NList::typeError(err + ": First file doesn't contain an R-Tree!");
|
|
}
|
|
delete r1;*/
|
|
|
|
|
|
/* Check dimension of the RTree
|
|
* contained in the file that was passed.
|
|
If the file does not contain an RTree
|
|
an error message will be returned*/
|
|
const char * c = dat1.c_str();
|
|
int dim = checkDimension(c);
|
|
|
|
|
|
/* If the first file contains an RTree we will need
|
|
* to check whether its dimension is actually
|
|
* covered*/
|
|
if (dim < 1 || dim > 8) {
|
|
return NList::typeError
|
|
(err + ": First file doesn't contain a valid R-Tree!");
|
|
}
|
|
|
|
if (dim == 5 || dim == 6 || dim == 7) {
|
|
return NList::typeError
|
|
(err + ": First file doesn't contain a valid R-Tree!");
|
|
}
|
|
|
|
|
|
// Check second argument (name of target file)
|
|
if ( !( CcString::checkType(nl->First(arg2))
|
|
|| FText::checkType(nl->First(arg2)))) {
|
|
return NList::typeError(err + ": Second argument is not string or text!");
|
|
}
|
|
if ( !( nl -> AtomType(nl->Second(arg2)) == StringType
|
|
|| nl -> AtomType(nl->Second(arg2)) == TextType) ) {
|
|
return NList::typeError(err + ": Second argument is not string or text!");
|
|
}
|
|
if ( nl -> AtomType(nl->Second(arg2)) == StringType ) {
|
|
// dat2 = nl->SymbolValue(nl->Second(arg2));
|
|
dat2 = nl->StringValue(nl->Second(arg2));
|
|
}
|
|
if ( nl -> AtomType(nl->Second(arg2)) == TextType ) {
|
|
dat2 = nl->Text2String(nl->Second(arg2));
|
|
}
|
|
/*
|
|
if (dat2.substr(dat2.size()-5, 4) != ".bin") {
|
|
return NList::typeError(err + ": Second argument hasn't extension .bin!");
|
|
}
|
|
*/
|
|
ListExpr resType = listutils::basicSymbol<CcBool>();
|
|
|
|
|
|
return nl->ThreeElemList( nl->SymbolAtom(Symbol::APPEND()),
|
|
nl->TwoElemList(nl->TextAtom(dat1), nl->TextAtom(dat2)), resType );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//end of TM for Operator rebuildfrtree////////
|
|
|
|
|
|
// 2. ValueMapping
|
|
|
|
/*
|
|
Operator ~fwindowintersect~
|
|
|
|
*/
|
|
template <int dim>
|
|
int fWindowIntersectValMap ( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
//define RTreeIterator*
|
|
//it will used as localInfo-class
|
|
RTreeIterator<dim>* rti = (RTreeIterator <dim>*)local.addr;
|
|
|
|
switch (message) {
|
|
case OPEN:{
|
|
if (rti) delete rti;
|
|
|
|
//read file
|
|
string fileName = ((Attribute*)args[0].addr)->toText();
|
|
|
|
StandardSpatialAttribute<dim>* arg
|
|
= (StandardSpatialAttribute<dim>*) args[1].addr;
|
|
|
|
Rectangle<dim> rectArg = arg->BoundingBox();
|
|
|
|
//create R-Tree and Iterator
|
|
RTree<dim>* rtree = RTree<dim>::Open(fileName.c_str(), 0);
|
|
rti = new RTreeIterator<dim>(rtree, rectArg);
|
|
local.addr = rti;
|
|
|
|
return 0;
|
|
}// end of OPEN
|
|
|
|
case REQUEST:{
|
|
size_t id = rti->Search();
|
|
|
|
if (id != 0){
|
|
//Falls Suche noch nicht zu Ende ist
|
|
TupleIdentifier* tid = new TupleIdentifier( true, id );
|
|
result.addr = tid;
|
|
return YIELD;
|
|
}
|
|
else{
|
|
//Ende des Baums erreicht
|
|
result.addr = 0;
|
|
return CANCEL;
|
|
}
|
|
}//end of REQUEST
|
|
|
|
case CLOSE:{
|
|
if (rti){
|
|
delete rti;
|
|
local.addr = 0;
|
|
}
|
|
return 0;
|
|
}//end of CLOSE
|
|
}//end of switch(message)
|
|
//should never happen
|
|
return -1;
|
|
}
|
|
|
|
//ValueMapping function: createfrtree
|
|
|
|
template <int dim>
|
|
int createfrtreeValMap ( Word* args, Word& result, int message,
|
|
Word& local, Supplier s )
|
|
{
|
|
Stream<Tuple> stream(args[0]);
|
|
|
|
switch (message) {
|
|
case OPEN:{
|
|
// writing the file for the RTree
|
|
string filename = ((Attribute*)args[1].addr)->toText();
|
|
int min = ((CcInt*)args[4].addr)->GetValue();
|
|
|
|
try{
|
|
local.addr = RTree<dim>::Create(filename.c_str(), 512, min);
|
|
}
|
|
catch (exception& e){
|
|
cerr << "Creation failed: " << e.what() << '\n';
|
|
return CANCEL;
|
|
}
|
|
|
|
qp->Open(args[0].addr);
|
|
break;
|
|
}
|
|
case REQUEST:{
|
|
if (local.addr != NULL){
|
|
Word tupleWord(Address(NULL));
|
|
qp->Request(args[0].addr, tupleWord);
|
|
|
|
if(qp->Received(args[0].addr)){
|
|
int index1 = ((CcInt*)args[5].addr)->GetValue(),
|
|
index2 = ((CcInt*) args[6].addr)->GetValue();
|
|
|
|
Tuple* tuple = (Tuple*)tupleWord.addr;
|
|
|
|
StandardSpatialAttribute<dim>* value =
|
|
(StandardSpatialAttribute<dim>*)tuple->GetAttribute(index1);
|
|
|
|
TupleIdentifier* id = (TupleIdentifier*)tuple->GetAttribute(index2);
|
|
|
|
try{
|
|
((RTree<dim>*)local.addr)->Insert(value->BoundingBox(),
|
|
(size_t)id->GetTid());
|
|
}
|
|
catch(exception& e){
|
|
cerr << "Insertion failed: " << e.what() << '\n';
|
|
}
|
|
|
|
result = tupleWord;
|
|
return YIELD;
|
|
}
|
|
}
|
|
|
|
result.addr = NULL;
|
|
return CANCEL;
|
|
}
|
|
case CLOSE:{
|
|
qp->Close(args[0].addr);
|
|
|
|
if (local.addr != NULL){
|
|
|
|
delete((RTree<dim>*)local.addr);
|
|
local.addr = NULL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// end of VM function for createfrtree //////////////////////////////////
|
|
|
|
|
|
|
|
// Value Mapping function for insertfrtree /////////////////////////////
|
|
|
|
template <int dim>
|
|
int insertfrtreeValMap(Word* args, Word& result, int message, Word& local,
|
|
Supplier s)
|
|
{
|
|
Stream<Tuple> stream(args[0]);
|
|
|
|
switch (message) {
|
|
case OPEN:{
|
|
string filename = ((Attribute*)args[1].addr)->toText();
|
|
|
|
try{
|
|
local.addr = RTree<dim>::Open(filename.c_str(), 50);
|
|
}
|
|
catch (exception& e){
|
|
cerr << "Opening failed: " << e.what() << '\n';
|
|
return CANCEL;
|
|
}
|
|
|
|
qp->Open(args[0].addr);
|
|
break;
|
|
}
|
|
case REQUEST:{
|
|
if (local.addr != NULL){
|
|
Word tupleWord(Address(NULL));
|
|
qp->Request(args[0].addr, tupleWord);
|
|
|
|
if(qp->Received(args[0].addr)){
|
|
int index1 = ((CcInt*)args[5].addr)->GetValue(),
|
|
index2 = ((CcInt*) args[6].addr)->GetValue();
|
|
|
|
Tuple* tuple = (Tuple*)tupleWord.addr;
|
|
|
|
StandardSpatialAttribute<dim>* value =
|
|
(StandardSpatialAttribute<dim>*)tuple->GetAttribute(index1);
|
|
|
|
TupleIdentifier* id = (TupleIdentifier*)tuple->GetAttribute(index2);
|
|
|
|
try{
|
|
((RTree<dim>*)local.addr)->Insert(value->BoundingBox(),
|
|
(size_t)id->GetTid());
|
|
}
|
|
catch(exception& e){
|
|
cerr << "Insertion failed: " << e.what() << '\n';
|
|
}
|
|
|
|
//cout << ((RTree<dim>*)local.addr)->ToString() << '\n';
|
|
|
|
result = tupleWord;
|
|
return YIELD;
|
|
}
|
|
}
|
|
|
|
result.addr = NULL;
|
|
return CANCEL;
|
|
}
|
|
case CLOSE:{
|
|
qp->Close(args[0].addr);
|
|
|
|
if (local.addr != NULL){
|
|
delete((RTree<dim>*)local.addr);
|
|
local.addr = NULL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// end of VM function for insertfrtree //////////////////////////////////
|
|
|
|
// Value Mapping function for deletefrtree /////////////////////////////
|
|
template <int dim>
|
|
int deletefrtreeValMap(Word* args, Word& result, int message, Word& local,
|
|
Supplier s)
|
|
{
|
|
Stream<Tuple> stream(args[0]);
|
|
|
|
switch (message) {
|
|
case OPEN:{
|
|
string filename = ((Attribute*)args[1].addr)->toText();
|
|
|
|
try{
|
|
local.addr = RTree<dim>::Open(filename.c_str(), 512);
|
|
}
|
|
catch (exception& e){
|
|
cerr << "Opening failed: " << e.what() << '\n';
|
|
return CANCEL;
|
|
}
|
|
|
|
qp->Open(args[0].addr);
|
|
break;
|
|
}
|
|
case REQUEST:{
|
|
if (local.addr != NULL){
|
|
Word tupleWord(Address(NULL));
|
|
qp->Request(args[0].addr, tupleWord);
|
|
|
|
if(qp->Received(args[0].addr)){
|
|
int index1 = ((CcInt*)args[5].addr)->GetValue(),
|
|
index2 = ((CcInt*) args[6].addr)->GetValue();
|
|
|
|
Tuple* tuple = (Tuple*)tupleWord.addr;
|
|
|
|
StandardSpatialAttribute<dim>* value =
|
|
(StandardSpatialAttribute<dim>*)tuple->GetAttribute(index1);
|
|
|
|
TupleIdentifier* id = (TupleIdentifier*)tuple->GetAttribute(index2);
|
|
|
|
try{
|
|
((RTree<dim>*)local.addr)->Delete(value->BoundingBox(),
|
|
(size_t)id->GetTid());
|
|
}
|
|
catch(exception& e){
|
|
cerr << "Deletion failed: " << e.what() << '\n';
|
|
}
|
|
|
|
//cout << ((RTree<dim>*)local.addr)->ToString() << '\n';
|
|
|
|
result = tupleWord;
|
|
return YIELD;
|
|
}
|
|
}
|
|
|
|
result.addr = NULL;
|
|
return CANCEL;
|
|
}
|
|
case CLOSE:{
|
|
qp->Close(args[0].addr);
|
|
|
|
if (local.addr != NULL){
|
|
delete((RTree<dim>*)local.addr);
|
|
local.addr = NULL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
// end of VM function for deletefrtree //////////////////////////////////
|
|
|
|
// Value Mapping for rebuildfrtree
|
|
|
|
int rebuildfrtreeValMap (Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
// Parameters 2 and 3 are delivered from the type mapping function
|
|
// in text format, params 0 and 1 can thus be neglected
|
|
FText* pre1 = (FText*) args[2].addr; // get the argument and cast it
|
|
FText* pre2 = (FText*) args[3].addr; // get the argument and cast it
|
|
// Cast file names to string (and later to char* for ctor)
|
|
string dat1 = (pre1->GetValue()).c_str();
|
|
string dat2 = (pre2->GetValue()).c_str();
|
|
|
|
const char * c = dat1.c_str();
|
|
|
|
int dim = checkDimension(c);
|
|
|
|
if (dim == 1){
|
|
RTree<1>* rtree = RTree<1>::Open(c, 512);
|
|
rtree->RebuildR(dat2.c_str());
|
|
delete rtree;
|
|
}
|
|
|
|
if (dim == 2){
|
|
RTree<2>* rtree = RTree<2>::Open(c, 512);
|
|
rtree->RebuildR(dat2.c_str());
|
|
delete rtree;
|
|
}
|
|
|
|
if (dim == 3){
|
|
RTree<3>* rtree = RTree<3>::Open(c, 512);
|
|
rtree->RebuildR(dat2.c_str());
|
|
delete rtree;
|
|
}
|
|
|
|
if (dim == 4){
|
|
RTree<4>* rtree = RTree<4>::Open(c, 512);
|
|
rtree->RebuildR(dat2.c_str());
|
|
delete rtree;
|
|
}
|
|
|
|
if (dim == 8){
|
|
RTree<8>* rtree = RTree<8>::Open(c, 512);
|
|
rtree->RebuildR(dat2.c_str());
|
|
delete rtree;
|
|
}
|
|
|
|
|
|
|
|
// rtree->RebuildR(dat2.c_str());
|
|
// delete rtree;
|
|
// Delete source file
|
|
//remove(dat1.c_str());
|
|
result = qp->ResultStorage(s); // use the result storage
|
|
CcBool* b = static_cast<CcBool*> (result.addr); // cast the result
|
|
b->Set(true, true); // compute and set the result
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
// end of VM for rebuldfrtree
|
|
|
|
|
|
// 4. Selection Function
|
|
|
|
/////////// createfrtree /////////////////////////////////////////
|
|
|
|
int createfrtreeSelect (ListExpr args){
|
|
//int index = nl->Sixth(args);
|
|
ListExpr attrList = nl->Second(nl->Second(nl->First(args)));
|
|
string name = nl->SymbolValue(nl->Third(args));
|
|
ListExpr type;
|
|
int index = listutils::findAttribute(attrList,name,type);
|
|
assert(index > 0);
|
|
|
|
//assert(index >0);
|
|
if(listutils::isKind(type, Kind::SPATIAL1D())){
|
|
return 0;
|
|
}
|
|
if(listutils::isKind(type, Kind::SPATIAL2D())){
|
|
return 1;
|
|
}
|
|
if(listutils::isKind(type, Kind::SPATIAL3D())){
|
|
return 2;
|
|
}
|
|
if(listutils::isKind(type, Kind::SPATIAL4D())){
|
|
return 3;
|
|
}
|
|
if(listutils::isKind(type, Kind::SPATIAL8D())){
|
|
return 4;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/////////// end of selection function for createfrtree //////////
|
|
|
|
|
|
// 5. Arrays for ValueMapping
|
|
|
|
|
|
/////////// createfrtree /////////////////////////////////////////
|
|
|
|
ValueMapping createfrtreeVM[] = {
|
|
createfrtreeValMap<1>,
|
|
createfrtreeValMap<2>,
|
|
createfrtreeValMap<3>,
|
|
createfrtreeValMap<4>,
|
|
createfrtreeValMap<8>
|
|
};
|
|
|
|
ValueMapping insertfrtreeVM[] = {
|
|
insertfrtreeValMap<1>,
|
|
insertfrtreeValMap<2>,
|
|
insertfrtreeValMap<3>,
|
|
insertfrtreeValMap<4>,
|
|
insertfrtreeValMap<8>
|
|
};
|
|
|
|
ValueMapping deletefrtreeVM[] = {
|
|
deletefrtreeValMap<1>,
|
|
deletefrtreeValMap<2>,
|
|
deletefrtreeValMap<3>,
|
|
deletefrtreeValMap<4>,
|
|
deletefrtreeValMap<8>
|
|
};
|
|
|
|
|
|
/////////// end of VM array for createfrtree ////////////////////
|
|
|
|
|
|
// 6. Operator Spec
|
|
|
|
OperatorSpec createfrtreeSpec(
|
|
"stream(tuple(X))x{txt,str}xIdxIdxint->stream(tpl(X))",
|
|
"createfrtree(_,_,_,_,_) ",
|
|
"creates an Rtree file",
|
|
"query createfrtree()"
|
|
);
|
|
|
|
OperatorSpec insertfrtreeSpec(
|
|
"stream(tuple(X))x{txt,str}xIdxId->stream(tpl(X))",
|
|
"insertfrtree(_,_,_,_) ",
|
|
"performs inserts into an Rtree file",
|
|
"query insertfrtree()"
|
|
);
|
|
|
|
OperatorSpec deletefrtreeSpec(
|
|
"stream(tuple(X))x{txt,str}xIdxId->stream(tpl(X))",
|
|
"deletefrtree(_,_,_,_) ",
|
|
"performs delete operations on a Rtree file",
|
|
"query deletefrtree()"
|
|
);
|
|
|
|
|
|
OperatorSpec rebuildfrtreeSpec(
|
|
"file{txt,str}xfile{txt,str}-> bool",
|
|
"rebuildfrtree(_,_) ",
|
|
"rebuilds an RTree and creates a new RTree file",
|
|
"query rebuildfrtree(oldfile.bin, newfile.bin )"
|
|
);
|
|
|
|
|
|
// 7. Operator Instance
|
|
|
|
Operator createfrtreeOp(
|
|
"createfrtree",
|
|
createfrtreeSpec.getStr(),
|
|
5,
|
|
createfrtreeVM,
|
|
createfrtreeSelect,
|
|
createfrtreeTM
|
|
);
|
|
|
|
Operator insertfrtreeOp(
|
|
"insertfrtree",
|
|
insertfrtreeSpec.getStr(),
|
|
5,
|
|
insertfrtreeVM,
|
|
createfrtreeSelect,
|
|
InsertfrtreeTM
|
|
);
|
|
|
|
|
|
Operator deletefrtreeOp(
|
|
"deletefrtree",
|
|
deletefrtreeSpec.getStr(),
|
|
5,
|
|
deletefrtreeVM,
|
|
createfrtreeSelect,
|
|
deletefrtreeTM
|
|
);
|
|
|
|
|
|
Operator rebuildfrtreeOp(
|
|
"rebuildfrtree",
|
|
rebuildfrtreeSpec.getStr(),
|
|
rebuildfrtreeValMap,
|
|
// createfrtreeSelect,
|
|
Operator::SimpleSelect,
|
|
rebuildfrtreeTM
|
|
);
|
|
|
|
|
|
OperatorSpec fWindowIntersectSpec(
|
|
"{txt, string}xR->stream(tid)",
|
|
"_fwindowintersects(_)",
|
|
"performs search in a Rtree index-file",
|
|
"query fwindowintersects['strassen_GeoData_rtree', rectan] count"
|
|
);
|
|
|
|
ValueMapping fWindowIntersectVMA[] = {
|
|
fWindowIntersectValMap<1>,
|
|
fWindowIntersectValMap<2>,
|
|
fWindowIntersectValMap<3>,
|
|
fWindowIntersectValMap<4>,
|
|
fWindowIntersectValMap<8>
|
|
};
|
|
|
|
int fWindowIntersectSelect (ListExpr args){
|
|
|
|
if(listutils::isKind(nl->Second(args), Kind::SPATIAL1D())){
|
|
return 0;
|
|
}
|
|
if (listutils::isKind(nl->Second(args), Kind::SPATIAL2D())){
|
|
return 1;
|
|
}
|
|
if(listutils::isKind(nl->Second(args), Kind::SPATIAL3D())){
|
|
return 2;
|
|
}
|
|
if(listutils::isKind(nl->Second(args), Kind::SPATIAL4D())){
|
|
return 3;
|
|
}
|
|
if(listutils::isKind(nl->Second(args), Kind::SPATIAL8D())){
|
|
return 4;
|
|
}
|
|
|
|
//should never be reached
|
|
return -1;
|
|
}
|
|
|
|
Operator fWindowIntersectOp(
|
|
"fwindowintersects",
|
|
fWindowIntersectSpec.getStr(),
|
|
5,
|
|
fWindowIntersectVMA,
|
|
fWindowIntersectSelect,
|
|
fWindowIntersectTM
|
|
);
|
|
|
|
|
|
|
|
//
|
|
// RTree Bulkload
|
|
//
|
|
// Value mapping select function
|
|
int bulkloadfrtreeSelect( ListExpr a ) {
|
|
|
|
// args:
|
|
// (
|
|
// (stream (tuple ((Rectangle rect) (TID tid))))
|
|
// text
|
|
// Rectangle
|
|
// TID
|
|
// int
|
|
// real
|
|
// )
|
|
|
|
NList args( a );
|
|
NList argStream = args.first();
|
|
NList argKeyName = args.third();
|
|
|
|
ListExpr attrList = argStream.second().second().listExpr();
|
|
string keyAttrName = argKeyName.str();
|
|
ListExpr keyAttrType = nl->Empty();
|
|
FindAttribute( attrList, keyAttrName, keyAttrType );
|
|
|
|
int res = -1;
|
|
if ( listutils::isKind( keyAttrType, Kind::SPATIAL1D() ) )
|
|
res = 0;
|
|
else if ( listutils::isKind( keyAttrType, Kind::SPATIAL2D() ) )
|
|
res = 1;
|
|
else if ( listutils::isKind( keyAttrType, Kind::SPATIAL3D() ) )
|
|
res = 2;
|
|
else if ( listutils::isKind( keyAttrType, Kind::SPATIAL4D() ) )
|
|
res = 3;
|
|
else if ( listutils::isKind( keyAttrType, Kind::SPATIAL8D() ) )
|
|
res = 4;
|
|
|
|
return res;
|
|
}
|
|
//
|
|
// Type mapping
|
|
ListExpr bulkloadfrtreeTM( ListExpr args ) {
|
|
|
|
// args:
|
|
// (
|
|
// ((stream (tuple ((Rectangle rect) (TID tid)))) (feed tmp1_tid))
|
|
// (text 'ix_rtree.bin')
|
|
// (Rectangle Rectangle)
|
|
// (TID TID)
|
|
// (int 2)
|
|
// (int 0)
|
|
// )
|
|
|
|
// log
|
|
//cout << "bulkloadfrtreeTM( " << nl->ToString( args ) << " )" << endl;
|
|
|
|
NList type( args );
|
|
|
|
// Do some checks
|
|
//
|
|
// Length check
|
|
if ( !type.hasLength( 6 ) )
|
|
return NList::typeError( "Expecting six arguments" );
|
|
|
|
// 1: Stream
|
|
NList argStream = type.first();
|
|
// 2: File
|
|
NList argFile = type.second();
|
|
// 3: Key-Type
|
|
NList argKeyName = type.third();
|
|
// 4: TID
|
|
NList argTidName = type.fourth();
|
|
// 5: Int - Min. fill
|
|
NList argMinFill = type.fifth();
|
|
// 6: Int - Max. distance
|
|
NList argMaxDist = type.sixth();
|
|
|
|
// Length
|
|
if ( !argStream.hasLength( 2 ) ||
|
|
!argFile.hasLength( 2 ) ||
|
|
!argKeyName.hasLength( 2 ) ||
|
|
!argTidName.hasLength( 2 ) ||
|
|
!argMinFill.hasLength( 2 ) ||
|
|
!argMaxDist.hasLength( 2 ) )
|
|
return NList::typeError( "internal error" );
|
|
|
|
// Type checks
|
|
if ( !Stream<Tuple>::checkType( argStream.first().listExpr() ) )
|
|
return NList::typeError( "Stream of tuples expected" );
|
|
//
|
|
if ( !CcString::checkType( argFile.first().listExpr() ) &&
|
|
!FText::checkType( argFile.first().listExpr() ) )
|
|
return NList::typeError( "String or Text in first argument expected" );
|
|
//
|
|
if ( !CcInt::checkType( argMinFill.first().listExpr() ) )
|
|
return NList::typeError( "Integer in fourth argument expected" );
|
|
//
|
|
if ( !CcReal::checkType( argMaxDist.first().listExpr() ) )
|
|
return NList::typeError( "Real in fifth argument expected" );
|
|
//
|
|
// Check attributes
|
|
//
|
|
if ( !argKeyName.first().isSymbol() )
|
|
return NList::typeError( "Attribute name in second argument expected" );
|
|
if ( !argTidName.first().isSymbol() )
|
|
return NList::typeError( "Attribute name in third argument expected" );
|
|
|
|
ListExpr attrList = argStream.first().second().second().listExpr();
|
|
// Key
|
|
string keyAttrName = argKeyName.first().str();
|
|
ListExpr keyAttrType = nl->Empty();
|
|
int keyAttrIndex = FindAttribute( attrList, keyAttrName, keyAttrType );
|
|
if ( keyAttrIndex <= 0 )
|
|
NList::typeError( "Attribute name '" + keyAttrName + "' not found" );
|
|
// TID
|
|
string tidAttrName = argTidName.first().str();
|
|
ListExpr tidAttrType = nl->Empty();
|
|
int tidAttrIndex = FindAttribute( attrList, tidAttrName, tidAttrType );
|
|
if ( tidAttrIndex <= 0 )
|
|
NList::typeError( "Attribute name '" + tidAttrName + "' not found" );
|
|
//
|
|
// Check attribute types
|
|
if ( !TupleIdentifier::checkType( tidAttrType ) )
|
|
return NList::typeError( "Attribute '" + tidAttrName +
|
|
"' is no TupleIdentifier" );
|
|
if ( !listutils::isKind( keyAttrType, Kind::SPATIAL1D() ) &&
|
|
!listutils::isKind( keyAttrType, Kind::SPATIAL2D() ) &&
|
|
!listutils::isKind( keyAttrType, Kind::SPATIAL3D() ) &&
|
|
!listutils::isKind( keyAttrType, Kind::SPATIAL4D() ) &&
|
|
!listutils::isKind( keyAttrType, Kind::SPATIAL8D() ) )
|
|
return NList::typeError( "Attribute '" + keyAttrName +
|
|
"' is not of kind SPATIAL1D, SPATIAL2D, SPATIAL3D, "
|
|
"SPATIAL3D or SPATIAL8D" );
|
|
|
|
//
|
|
// check file for existance
|
|
string indexFile = argFile.second().str();
|
|
ifstream f( indexFile.c_str() );
|
|
if ( f.good() ) {
|
|
f.close();
|
|
return NList::typeError( "File '" + indexFile + "' already exists" );
|
|
} else { f.close(); }
|
|
|
|
// Result
|
|
NList append;
|
|
// (i i)
|
|
append.append( nl->IntAtom( keyAttrIndex - 1 ) );
|
|
append.append( nl->IntAtom( tidAttrIndex - 1 ) );
|
|
//
|
|
ListExpr res = NList(
|
|
// (APPEND)
|
|
NList( Symbol::APPEND() ),
|
|
// append
|
|
append,
|
|
// (stream(tupel(..)))
|
|
argStream.first()
|
|
).listExpr();
|
|
|
|
return res;
|
|
}
|
|
//
|
|
// Value mapping function
|
|
template<int dim>
|
|
int bulkloadfrtreeVM( Word* args, Word& result,
|
|
int message, Word& local, Supplier s ) {
|
|
|
|
// args
|
|
// 0 : stream(tuple( .. ))
|
|
// 1 : text - Filename
|
|
// 2 : Symbol - Key Attribute Name
|
|
// 3 : Symbol - TID Attribute Name
|
|
// 4 : int - Min. filling
|
|
// 5 : real - Max. distance
|
|
// 6 : int - Key Attribute Index
|
|
// 7 : int - TID Attr Index
|
|
|
|
RTree<dim>* tree = static_cast<RTree<dim>*>( local.addr );
|
|
|
|
switch( message ) {
|
|
case OPEN: {
|
|
if ( tree != 0 ) delete tree;
|
|
|
|
string indexFile = ((Attribute*)args[1].addr)->toText();
|
|
int minFilling = StdTypes::GetInt( args[4].addr );
|
|
CcReal* maxDistanceAttr = static_cast<CcReal*>( args[5].addr );
|
|
|
|
double maxDistance = maxDistanceAttr->IsDefined() ?
|
|
maxDistanceAttr->GetValue() : 0.0;
|
|
|
|
if ( minFilling < 0 )
|
|
minFilling = 0;
|
|
|
|
// Create tree and start bulkload process
|
|
try {
|
|
tree = RTree<dim>::Create( indexFile.c_str(), 1024, minFilling );
|
|
tree->BeginBulkload( maxDistance );
|
|
local.addr = tree;
|
|
}
|
|
catch( exception& ex ) {
|
|
cerr << "Creation failed: " << ex.what() << endl;
|
|
return CANCEL;
|
|
} // catch
|
|
|
|
// Open stream
|
|
qp->Open( args[0].addr );
|
|
return 0;
|
|
} // case OPEN
|
|
case REQUEST: {
|
|
if ( local.addr == 0 ) return CANCEL;
|
|
|
|
// Request next element in stream
|
|
Word tupleWord( Address( NULL ) );
|
|
qp->Request( args[0].addr, tupleWord );
|
|
|
|
if ( qp->Received( args[0].addr ) ) {
|
|
Tuple* tuple = (Tuple*)tupleWord.addr;
|
|
|
|
int keyAttrIndex = StdTypes::GetInt( args[6].addr );
|
|
int tidAttrIndex = StdTypes::GetInt( args[7].addr );
|
|
|
|
Attribute* keyAttr = tuple->GetAttribute( keyAttrIndex );
|
|
StandardSpatialAttribute<dim>* key =
|
|
(StandardSpatialAttribute<dim>*)keyAttr;
|
|
|
|
TupleIdentifier* tidAttr =
|
|
(TupleIdentifier*)tuple->GetAttribute( tidAttrIndex );
|
|
TupleId tid = tidAttr->GetTid();
|
|
|
|
try {
|
|
tree->Bulkload( key->BoundingBox(), (size_t)tid );
|
|
}
|
|
catch( exception& ex ) {
|
|
cerr << "Bulkload error: " << ex.what() << endl;
|
|
return CANCEL;
|
|
} // catch
|
|
|
|
result.setAddr( tupleWord.addr );
|
|
return YIELD;
|
|
}
|
|
else {
|
|
// End of stream reached
|
|
result.addr = NULL;
|
|
return CANCEL;
|
|
} // else
|
|
} // case REQUEST
|
|
case CLOSE: {
|
|
// close stream
|
|
qp->Close( args[0].addr );
|
|
|
|
if ( local.addr != 0 ) {
|
|
// End bulkload, cleanup
|
|
tree->EndBulkload();
|
|
|
|
// log
|
|
//cout << tree->ToString() << endl;
|
|
|
|
delete tree;
|
|
local.addr = NULL;
|
|
} // if
|
|
|
|
return 0;
|
|
} // case CLOSE;
|
|
default: {
|
|
// should never happen
|
|
return -1;
|
|
} // default;
|
|
} // switch
|
|
}
|
|
//
|
|
// Value mapping array
|
|
ValueMapping bulkloadfrtreeVMA[] = {
|
|
bulkloadfrtreeVM<1>,
|
|
bulkloadfrtreeVM<2>,
|
|
bulkloadfrtreeVM<3>,
|
|
bulkloadfrtreeVM<4>,
|
|
bulkloadfrtreeVM<8>
|
|
};
|
|
//
|
|
// OperatorSpecs
|
|
OperatorSpec bulkloadfrtreeOperatorSpec(
|
|
"stream( tuple( X ) ) x {text, string} x Ident x"
|
|
"Ident x int x real -> stream( tuple( X ) )",
|
|
"_ bulkloadfrtree [_, _, _, _, _]",
|
|
"creates a file based R-Tree index with bulkload",
|
|
"query buildings feed addid bulkloadfrtree"
|
|
"['index.bin', Rect, TID, 10, 5.0] count"
|
|
);
|
|
//
|
|
// Operators
|
|
Operator bulkloadfrtreeOp(
|
|
"bulkloadfrtree",
|
|
bulkloadfrtreeOperatorSpec.getStr(),
|
|
5,
|
|
bulkloadfrtreeVMA, // value mapping array
|
|
bulkloadfrtreeSelect, // select function
|
|
bulkloadfrtreeTM // type mapping
|
|
);
|
|
|
|
|
|
/*
|
|
Definition of the algebra
|
|
|
|
*/
|
|
class FileIndexAlgebra : public Algebra{
|
|
public:
|
|
FileIndexAlgebra() : Algebra(){
|
|
|
|
//AddOperator (&ftestOp);
|
|
//AddOperator (&ftestOp);
|
|
AddOperator (&createfrtreeOp);
|
|
createfrtreeOp.SetUsesMemory();
|
|
AddOperator (&fWindowIntersectOp);
|
|
fWindowIntersectOp.SetUsesMemory();
|
|
fWindowIntersectOp.SetUsesArgsInTypeMapping();
|
|
AddOperator (&rebuildfrtreeOp);
|
|
rebuildfrtreeOp.SetUsesMemory();
|
|
rebuildfrtreeOp.SetUsesArgsInTypeMapping();
|
|
// rebuildfbtreeOp.SetUsesArgsInTypeMapping();
|
|
AddOperator (&insertfrtreeOp);
|
|
insertfrtreeOp.SetUsesMemory();
|
|
insertfrtreeOp.SetUsesArgsInTypeMapping();
|
|
//AddOperator (&FWindowintersectsOp);
|
|
|
|
AddOperator (&deletefrtreeOp);
|
|
deletefrtreeOp.SetUsesMemory();
|
|
deletefrtreeOp.SetUsesArgsInTypeMapping();
|
|
|
|
|
|
//
|
|
// R-Tree bulkload
|
|
//
|
|
AddOperator( &bulkloadfrtreeOp );
|
|
bulkloadfrtreeOp.SetUsesArgsInTypeMapping();
|
|
bulkloadfrtreeOp.SetUsesMemory();
|
|
|
|
|
|
//
|
|
// BPTree operators
|
|
//
|
|
// Createfbtree
|
|
AddOperator( &BPTreeOperators::GetCreatefbtreeOperator() );
|
|
// Rebuildfbtree
|
|
AddOperator( &BPTreeOperators::GetRebuildfbtreeOperator() );
|
|
// Deletefbtree
|
|
AddOperator( &BPTreeOperators::GetDeletefbtreeOperator() );
|
|
// Insertfbtree
|
|
AddOperator( &BPTreeOperators::GetInsertfbtreeOperator() );
|
|
// Bulkloadfbtree
|
|
AddOperator( &BPTreeOperators::GetBulkloadfbtreeOperator() );
|
|
//
|
|
// frange
|
|
Operator& frangeOp = BPTreeOperators::GetFrangeOperator();
|
|
AddOperator( &frangeOp );
|
|
frangeOp.SetUsesArgsInTypeMapping();
|
|
// fleftrange
|
|
Operator& fleftrangeOp = BPTreeOperators::GetFleftrangeOperator();
|
|
AddOperator( &fleftrangeOp );
|
|
fleftrangeOp.SetUsesArgsInTypeMapping();
|
|
// frightrange
|
|
Operator& frightrangeOp = BPTreeOperators::GetFrightrangeOperator();
|
|
AddOperator( &frightrangeOp );
|
|
frightrangeOp.SetUsesArgsInTypeMapping();
|
|
// fexactmatch
|
|
Operator& fexactmatchOp = BPTreeOperators::GetFexactmatchOperator();
|
|
AddOperator( &fexactmatchOp );
|
|
fexactmatchOp.SetUsesArgsInTypeMapping();
|
|
}
|
|
|
|
~FileIndexAlgebra() {};
|
|
};
|
|
} // end of namespace
|
|
|
|
/*
|
|
Initialization of algebra
|
|
|
|
*/
|
|
extern "C"
|
|
Algebra* InitializeFileIndexAlgebra( NestedList* nlRef, QueryProcessor* qpRef ){
|
|
nl = nlRef;
|
|
qp =qpRef;
|
|
|
|
return new fialgebra::FileIndexAlgebra;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|