diff options
author | Constantin Jucovschi <cj@ubuntu.localdomain> | 2009-04-24 07:20:22 -0400 |
---|---|---|
committer | Constantin Jucovschi <cj@ubuntu.localdomain> | 2009-04-24 07:20:22 -0400 |
commit | 8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 (patch) | |
tree | bd328a4dd4f92d32202241b5e3a7f36177792c5f /tilemgr | |
download | rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip |
Initial commitv8.0
Diffstat (limited to 'tilemgr')
-rw-r--r-- | tilemgr/Makefile.am | 33 | ||||
-rw-r--r-- | tilemgr/cell.cc | 1 | ||||
-rw-r--r-- | tilemgr/cell.hh | 2 | ||||
-rw-r--r-- | tilemgr/cell.icc | 2 | ||||
-rw-r--r-- | tilemgr/compression.hh | 1 | ||||
-rw-r--r-- | tilemgr/comptile.cc | 1 | ||||
-rw-r--r-- | tilemgr/comptile.hh | 1 | ||||
-rw-r--r-- | tilemgr/gencompression.cc | 2 | ||||
-rw-r--r-- | tilemgr/gencompression.hh | 2 | ||||
-rw-r--r-- | tilemgr/nocompression.cc | 2 | ||||
-rw-r--r-- | tilemgr/nocompression.hh | 2 | ||||
-rw-r--r-- | tilemgr/perstile.cc | 1 | ||||
-rw-r--r-- | tilemgr/perstile.hh | 0 | ||||
-rw-r--r-- | tilemgr/perstile.icc | 0 | ||||
-rw-r--r-- | tilemgr/test/Makefile | 81 | ||||
-rw-r--r-- | tilemgr/test/test_access.cc | 673 | ||||
-rw-r--r-- | tilemgr/test/test_access.data | 3 | ||||
-rw-r--r-- | tilemgr/test/test_splittile.cc | 142 | ||||
-rw-r--r-- | tilemgr/test/test_tile.cc | 979 | ||||
-rw-r--r-- | tilemgr/test/tilertest.cc | 288 | ||||
-rw-r--r-- | tilemgr/tile.cc | 1187 | ||||
-rw-r--r-- | tilemgr/tile.hh | 391 | ||||
-rw-r--r-- | tilemgr/tile.icc | 1 | ||||
-rw-r--r-- | tilemgr/tiler.cc | 397 | ||||
-rw-r--r-- | tilemgr/tiler.hh | 93 | ||||
-rw-r--r-- | tilemgr/transtile.cc | 1 | ||||
-rw-r--r-- | tilemgr/transtile.hh | 1 |
27 files changed, 4287 insertions, 0 deletions
diff --git a/tilemgr/Makefile.am b/tilemgr/Makefile.am new file mode 100644 index 0000000..676d354 --- /dev/null +++ b/tilemgr/Makefile.am @@ -0,0 +1,33 @@ +# -*-Makefile-*- (for Emacs) +# +# This file is part of rasdaman community. +# +# Rasdaman community 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 3 of the License, or +# (at your option) any later version. +# +# Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +# +# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +# rasdaman GmbH. +# +# For more information please see <http://www.rasdaman.org> +# or contact Peter Baumann via <baumann@rasdaman.com>. +# +# MAKEFILE FOR: +# tilemgr +# +# +# COMMENTS: +# +################################################################## + +noinst_LIBRARIES = libtilemgr.a +libtilemgr_a_SOURCES = tile.cc tile.hh tile.icc tiler.cc tiler.hh diff --git a/tilemgr/cell.cc b/tilemgr/cell.cc new file mode 100644 index 0000000..bcab9cd --- /dev/null +++ b/tilemgr/cell.cc @@ -0,0 +1 @@ +//not used diff --git a/tilemgr/cell.hh b/tilemgr/cell.hh new file mode 100644 index 0000000..4c8af27 --- /dev/null +++ b/tilemgr/cell.hh @@ -0,0 +1,2 @@ +//not used + diff --git a/tilemgr/cell.icc b/tilemgr/cell.icc new file mode 100644 index 0000000..4c8af27 --- /dev/null +++ b/tilemgr/cell.icc @@ -0,0 +1,2 @@ +//not used + diff --git a/tilemgr/compression.hh b/tilemgr/compression.hh new file mode 100644 index 0000000..2e291ae --- /dev/null +++ b/tilemgr/compression.hh @@ -0,0 +1 @@ +//not used anymore diff --git a/tilemgr/comptile.cc b/tilemgr/comptile.cc new file mode 100644 index 0000000..bcab9cd --- /dev/null +++ b/tilemgr/comptile.cc @@ -0,0 +1 @@ +//not used diff --git a/tilemgr/comptile.hh b/tilemgr/comptile.hh new file mode 100644 index 0000000..bcab9cd --- /dev/null +++ b/tilemgr/comptile.hh @@ -0,0 +1 @@ +//not used diff --git a/tilemgr/gencompression.cc b/tilemgr/gencompression.cc new file mode 100644 index 0000000..5fa2fce --- /dev/null +++ b/tilemgr/gencompression.cc @@ -0,0 +1,2 @@ +//not used anymore + diff --git a/tilemgr/gencompression.hh b/tilemgr/gencompression.hh new file mode 100644 index 0000000..5fa2fce --- /dev/null +++ b/tilemgr/gencompression.hh @@ -0,0 +1,2 @@ +//not used anymore + diff --git a/tilemgr/nocompression.cc b/tilemgr/nocompression.cc new file mode 100644 index 0000000..5fa2fce --- /dev/null +++ b/tilemgr/nocompression.cc @@ -0,0 +1,2 @@ +//not used anymore + diff --git a/tilemgr/nocompression.hh b/tilemgr/nocompression.hh new file mode 100644 index 0000000..5fa2fce --- /dev/null +++ b/tilemgr/nocompression.hh @@ -0,0 +1,2 @@ +//not used anymore + diff --git a/tilemgr/perstile.cc b/tilemgr/perstile.cc new file mode 100644 index 0000000..a23f993 --- /dev/null +++ b/tilemgr/perstile.cc @@ -0,0 +1 @@ +//moved to tile diff --git a/tilemgr/perstile.hh b/tilemgr/perstile.hh new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tilemgr/perstile.hh diff --git a/tilemgr/perstile.icc b/tilemgr/perstile.icc new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tilemgr/perstile.icc diff --git a/tilemgr/test/Makefile b/tilemgr/test/Makefile new file mode 100644 index 0000000..2070f70 --- /dev/null +++ b/tilemgr/test/Makefile @@ -0,0 +1,81 @@ +# -*-Makefile-*- +# +# This file is part of rasdaman community. +# +# Rasdaman community 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 3 of the License, or +# (at your option) any later version. +# +# Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +# +# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +# rasdaman GmbH. +# +# For more information please see <http://www.rasdaman.org> +# or contact Peter Baumann via <baumann@rasdaman.com>. # Top Level makefile. This points to the various modules that have to be build +# and/or deployed +# +# MAKEFILE FOR: +# test programs of module tilemgr +# +# COMMENTS: +# +################################################################## +######################### Definitions ############################ + +# all test programs +SRCCXX = test_access.cc test_splittile.cc test_tile.cc tilertest.cc +OBJS = ${SRCCXX:%.cc=%.o} +ALLTESTS = ${SRCCXX:%.cc=%} + + +# Sun Solaris: -lposix4 is needed for test_tile because of clock_gettime +ifeq ($(OSTYPE),$(OSTYPE_SOLARIS)) + LDFLAGS += -lposix4 +endif + +ALLFLAGS = $(BASEDBLDFLAGS) $(LDFLAGS) $(STLLDFLAGS) -L$(SUPPORT_BASE)/lib -lz + +MAINLIBS = $(RASLIB) $(TILEMGR) $(MDDIF) $(CATALOGIF) $(CATALOGMGR) \ + $(INDEXMGR) $(BLOBIF) $(MDDMGR) $(ADMINIF) $(QLPARSER) $(INDEXIF) + +########################### Targets ############################## + +# make all tests +.PHONY: test +test: test_tile test_splittile test_access + + +######################## Dependencies ############################ + +test_splittile: test_splittile.o $(RASLIB) $(TILEMGR) $(MDDMGR) $(CATALOGMGR) \ + $(MDDIF) $(CATALOGIF) $(INDEXIF) $(INDEXMGR) $(BLOBIF) $(ADMINIF) + $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(STLLDFLAGS) $(LDFLAGS) -o $@ $^ \ + $(STLLDFLAGS) + +tilertest: tilertest.o $(RASLIB) $(TILEMGR) $(MDDMGR) $(CATALOGMGR) \ + $(MDDIF) $(CATALOGIF) $(INDEXIF) $(INDEXMGR) $(BLOBIF) $(ADMINIF) + $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(STLLDFLAGS) $(LDFLAGS) -o $@ $^ $(BLOBIF) $(ADMINIF) $(CATALOGIF) $(INDEXIF) $(MDDIF) $(CATALOGIF) $(STLLDFLAGS) $(INDEXMGR) $(COMPRESSION) $(RASLIB) + + +# can not be used as a target (module library is not remade!) +test_tile: test_tile.o $(QLPARSER) $(RASLIB) $(ADMINIF) $(CATALOGMGR) \ + $(TILEMGR) $(MDDMGR) $(MDDIF) $(CATALOGIF) $(INDEXMGR) $(BLOBIF) $(INDEXIF) + $(PURIFY) $(CXX) $(LDFLAGS) $(STLLDFLAGS) $(BASEDBLDFLAGS) \ + -L$(SUPPORT_BASE)/lib -o $@ $^ -lmalloc -lospace \ + $(RASLIB) $(QLPARSER) -lz + + +test_access: test_access.o $(SERVERCOMM) $(QLPARSER) $(CONVERSION) $(RASLIB) \ + $(ADMINIF) $(CACHETAMGR) $(COMPRESSION) $(MDDIF) $(CATALOGIF) \ + $(INDEXMGR) $(BLOBIF) $(INDEXIF) $(HTTPSERVER) + $(PURIFY) $(CXX) $(LDFLAGS) $(BASEDBLDFLAGS) -o $@ $^ \ + $(RELCATALOGIF) -lstdc++ -L$(SUPPORT_BASE)/lib $(RASLIB) -ltiff -lz + diff --git a/tilemgr/test/test_access.cc b/tilemgr/test/test_access.cc new file mode 100644 index 0000000..0b9149c --- /dev/null +++ b/tilemgr/test/test_access.cc @@ -0,0 +1,673 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community 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 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +*/ + +/**************************************************************************** + * + * + * PURPOSE: + * accesses data from a RasDaMan database according to the options + * specified in an input file. Optionally outputs timing and size + * information. + * + * DESCRIPTION: + * test_access reads from a text file a database name, and mddcolls + * names and for each one of them, it either reads a PersMDDColl and + * prints the status of all the mddobjs it contains (or part of them) + * or it deletes the MDDObjs. + * The program is able to print the tiles contents, show the accessing + * time and the sizes of each MDDObject. + * The input file has to start with the line: + * 'Database: <database name> ' + * and after it, for every MDDCollection, the line: + * 'MDDColl: <mddcoll name> ' + * which can be followed by the line: + * ' intersect: <domain> ' + * or by the line: + * ' pointQuery: <domain> ' + * in this case, the cell with address equal to the origin of the + * tile is accessed. + * which causes printing only the status of the mddobjs which + * intersect with <domain>. + * Options and arguments are described in the printUsage( ) function. + * + * Example input file : + * Database: SMRasDaBase + * MDDColl: Images2DA + * intersect: [0:29,9:19] + * MDDColl: Toms3DA + * + * + * COMMENTS: + * In this version, the -r option deletes whole collections only. + * To be extended in the future to delete selected objects and/or + * selected parts of objects. + * + ***************************************************************************/ + +#ifdef EARLY_TEMPLATE +#define __EXECUTABLE__ +#ifdef __GNUG__ +#include "server/template_inst.hh" +#endif +#endif + +#include <stdlib.h> +#include <iostream.h> +#include <fstream.h> +#include <string.h> +#include <vector.h> + +#ifdef BASEDB_O2 +#include "o2template_CC.hxx" // declaration of O2 ref and coll classes +#endif + +#include "raslib/rminit.hh" +#include "raslib/rmdebug.hh" +#include "typefactory.hh" +#include "ulongtype.hh" // from the catalogif base DBMS interface module + +#include "mddmgr/persmddcoll.hh" +#include "mddmgr/persmddobj.hh" + +#include "mddmgr/persmddcolliter.hh" + +#include "adminif.hh" +#include "databaseif.hh" +#include "transactionif.hh" + +#include "compression/tilecompression.hh" + +extern char* myExecArgv0 = ""; + +RMINITGLOBALS('C') + +#define MAX 256 +ifstream testfile; + +void testAccessing( char* persMDDCollName, char* search, + int printTilesContents, int timeAccess, + int printSizes, int printCompression ); +void intersectOption( char* search, + PersMDDColl* accessedColl, + int printTilesContents, + int timeAccess, + int printSizes ); +void pointQueryOption( char* search, + PersMDDColl* accessedColl, + int timeAccess, + int printSizes ); +void testDeleteColls( DatabaseIf* db, char* persMDDCollName, + char* search, int timeAccess, int printSizes ); + +int checkArguments( int argc, char** argv, const char* searchText, + int& optionValueIndex ); +void printUsage( ); + +/********************************************************************** + * Function name.: int main (int argc, char** argv) + * + * Arguments.....: + * argc: number of arguments given to program + * argv: array of char* with arguments + * Return value..: exit status + * Description...: none + **********************************************************************/ + +int +main( int argc, char** argv) +{ + // variables representing O2 database, test file, ta and session + DatabaseIf database; + TransactionIf ta; + // static char O2BenchSchemaName[] = "SMRasDaSchema"; + static char O2BenchDBName[MAX]; + char mc_name[MAX],search[MAX]; + int printTilesContents = 0; + int timeAccess = 0; + int printSizes = 0; + int printCompression = 0; + int deleteColls = 0; + int i, optionValueIndex; + + // don't forget to initialize before using AdminIf! + myExecArgv0 = argv[0]; + AdminIf* myAdmin = AdminIf::instance(); + + // is help is needed + if (checkArguments (argc, argv, "-h", optionValueIndex)) + { + printUsage( ); + delete myAdmin; + exit( 0 ); + } + + // openning the test file + if (checkArguments (argc, argv, "-f", optionValueIndex)) + { + for (i = 0; argv[optionValueIndex][i+1] != '\0'; i++) + search[i] = argv[optionValueIndex][i+2]; + testfile.open (search); + if (!testfile) + { + cout << "cannot open this file" << endl; + return 1; + } + } + else + printUsage( ); + /* + { + cout << "Please write: test_access -f<testfile-name>" << endl; + cout << "Or maybe: test_access -h for help...." << endl; + return 1; + } + */ + + // updating the flag of printing the tiles + if (checkArguments (argc, argv, "-p", optionValueIndex)) + printTilesContents = 1; + + // updating the flag of timming the access + if (checkArguments (argc, argv, "-t", optionValueIndex)) + timeAccess = 1; + + // updating the flag of printing the sizes of mddobjs + if (checkArguments (argc, argv, "-s", optionValueIndex)) + printSizes = 1; + + // updating the flag of deletion + if (checkArguments (argc, argv, "-r", optionValueIndex)) + deleteColls = 1; + + // updating the flag of compression + if (checkArguments (argc, argv, "-c", optionValueIndex)) + printCompression = 1; + + // reading data-base name + testfile.getline (search, MAX, ':'); + while ((!strstr (search, "Database")) && (!testfile.eof ( ))) + testfile.getline (search, MAX, ':'); + testfile >> O2BenchDBName; + + // connect to the database + cout << "Connecting to database " << O2BenchDBName + << "..." << endl; + database.open (O2BenchDBName); + + // searching for mddcalls + testfile.getline (search, MAX, ':'); + while (!testfile.eof ( )) + { + ta.begin ( &database ); + + // searching for mddcall + while ((!strstr (search, "MDDColl")) && (!testfile.eof ( ))) + testfile.getline (search, MAX, ':'); + if (strstr (search, "MDDColl")) + { + testfile >> mc_name; + testfile.getline (search, MAX, ':'); + if (!deleteColls) + testAccessing (mc_name, search, printTilesContents, timeAccess, + printSizes, printCompression); + else + testDeleteColls(&database, mc_name, search, timeAccess, printSizes); + } + + ta.commit( ); + } + + cout << endl<< "Ending O2 session..." << endl; + database.close( ); + testfile.close( ); + delete myAdmin; +} + +/********************************************************************** + * Function......: + * testAccessing( char* persMDDCollName, char* search, + * int printTilesContents, int timeAccess, + * int printSizes) + * Arguments.....: + * persMDDCollName: the MDDColl name + * search: for searching the words from the file + * printTilesContents: the flag of printing the tiles + * timeAccess: the flag of timming the access + * Return value..: none + * Description...: reads DirTilesIx's and shows contents + **********************************************************************/ + +void testAccessing( char* persMDDCollName, char* search, + int printTilesContents, int timeAccess, + int printSizes, int printCompression) +{ + PersMDDObj* accessedObj; + PersMDDColl* accessedColl; + + cout << endl << endl << "....testAccessing " << persMDDCollName << endl; + try + { + accessedColl = new PersMDDColl(persMDDCollName); + } + catch(...) + { + cout << " Error: exception caught when trying to access collection "; + cout << endl; + return; + } + + // To test PersMDDColl::printStatus( ) + // accessedColl->printStatus( ); + + // To test PersMDDObj::printStatus( ), MDDCollIter::createIterator( ) and + // MDDCollIter methods : + + // cout << " Iterating through the collection with PersMDDCollIter " << endl; + // MDDCollIter* objsIt = accessedColl->createIterator( ); + + + // the regular option of showing the contents + if ((strstr (search, "MDDColl")) || (testfile.eof ( ))) + { + cout << " Iterating through the collection with PersMDDCollIter " << endl; + MDDCollIter* objsIt = accessedColl->createIterator( ); + + for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( )) + { + accessedObj = (PersMDDObj*) objsIt->getElement(); + cout << endl << endl << " --" << i << ". MDD object in set:" << endl; + + if (printTilesContents && timeAccess) + { + vector<Tile*>* TileVector; + + // start counter + RMInit::dbgOut.rdbuf(cout.rdbuf()); + RMTimer* Counter = new RMTimer("PersMDDObj", "getTiles"); + TileVector = accessedObj->getTiles ( ); + + // stop counter + cout << "The time of accessing by "; + delete Counter; + + vector<Tile*> ::iterator t; + for (t = TileVector->begin ( ); t != TileVector->end ( ); t++) + { + (*t)->printStatus( ); + cout << endl; + } + + TileVector->erase( TileVector->begin(), TileVector->end() ); + delete TileVector; + } + + else if (printTilesContents && !timeAccess) + { + vector<Tile*>* TileVector; + TileVector = accessedObj->getTiles ( ); + + vector<Tile*> ::iterator t; + for (t = TileVector->begin ( ); t != TileVector->end ( ); t++) + { + (*t)->printStatus( ); + cout << endl; + } + + TileVector->erase( TileVector->begin(), TileVector->end() ); + delete TileVector; + } + + else if (!printTilesContents && timeAccess) + { + // start counter + RMInit::dbgOut.rdbuf(cout.rdbuf()); + RMTimer* Counter = new RMTimer("PersMDDObj", "printStatus"); + accessedObj->printStatus ( ); + + // stop counter + cout << endl << "The time of accessing by "; + delete Counter; + } + + else if (!printTilesContents && !timeAccess) + { + accessedObj->printStatus ( ); + } + + if (printSizes) + { + // printing the sizes of the mddobj + cout << endl << "The logical-size of the mddobj: " << accessedObj->getLogicalSize ( ) << endl; + cout << "The physical-size of the mddobj: " << accessedObj->getPhysicalSize ( ) << endl; + cout << "The physical-cells-size of the mddobj: " << accessedObj->getPhysicalCellsSize ( ) << endl; + cout << "The index-size of the mddobj: " << accessedObj->getIxSize ( ) << endl; + } + + if (printCompression) + { + int i = 0; + unsigned long totalSize = 0; + + vector<Tile*>* TileVector; + TileVector = accessedObj->getTiles ( ); + + vector<Tile*> ::iterator t; + for (t = TileVector->begin ( ); t != TileVector->end ( ); t++) + { + cout << ++i << ". "; + if( (*t)->getDataFormat() == r_ZLib ) + { + totalSize += (*t)->getPhysicalSize( ); + cout << "Size of compressed tile: " + << (*t)->getPhysicalSize( ) << endl; + } + else + { + cout << "Tile not compressed! Size: " << (*t)->getSize() << endl; + + } + } + TileVector->erase( TileVector->begin(), TileVector->end() ); + delete TileVector; + + if(totalSize != 0) + cout << "Total size of compressed tiles: " << totalSize << endl; + } + } // for objsIt loop + + delete objsIt; + + } // if MDDColl + + // the intersect option + else if (strstr (search, "intersect")) + { + intersectOption( search, accessedColl, printTilesContents, timeAccess, printSizes); + } + else if (strstr (search, "pointQuery")) + { + pointQueryOption( search, accessedColl, timeAccess, printSizes); + } + else + { + cout << "don't know what is this..." << endl; + testfile.getline (search, MAX, ':'); + } + + + + accessedColl->releaseAll( ); + delete accessedColl; +} + + + +void +intersectOption( char* search, + PersMDDColl* accessedColl, + int printTilesContents, + int timeAccess, + int printSizes ) +{ + PersMDDObj* accessedObj; + + int cont = 1; + for ( ; cont == 1 ; ) // intersect loop + { + testfile.get (search, MAX, '['); + testfile.getline (search, MAX, ']'); + strcat (search, "]"); + + cout << " Iterating through the collection with PersMDDCollIter " << endl; + MDDCollIter* objsIt = accessedColl->createIterator( ); + + for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( )) + { + accessedObj = (PersMDDObj*) objsIt->getElement(); + cout << endl << endl << " --" << i << ". MDD object in set:" << endl; + + r_Minterval interval (search); + cout << "Intersecting to "<< interval << endl; + vector<Tile*>* TileVector; + vector<Tile*> ::iterator t; + RMTimer* Counter; + + if ( timeAccess ) + { + // start counter + // RMInit::dbgOut = cout.rdbuf(); + RMInit::bmOut << "Intersect Region " << interval << " " << "\t"; + // Counter = new RMTimer(" PersMDDObj", "intersect"); + } + + TileVector = accessedObj->intersect (interval); + + if ( printTilesContents ) + { + int j = 1; + for (t = TileVector->begin ( ); t != TileVector->end ( ); t++, j++) + { + cout << "Tile "<< j <<": "<<endl; + (*t)->printStatus( ); + cout << endl; + } + } + else + { + int j = 1; + for (t = TileVector->begin ( ); t != TileVector->end ( ); t++, j++) + cout << "Tile " << j << ": " << (*t)->getDomain ( ) << endl; + } + + // ?? TileVector->erase( ); + delete TileVector; + + if (printSizes) + { + // printing the sizes of the mddobj + cout << endl << "The logical-size of the mddobj: " << accessedObj->getLogicalSize ( ) << endl; + cout << "The physical-size of the mddobj: " << accessedObj->getPhysicalSize ( ) << endl; + cout << "The physical-cells-size of the mddobj: " << accessedObj->getPhysicalCellsSize ( ) << endl; + cout << "The index-size of the mddobj: " << accessedObj->getIxSize ( ) << endl; + } + } // for objsIt loop + + delete objsIt; + testfile.getline (search, MAX, ':'); + cout << search << endl; + if ( !strstr( search, "intersect") ) + cont = 0; + // cout << " cont "<< cont << endl; + } // for cont loop +} + +void +pointQueryOption( char* search, + PersMDDColl* accessedColl, + int timeAccess, + int printSizes ) +{ + PersMDDObj* accessedObj; + + int cont = 1; + for ( ; cont == 1 ; ) // intersect loop + { + testfile.get (search, MAX, '['); + testfile.getline (search, MAX, ']'); + strcat (search, "]"); + + cout << " Iterating through the collection with PersMDDCollIter " << endl; + MDDCollIter* objsIt = accessedColl->createIterator( ); + + for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( )) + { + accessedObj = (PersMDDObj*) objsIt->getElement(); + cout << endl << endl << " --" << i << ". MDD object in set:" << endl; + + r_Minterval interval (search); + r_Point pnt = interval.get_origin( ); + cout << "Point query to "<< pnt << endl; + + RMTimer* Counter; + if ( timeAccess ) + { + // start counter + RMInit::bmOut << "Intersect Region " << interval << " " << "\t"; + // Counter = new RMTimer(" PersMDDObj", "intersect"); + } + + char* result = accessedObj->pointQuery(pnt); + if ( result ) + cout << "Result of point query : "<< long(*result) <<endl; + else + cout << "Null pointer returned from pointQuery!!!! "<< endl; + + if (printSizes) + { + // printing the sizes of the mddobj + cout << endl << "The logical-size of the mddobj: " << accessedObj->getLogicalSize ( ) << endl; + cout << "The physical-size of the mddobj: " << accessedObj->getPhysicalSize ( ) << endl; + cout << "The physical-cells-size of the mddobj: " << accessedObj->getPhysicalCellsSize ( ) << endl; + cout << "The index-size of the mddobj: " << accessedObj->getIxSize ( ) << endl; + } + } // for objsIt loop + + delete objsIt; + testfile.getline (search, MAX, ':'); + cout << search << endl; + if ( !strstr( search, "pointQuery") ) + cont = 0; + // cout << " cont "<< cont << endl; + } // for cont loop +} + + + +/********************************************************************** + * Function......: + * testDeleteColls( DatabaseIf* db, char* persMDDCollName, + * char* search, int timeAccess,int printSizes ) + * + * Arguments.....: + * persMDDCollName: the MDDColl name + * search: for searching the words from the file + * printTilesContents: the flag of printing the tiles + * timeAccess: the flag of timming the access + * Return value..: none + * Description...: reads DirTilesIx's and shows contents + **********************************************************************/ + +void testDeleteColls( DatabaseIf* db, char* persMDDCollName, + char* search, int timeAccess, int printSizes) +{ + // PersMDDObj* accessedObj; + PersMDDColl* accessedColl; + + /* + cout << endl << endl << "... Destroying root collection " + << persMDDCollName << endl; + PersMDDColl::destroyRoot( persMDDCollName, db ); + */ + + cout << endl << endl << "....testAccessing " << persMDDCollName << endl; + try + { + accessedColl = new PersMDDColl( persMDDCollName ); + } + catch(...) + { + cout << " Error: exception caught when trying to access collection "; + cout << endl; + return; + } + + accessedColl->removeAll( ); + accessedColl->releaseAll( ); + + cout << endl << endl << "... Destroying root collection " + << persMDDCollName << endl; + PersMDDColl::destroyRoot( persMDDCollName, db ); + +} + +/********************************************************************** + * Function......: checkArguments (int argc, char** argv, + * const char* searchText, + * int& optionValueIndex) + * + * Arguments.....: + * argc: number of arguments given to program + * argv: array of char* with arguments + * searchText: the desire option + * optionValueIndex: the index of the found option + * Return value..: int + * Description...: searching an option in the accexuting line + **********************************************************************/ +int checkArguments (int argc, char** argv, const char* searchText, + int& optionValueIndex) +{ + int found = 0; + int i = 1; + + while (!found && i < argc) + { + found = !strncmp (searchText, argv[i], 2); + if (!found) + i++; + } + if (found) + optionValueIndex = i; + else + optionValueIndex = 0; + + return found; +} + + +void printUsage( ) +{ + cout << endl << "Usage: " << endl; + cout << "test_access -h" << endl; + cout << "test_access -f<file> [-t] [-p] [-s]" << endl; + cout << "test_access -f<file> -r " << endl; + cout << " -h ... this help" << endl; + cout << " -p ... for printing tiles contents" << endl; + cout << " -t ... for timming the access" << endl; + cout << " -s ... for printing the sizes of mddobjs" << endl; + cout << " -f<file> ... for the name of the text file" << endl; + cout << " -r ... for deleting the collections listed in <file>" << endl; + cout << " -c ... for printing info on compressed tiles"; + cout << endl << endl; + +} + + + + + + + + + + + diff --git a/tilemgr/test/test_access.data b/tilemgr/test/test_access.data new file mode 100644 index 0000000..d3b434f --- /dev/null +++ b/tilemgr/test/test_access.data @@ -0,0 +1,3 @@ +Database: RASBASE +MDDColl: rockies_comp + diff --git a/tilemgr/test/test_splittile.cc b/tilemgr/test/test_splittile.cc new file mode 100644 index 0000000..de713e2 --- /dev/null +++ b/tilemgr/test/test_splittile.cc @@ -0,0 +1,142 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community 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 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +*/ + +/************************************************************* + * + * + * COMMENTS: + * + ************************************************************/ + +#include <stdlib.h> +#include <iostream> +#include "typefactory.hh" +#include "basetype.hh" +#include "tilemgr/tile.hh" +#include "tilemgr/transtile.hh" + + +#include "raslib/rminit.hh" +RMINITGLOBALS('C') + +#include "raslib/minterval.hh" +#include "raslib/sinterval.hh" +#include "adminif.hh" +#include "databaseif.hh" +#include "transactionif.hh" + +// perhaps used later +static char O2BenchDBName[] = "TestSMBase"; +static char O2BenchSchemaName[] = "TestSMSchema"; + +// static void ClearDB( d_Database &DB ); +extern char* myExecArgv0 = ""; + +/************************************************************* + * Function name.: int main( int argc, char** argv) + * + * Arguments.....: + * argc: number of arguments given to program + * argv: array of char* with arguments + * Return value..: exit status + * Description...: none + ************************************************************/ +int +main( int argc, char** argv) +{ + // variables representing O2 database, ta and session + DatabaseIf database; + TransactionIf ta; + + // don't forget to initialize before using AdminIf! + myExecArgv0 = argv[0]; + AdminIf* myAdmin = AdminIf::instance(); + + + // connect to the database + cout << "Connecting to database " << O2BenchDBName << "..." << endl; + database.open( O2BenchDBName ); + + + // create indexes and put them in TestMDDObjContainer + cout << " SplitTile..." << endl; + ta.begin(); + + static BaseType* bt = TypeFactory::mapType( "Short" ); + cout << "BaseType " << bt->getTypeName( ) << endl; + + r_Minterval tileDom = + r_Minterval(2) << r_Sinterval(0l,0l) << r_Sinterval(0l,99l); + //r_Minterval(2) << r_Sinterval(0l,9l) << r_Sinterval(0l,9l); + //("[0:9,0:9]"); + cout << "tileDom " << tileDom << endl; + r_Minterval BigTileDom = + r_Minterval(2) << r_Sinterval(0l,39l) << r_Sinterval(0l, 99l); + // ("[0:39,0:39]"); + cout << "BigTileDom " << BigTileDom << endl; + + unsigned long sz = bt->getSize( ) * BigTileDom.cell_count( ); + + char* cells = new char[sz]; + /* + for (int i = 0; i < sz ; i++ ) + { + if (i /2) cells[i] = char (i/10); + else cells[i] = 0; + } + */ + short* typedCells = (short*) cells; + unsigned typedSz = BigTileDom.cell_count( ); + for (int i = 0; i < typedSz; i++ ) + typedCells[i] = i; + + vector< Tile* >* tilesReturned; + TransTile* tile1Obj1 = new TransTile( BigTileDom, + (const BaseType* ) bt, + ( char*) cells, 1); + + cout << "Calling splitTile " << endl; + tilesReturned = tile1Obj1->splitTile( tileDom ); + cout << "Finished splitTile " << endl; + + + vector<Tile*>::iterator entryIt = tilesReturned->begin(); + + i = 0 ; + while (entryIt != tilesReturned->end()) + { + cout << "Tile " << i << endl; + (*entryIt)->printStatus(); + entryIt++; + i++; + } + + ta.commit(); + + delete[] cells; + + cout << endl << "Ending O2 session..." << endl; + database.close( ); + delete myAdmin; +} + diff --git a/tilemgr/test/test_tile.cc b/tilemgr/test/test_tile.cc new file mode 100644 index 0000000..18f5b97 --- /dev/null +++ b/tilemgr/test/test_tile.cc @@ -0,0 +1,979 @@ +#include "mymalloc/mymalloc.h" +/* +* This file is part of rasdaman community. +* +* Rasdaman community 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 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +*/ + +/************************************************************* + * + * + * PURPOSE: + * creates Tiles and does ops + * + * + * COMMENTS: + * none + * + ************************************************************/ + +static const char rcsid[] = "@(#)cachetamgr,test_tile: $Id: test_tile.cc,v 1.26 2002/08/30 11:51:22 coman Exp $"; + +#include <stdlib.h> +#include <iostream> +#include <time.h> +#include "ulongtype.hh" +#include "booltype.hh" +#include "chartype.hh" +#include "structtype.hh" + +#ifndef bool + #include <bool.h> + #define OS_OMIT_BOOL +#endif + +#include "adminif.hh" +#include "databaseif.hh" +#include "transactionif.hh" +#include "tilemgr/perstile.hh" +#include "tilemgr/transtile.hh" +#include "typefactory.hh" +#include "raslib/rminit.hh" +#include "raslib/rmdebug.hh" + +// global variable for AdminIf because of O2 d_Session::begin() +extern char* myExecArgv0 = ""; + +RMINITGLOBALS('C') + +// perhaps used later +static char O2BenchDBName[256] = "NorbertBase"; +static char O2BenchSchemaName[256] = "NorbertSchema"; + +void +printTime() +{ + struct timespec cur_time; + clock_gettime(CLOCK_REALTIME, &cur_time); + + cout << asctime(localtime(&(cur_time.tv_sec))); +} + +void +testConstructors() +{ + // for for loops + unsigned long i; + // Tile used for tests + Tile* myTile; + // base types for tiles + BaseType* ulongType = TypeFactory::mapType("ULong"); + // domain of all Tiles + r_Minterval dom = + r_Minterval(3) << r_Sinterval(1L,10L) << r_Sinterval(11L,20L) + << r_Sinterval(5L,7L); + + // testing constructor executing section operation + // first create a tile with the whole domain + // char* containing data for one ULong Tile + char* tileData = (char*)mymalloc(dom.cell_count() * ulongType->getSize()); + for(i = 0; i < dom.cell_count() * ulongType->getSize(); i++) + { + if(i % ulongType->getSize() == 3 ) + tileData[i] = 10; + else + tileData[i] = 0; + } + + // transient with value + cout << "Creating transient ULong Tile containing 10 with domain " + << dom << ":" << endl; + myTile = new TransTile( dom, ulongType, tileData ); + + // now project it + set<r_Dimension, less<r_Dimension> >* projSet = + new set<r_Dimension, less<r_Dimension> >; + projSet->insert(1); + + r_Minterval projDom = + r_Minterval(3) << r_Sinterval(1l, 10l) << r_Sinterval(15l, 15l) + << r_Sinterval(5l, 7l); + + Tile* projectedTile = new TransTile(myTile, projDom, projSet); + + projectedTile->printStatus(); + + delete projSet; + delete projectedTile; +} + +void +testCompression() +{ + // for for loops + unsigned long i; + // Tile used for tests + Tile* myTile; + // Tile used for inititializing tiles with OP_IDENTITY + Tile* myContentTile; + // for contents of tiles + char* tileData; + // base types for tiles + BaseType* ulongType = TypeFactory::mapType("ULong"); + // domain of all Tiles + r_Minterval dom = + r_Minterval(3) << r_Sinterval(1L,10L) << r_Sinterval(11L,20L) + << r_Sinterval(5L,7L); + + cout << "Testing Constructors for Tiles" << endl; + cout << "------------------------------" << endl << endl; + + // ------------------------------------------------------------ + // uncompressed TransTile + // ------------------------------------------------------------ + + // char* containing data for one ULong Tile + tileData = (char*)mymalloc(dom.cell_count() * ulongType->getSize()); + for(i = 0; i < dom.cell_count() * ulongType->getSize(); i++) + { + if(i % ulongType->getSize() == 3 ) + tileData[i] = 10; + else + tileData[i] = 0; + } + + // transient with value + cout << "Creating transient ULong Tile containing 10 with domain " + << dom << ":" << endl; + myTile = new TransTile( dom, ulongType, tileData ); + + cout << " Printing created Tile: " << endl; + myTile->printStatus(); + + cout << " Deleting created Tile" << endl << endl; + delete myTile; + + // ------------------------------------------------------------ + // uncompressed PersTile + // ------------------------------------------------------------ + + // char* containing data for one ULong Tile + tileData = (char*)mymalloc(dom.cell_count() * ulongType->getSize()); + for(i = 0; i < dom.cell_count() * ulongType->getSize(); i++) + { + if(i % ulongType->getSize() == 3 ) + tileData[i] = 10; + else + tileData[i] = 0; + } + + // persistent with value + cout << "Creating persistent ULong Tile containing 10 with domain " + << dom << ":" << endl; + myTile = new PersTile( dom, ulongType, tileData ); + + cout << " Printing created Tile: " << endl; + myTile->printStatus(); + + cout << " Deleting created Tile" << endl << endl; + delete myTile; + + // ------------------------------------------------------------ + // uncompressed TransTile + // ------------------------------------------------------------ + + // char* containing data for one ULong Tile + tileData = (char*)mymalloc(dom.cell_count() * ulongType->getSize()); + for(i = 0; i < dom.cell_count() * ulongType->getSize(); i++) + { + if(i % ulongType->getSize() == 3 ) + tileData[i] = 10; + else + tileData[i] = 0; + } + + // transient with value + cout << "Creating transient ULong Tile containing 10 with domain " + << dom << ":" << endl; + myContentTile = new TransTile( dom, ulongType, tileData ); + myTile = new TransTile( dom, ulongType ); + myTile->execUnaryOp( Ops::OP_IDENTITY, dom, myContentTile, dom ); + + cout << " Printing created Tile: " << endl; + myTile->printStatus(); + + cout << " Deleting created Tile" << endl << endl; + delete myTile; + + // ------------------------------------------------------------ + // uncompressed PersTile + // ------------------------------------------------------------ + + // char* containing data for one ULong Tile + tileData = (char*)mymalloc(dom.cell_count() * ulongType->getSize()); + for(i = 0; i < dom.cell_count() * ulongType->getSize(); i++) + { + if(i % ulongType->getSize() == 3 ) + tileData[i] = 10; + else + tileData[i] = 0; + } + + // persistent with value + cout << "Creating persistent ULong Tile containing 10 with domain " + << dom << ":" << endl; + myContentTile = new PersTile( dom, ulongType, tileData ); + myTile = new PersTile( dom, ulongType, r_ZLib ); + myTile->execUnaryOp( Ops::OP_IDENTITY, dom, myContentTile, dom ); + + cout << " Printing created Tile: " << endl; + myTile->printStatus(); + + cout << " Deleting created Tile" << endl << endl; + delete myTile; + + // ------------------------------------------------------------ + // compressed TransTile + // ------------------------------------------------------------ + + // char* containing data for one ULong Tile + tileData = (char*)mymalloc(dom.cell_count() * ulongType->getSize()); + for(i = 0; i < dom.cell_count() * ulongType->getSize(); i++) + { + if(i % ulongType->getSize() == 3 ) + tileData[i] = 10; + else + tileData[i] = 0; + } + + // transient with value + cout << "Creating compressed transient ULong Tile containing 10 with domain " + << dom << ":" << endl; + myTile = new TransTile( dom, ulongType, r_ZLib ); + myTile->setContents(tileData); + + cout << " Physical Size: " << myTile->getPhysicalSize() << endl; + + cout << " Printing created Tile: " << endl; + myTile->printStatus(); + + cout << " Physical Size: " << myTile->getPhysicalSize() << endl; + + cout << " Deleting created Tile" << endl << endl; + delete myTile; + + // ------------------------------------------------------------ + // compressed PersTile + // ------------------------------------------------------------ + + // char* containing data for one ULong Tile + tileData = (char*)mymalloc(dom.cell_count() * ulongType->getSize()); + for(i = 0; i < dom.cell_count() * ulongType->getSize(); i++) + { + if(i % ulongType->getSize() == 3 ) + tileData[i] = 10; + else + tileData[i] = 0; + } + + // persistent with value + cout << "Creating compressed persistent ULong Tile containing 10 with domain " + << dom << ":" << endl; + myTile = new PersTile( dom, ulongType, r_ZLib ); + myTile->setContents(tileData); + + cout << " Physical Size: " << myTile->getPhysicalSize() << endl; + + cout << " Printing created Tile: " << endl; + myTile->printStatus(); + + cout << " Physical Size: " << myTile->getPhysicalSize() << endl; + + cout << " Deleting created Tile" << endl << endl; + delete myTile; + + // ------------------------------------------------------------ + // compressed TransTile + // ------------------------------------------------------------ + + // char* containing data for one ULong Tile + tileData = (char*)mymalloc(dom.cell_count() * ulongType->getSize()); + for(i = 0; i < dom.cell_count() * ulongType->getSize(); i++) + { + if(i % ulongType->getSize() == 3 ) + tileData[i] = 10; + else + tileData[i] = 0; + } + + // transient with value + cout << "Creating compressed transient ULong Tile containing 10 with domain " + << dom << ":" << endl; + myContentTile = new TransTile( dom, ulongType, tileData ); + myTile = new TransTile( dom, ulongType, r_ZLib ); + myTile->execUnaryOp( Ops::OP_IDENTITY, dom, myContentTile, dom ); + + cout << " Physical Size: " << myTile->getPhysicalSize() << endl; + + cout << " Printing created Tile: " << endl; + myTile->printStatus(); + + cout << " Physical Size: " << myTile->getPhysicalSize() << endl; + + cout << " Deleting created Tile" << endl << endl; + delete myTile; + + // ------------------------------------------------------------ + // compressed PersTile + // ------------------------------------------------------------ + + // char* containing data for one ULong Tile + tileData = (char*)mymalloc(dom.cell_count() * ulongType->getSize()); + for(i = 0; i < dom.cell_count() * ulongType->getSize(); i++) + { + if(i % ulongType->getSize() == 3 ) + tileData[i] = 10; + else + tileData[i] = 0; + } + + // persistent with value + cout << "Creating compressed persistent ULong Tile containing 10 with domain " + << dom << ":" << endl; + myContentTile = new PersTile( dom, ulongType, tileData ); + myTile = new PersTile( dom, ulongType, r_ZLib ); + myTile->execUnaryOp( Ops::OP_IDENTITY, dom, myContentTile, dom ); + + cout << " Physical Size: " << myTile->getPhysicalSize() << endl; + + cout << " Printing created Tile: " << endl; + myTile->printStatus(); + + cout << " Physical Size: " << myTile->getPhysicalSize() << endl; + + cout << " Deleting created Tile" << endl << endl; + delete myTile; +} + +void +testUnaryOps() +{ + // base types for tiles + BaseType* ulongType = TypeFactory::mapType("ULong"); + BaseType* boolType = TypeFactory::mapType("Bool");; + BaseType* charType = TypeFactory::mapType("Char");; + + // default cell for filling ULong Tiles + unsigned long longVal = 4294966295; + char* ulongCell = (char*)&longVal; + + // default cell for filling Bool Tiles + unsigned char boolVal = 1; + char* boolCell = (char*)&boolVal; + + // domain of all Tiles + r_Minterval dom = + r_Minterval(2) << r_Sinterval(1L,10L) << r_Sinterval(11L,20L); + + r_Minterval domOp = + r_Minterval(2) << r_Sinterval(1L,5L) << r_Sinterval(11L,15L); + + // domain of one dimensional result + r_Minterval res1D = + r_Minterval(2) << r_Sinterval(1L,10L); + + unsigned char charVal = 20; + char* charCell = (char*)&charVal; + + // Tiles used for tests + Tile* transULongTile; + Tile* transBoolTile; + Tile* persULongTile; + Tile* persBoolTile; + Tile* transCharTile; + Tile* transCharRes; + + cout << "Testing Unary Operations on Tiles" << endl; + cout << "---------------------------------" << endl << endl; + + // transient with value + cout << "Creating Tiles for Unary Operations with domain " + << dom << ":" << endl; + transULongTile = new TransTile( dom, ulongType, ulongCell ); + transBoolTile = new TransTile( dom, boolType, boolCell ); + persULongTile = new PersTile( dom, ulongType, ulongCell ); + persBoolTile = new PersTile( dom, boolType, boolCell ); + transCharTile = new TransTile( dom, charType, charCell ); + transCharRes = new TransTile( domOp, charType, boolCell ); + + + cout << "Operations with ULong:" << endl << endl; + + cout << "Carrying out NOT on TransTile (should be 1000)" << endl; + transULongTile->execUnaryOp(Ops::OP_NOT, dom, transULongTile, dom); + + cout << "Contents after operation: " << endl; + transULongTile->printStatus(); + + cout << "Carrying out IDENTITY on TransTile (should be 1000)" << endl; + transULongTile->execUnaryOp(Ops::OP_IDENTITY, dom, transULongTile, dom); + + cout << "Contents after operation: " << endl; + transULongTile->printStatus(); + + cout << "Carrying out NOT on PersTile (should be 1000)" << endl; + persULongTile->execUnaryOp(Ops::OP_NOT, dom, persULongTile, dom); + + cout << "Contents after operation: " << endl; + persULongTile->printStatus(); + + cout << "Carrying out IDENTITY on PersTile (should be 1000)" << endl; + persULongTile->execUnaryOp(Ops::OP_IDENTITY, dom, persULongTile, dom); + + cout << "Contents after operation: " << endl; + persULongTile->printStatus(); + + cout << "Operations with Bool:" << endl << endl; + + cout << "Carrying out NOT on TransTile (should be FALSE)" << endl; + transBoolTile->execUnaryOp(Ops::OP_NOT, dom, transBoolTile, dom); + + cout << "Contents after operation: " << endl; + transBoolTile->printStatus(); + + cout << "Carrying out IDENTITY on TransTile (should be FALSE)" << endl; + transBoolTile->execUnaryOp(Ops::OP_IDENTITY, dom, transBoolTile, dom); + + cout << "Contents after operation: " << endl; + transBoolTile->printStatus(); + + cout << "Carrying out NOT on PersTile (should be FALSE)" << endl; + persBoolTile->execUnaryOp(Ops::OP_NOT, dom, persBoolTile, dom); + + cout << "Contents after operation: " << endl; + persBoolTile->printStatus(); + + cout << "Carrying out IDENTITY on PersTile (should be FALSE)" << endl; + persBoolTile->execUnaryOp(Ops::OP_IDENTITY, dom, persBoolTile, dom); + + cout << "Contents after operation: " << endl; + persBoolTile->printStatus(); + + cout << "Carrying out IDENTITY on subset of char tile" << endl; + transCharRes->execUnaryOp(Ops::OP_IDENTITY, domOp, transCharTile, domOp); + + cout << "Contents after operation: " << endl; + transCharRes->printStatus(); + + // Trying to get more interesting values into tile + unsigned char val = 0; + for(int i = 0; i < transCharTile->getSize(); i++) { + transCharTile->setCell(i, (const char*)&val); + val++; + } + + cout << "Tile with more interesting values: " << endl; + transCharTile->printStatus(); + + cout << "Carrying out IDENTITY on subset of char tile" << endl; + transCharRes->execUnaryOp(Ops::OP_IDENTITY, domOp, transCharTile, domOp); + + cout << "Contents after operation: " << endl; + transCharRes->printStatus(); + + // Operation with result of a different dimensionality + + // domain of all Tiles + r_Minterval horSlice = + r_Minterval(2) << r_Sinterval(1L,10L) << r_Sinterval(15L,15L); + r_Minterval verSlice = + r_Minterval(2) << r_Sinterval(5L,5L) << r_Sinterval(11L,20L); + Tile* transRes1D = new TransTile( res1D, charType, charCell ); + + cout << "Carrying out IDENTITY to receive a 1D vertical slice" << endl; + transRes1D->execUnaryOp(Ops::OP_IDENTITY, res1D, transCharTile, horSlice); + + cout << "Contents after operation: " << endl; + transRes1D->printStatus(); + + cout << "Carrying out IDENTITY to receive a 1D horizontal slice" << endl; + transRes1D->execUnaryOp(Ops::OP_IDENTITY, res1D, transCharTile, verSlice); + + cout << "Contents after operation: " << endl; + transRes1D->printStatus(); + + cout << "Deleting created Tiles ..." << endl << endl; + + delete transULongTile; + delete transBoolTile; + delete persULongTile; + delete persBoolTile; + delete transCharRes; + delete transCharTile; + delete transRes1D; +} + +void +testBinaryOps() +{ + // base types for tiles + BaseType* ulongType = TypeFactory::mapType("ULong"); + BaseType* boolType = TypeFactory::mapType("Bool");; + + // default cell for filling ULong Tiles + unsigned long longVal = 1000; + char* ulongCell = (char*)&longVal; + + // default cell for filling Bool Tiles + unsigned char boolVal = 1; + char* boolCell = (char*)&boolVal; + + // domain of all Tiles + r_Minterval dom = + r_Minterval(3) << r_Sinterval(1L,10L) << r_Sinterval(11L,20L) + << r_Sinterval(5L,7L); + + // Tiles used for tests + Tile* transULongTile; + Tile* transBoolTile; + Tile* persULongTile; + Tile* persBoolTile; + Tile* constULongTile; + Tile* constBoolTile; + + cout << "Testing Binary Operations on Tiles" << endl; + cout << "---------------------------------" << endl << endl; + + cout << "Creating Tiles for Binary Operations with domain " + << dom << ":" << endl; + transULongTile = new TransTile( dom, ulongType, ulongCell ); + transBoolTile = new TransTile( dom, boolType, boolCell ); + persULongTile = new PersTile( dom, ulongType, ulongCell ); + persBoolTile = new PersTile( dom, boolType, boolCell ); + + cout << "Creating a TransTile for the two operands..." << endl; + TransTile ttileOp = TransTile(dom, ulongType, ulongCell); + + cout << "Contents: " << endl; + ttileOp.printStatus(); + + cout << "Creating a TransTile for the result..." << endl; + TransTile ttileRes = TransTile(dom, ulongType, ulongCell); + + cout << "Carrying out binary operation..." << endl; + ttileRes.execBinaryOp(Ops::OP_PLUS, dom, &ttileOp, dom, &ttileOp, dom); + + cout << "Contents after operation: " << endl; + ttileRes.printStatus(); + + // testing binary operation with Bool as result + long bval = 10000; + + // default cell for filling all Tiles + char* bvalCell = (char*)&bval; + + cout << "Creating a TransTile for the two operands..." << endl; + TransTile btileOp = TransTile(dom, ulongType, boolCell); + + cout << "Contents: " << endl; + btileOp.printStatus(); + + cout << "Creating a TransTile for the result..." << endl; + TransTile btileRes = TransTile(dom, boolType, boolCell); + + cout << "Carrying out binary operation..." << endl; + btileRes.execBinaryOp(Ops::OP_EQUAL, dom, &btileOp, dom, &btileOp, dom); + + cout << "Contents after operation: " << endl; + btileRes.printStatus(); + + cout << "Carrying out PLUS with TransTile and constant (should be 2000)" + << endl; + + transULongTile->execConstOp(Ops::OP_PLUS, dom, transULongTile, dom, + ulongCell, ulongType); + + cout << "Contents after operation: " << endl; + transULongTile->printStatus(); + + delete transULongTile; + delete transBoolTile; + delete persULongTile; + delete persBoolTile; + delete constULongTile; + delete constBoolTile; +} + +void +testCompTile() +{ +// // size of tiles in one direction +// const long testSize = 10; +// // base types for tiles +// BaseType* ulongType = TypeFactory::mapType("ULong"); + +// // default cell for filling ULong Tiles +// unsigned long longVal = 1000; +// char* ulongCell = (char*)&longVal; + +// // domain of all Tiles +// r_Minterval dom = +// r_Minterval(2) << r_Sinterval(1L,testSize) << r_Sinterval(1L,testSize); + +// // Tiles used for tests +// Tile* compTile1; +// Tile* compTile2; +// TransTile* transTile; + +// cout << "Testing CompTile" << endl; +// cout << "----------------" << endl << endl; + +// cout << "Creating Tiles with domain " +// << dom << ":" << endl; +// compTile1 = new CompTile( dom, ulongType, Tile::COMP_ZLIB, ulongCell ); +// compTile2 = new CompTile( dom, ulongType, Tile::COMP_ZLIB, ulongCell ); +// transTile = new TransTile( dom, ulongType, ulongCell ); + + // initialize with random values +// long val; +// for(int i = 0; i < testSize; i++) { +// for(int j = 0; j < testSize; j++) { +// val = (long)(LONG_MIN + ((double)LONG_MAX-LONG_MIN)*drand48()); +// compTile1->setCell(i*testSize+j, (char*)&val); +// val = (long)(LONG_MIN + ((double)LONG_MAX-LONG_MIN)*drand48()); +// compTile2->setCell(i*testSize+j, (char*)&val); +// } +// } + + // initialize with incrementing values. +// long val; +// for(int i = 0; i < testSize; i++) { +// for(int j = 0; j < testSize; j++) { +// val = i*testSize+j; +// compTile1->setCell(i*testSize+j, (char*)&val); +// compTile2->setCell(i*testSize+j, (char*)&val); +// } +// } + + // initialize with incrementing values, simulate struct +// long val; +// for(int i = 0; i < testSize; i++) { +// for(int j = 0; j < testSize; j += 3) { +// val = i*testSize+j; + +// compTile1->setCell(i*testSize+j, (char*)&val); +// if(j+1 < testSize) +// compTile1->setCell(i*testSize+j+1, (char*)&val+1000000); +// if(j+2 < testSize) +// compTile1->setCell(i*testSize+j+2, (char*)&val+2000000); + +// compTile2->setCell(i*testSize+j, (char*)&val); +// if(j+1 < testSize) +// compTile2->setCell(i*testSize+j+1, (char*)&val+1000000); +// if(j+2 < testSize) +// compTile2->setCell(i*testSize+j+2, (char*)&val+2000000); +// } +// } + +// cout << "Contents transTile: " << endl; +// if(transTile->getSize() <= 1000) +// transTile->printStatus(); + +// cout << "Contents compTile1: " << endl; +// if(transTile->getSize() <= 1000) +// compTile1->printStatus(); + +// cout << "Contents compTile2: " << endl; +// if(transTile->getSize() <= 1000) +// compTile2->printStatus(); + + // does only work if compress() is not protected. +// cout << "Compressing compTiles" << endl; +// ((CompTile*)compTile1)->compress(); +// ((CompTile*)compTile2)->compress(); + +// cout << "Carrying out binary operation..." << endl; +// transTile->execBinaryOp(Ops::OP_PLUS, dom, compTile1, dom, compTile2, dom); + +// cout << "Contents after operation: " << endl; +// if(transTile->getSize() <= 1000) +// transTile->printStatus(); + +// delete compTile1; +// delete compTile2; +// delete transTile; +} + +void +testOpsWithConsts() +{ + // base types for tiles + BaseType* ulongType = TypeFactory::mapType("ULong"); + BaseType* charType = TypeFactory::mapType("Char"); + + StructType* structType = new StructType("TestStruct", 2); + structType->addElement("Band1", "ULong"); + structType->addElement("Band2", "Char"); + + // default cell for filling ULong Tiles + unsigned long uLongVal = 1000; + char* ulongCell = (char*)&uLongVal; + // default cell for filling Char Tiles + unsigned char charVal = 112; + char* charCell = (char*)&charVal; + // default cell for filling Struct Tiles + unsigned char structCell[5]; + structCell[0] = ulongCell[0]; + structCell[1] = ulongCell[1]; + structCell[2] = ulongCell[2]; + structCell[3] = ulongCell[3]; + structCell[4] = charCell[0]; + + // domain of all Tiles + r_Minterval dom = + r_Minterval(2) << r_Sinterval(1L,5L) << r_Sinterval(1L,5L); + + // Tiles used for tests + cout << "Creating Tiles with domain " + << dom << ":" << endl; + Tile* charTile = new TransTile(dom, charType, charCell); + Tile* ulongTile = new TransTile(dom, ulongType, ulongCell); + Tile* structTile = new TransTile(dom, structType, (char*)structCell); + + cout << "Contents of Tiles: " << endl; + charTile->printStatus(); + ulongTile->printStatus(); + structTile->printStatus(); + + cout << "Result Type for Struct and Char: " + << (Ops::getResultType(Ops::OP_PLUS, structType, charType))->getTypeName() << endl; + + cout << "Carrying out binary operation with constant on structTile ..." + << endl; + structTile->execConstOp(Ops::OP_PLUS, dom, structTile, dom, charCell, + charType); + + cout << "Contents after operation: " << endl; + structTile->printStatus(); + + cout << "Carrying out binary operation with charTile on structTile ..." + << endl; + structTile->execBinaryOp(Ops::OP_PLUS, dom, structTile, dom, charTile, dom); + + cout << "Contents after operation: " << endl; + structTile->printStatus(); + + cout << "Carrying out binary operation with two structTiles ..." + << endl; + structTile->execBinaryOp(Ops::OP_PLUS, dom, structTile, dom, structTile, dom); + + cout << "Contents after operation: " << endl; + structTile->printStatus(); + + delete charTile; + delete ulongTile; + delete structTile; +} + +void +testCellAccess() +{ + // base types for tiles + BaseType* ulongType = TypeFactory::mapType("ULong"); + BaseType* charType = TypeFactory::mapType("Char"); + + // default cell for filling ULong Tiles + unsigned long uLongVal = 1000; + char* ulongCell = (char*)&uLongVal; + // default cell for filling Char Tiles + unsigned char charVal = 112; + char* charCell = (char*)&charVal; + + // domain of all Tiles + r_Minterval dom = + r_Minterval(2) << r_Sinterval(1L,10L) << r_Sinterval(1L,10L); + + // Tiles used for tests + cout << "Creating Tiles with domain " + << dom << ":" << endl; + Tile* charTile = new TransTile(dom, charType, charCell); + Tile* ulongTile = new TransTile(dom, ulongType, ulongCell); + + cout << "Accessing cell by point: "; + r_Point a = r_Point(2) << 5 << 5; + cout << (int)*(charTile->getCell(a)) << " " + << *(unsigned long*)ulongTile->getCell(a) << endl; + + delete charTile; + delete ulongTile; +} + +void +testScaleOp(void) +{ + r_Dimension dim = 2; + r_Dimension i; + BaseType* charType = TypeFactory::mapType("Char"); + r_Minterval dom = r_Minterval(dim); + r_Minterval nextDom = r_Minterval(dim); + r_Point origin(dim); + r_Point offset(dim); + unsigned long fullSize; + float scaleBy, incrementBy, eps; + + for (i=0; i<dim; i++) + { + origin[i] = (r_Range)0; + offset[i] = (r_Range)64; + dom << r_Sinterval(origin[i] + offset[i], (r_Range)511 + offset[i]); + nextDom << r_Sinterval((r_Range)512 + offset[i], (r_Range)1023 + offset[i]); + } + + fullSize = dom.cell_count(); + char *tileValues = (char*)mymalloc(fullSize); + Tile *charTile = new TransTile(dom, charType, tileValues, fullSize); + Tile *nextTile = new TransTile(dom, charType); + memset(charTile->getContents(), 0, dom.cell_count()); + + vector<float> scaleFactors(dim); + + incrementBy = 0.05; eps = 1e-2; + for (scaleBy=incrementBy; scaleBy <= 8-eps; scaleBy += incrementBy) + { + vector<float>::iterator iter = scaleFactors.begin(); + + cout << "Scale " << dom << " by " << scaleBy << endl; + + for (i=0; i<dim; i++, iter++) + *iter = scaleBy; + + r_Minterval scaledDom; + if (charTile->scaleGetDomain(dom, origin, scaleFactors, scaledDom)) + { + unsigned long scaledSize = scaledDom.cell_count(); + char *scaledValues = (char*)mymalloc(scaledSize); + Tile *scaledTile = new TransTile(scaledDom, charType, scaledValues, scaledSize); + + r_Minterval nextScaledDom; + if (nextTile->scaleGetDomain(nextDom, origin, scaleFactors, nextScaledDom)) + { + cout << "scaledDom: " << scaledDom << ", nextScaledDom: " << nextScaledDom << endl; + for (i=0; i<dim; i++) + { + if (nextScaledDom[i].low() != scaledDom[i].high() + 1) + { + cout << "NO SEAMLESS MATCH IN DIM " << i << '!' << endl; + } + } + } + + scaledTile->execScaleOp(charTile, dom, origin, scaleFactors); + + delete scaledTile; + } + else + { + cout << "Tile scaled to zero domain" << endl; + } + + incrementBy = 0.05 * (1 << (int)((scaleBy + eps) / 2)); + } + + delete charTile; + delete nextTile; +} + + +/************************************************************* + * Function name.: int main( int argc, char** argv) + * + * Arguments.....: + * argc: number of arguments given to program + * argv: array of char* with arguments + * Return value..: exit status + * Description...: none + ************************************************************/ + +int +main( int argc , char* argv[] ) +{ + int i; + + i = 1; + while (i < argc) + { + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'd': + strcpy(O2BenchDBName, argv[++i]); break; + case 's': + strcpy(O2BenchSchemaName, argv[++i]); break; + case 'h': + cout << "Use: " << argv[0] << " [-d dbname -s schemaname -h]" << endl; + exit(0); + default: + break; + } + } + i++; + } + + // variables representing O2 database, ta and session + DatabaseIf database; + TransactionIf ta; + + // don't forget to initialize before using AdminIf! + myExecArgv0 = argv[0]; + AdminIf* myAdmin = AdminIf::instance(); + + cout << "RManDebug: " << RManDebug << endl; + + // connect to the database + cout << "Connecting to database " << O2BenchDBName + << "..." << endl; + database.open( O2BenchDBName ); + + ta.begin(&database); + + cout << "These tests were done with:" << endl + << " " << rcsid << endl; + cout << "This protocol was created on:" << endl << " "; + printTime(); + cout << endl; + + // testConstructors(); + // testCompression(); + // testUnaryOps(); + // testBinaryOps(); + // testCompTile(); + // testOpsWithConsts(); + // testAlgebraOps(); + // testCellAccess(); + // testScaleOp(); + testScaleOp(); + + ta.commit(); + + cout << "Ending O2 session..." << endl; + database.close(); + delete myAdmin; +} diff --git a/tilemgr/test/tilertest.cc b/tilemgr/test/tilertest.cc new file mode 100644 index 0000000..3502ccc --- /dev/null +++ b/tilemgr/test/tilertest.cc @@ -0,0 +1,288 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community 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 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +*/ + +#include "mymalloc/mymalloc.h" +#ifdef EARLY_TEMPLATE +#define __EXECUTABLE__ +#ifdef __GNUG__ +#include "server/template_inst.hh" +#endif +#endif + +#include "raslib/rmdebug.hh" +#include "raslib/minterval.hh" +#include <iostream.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <vector.h> +#include <pair.h> +#include "tilemgr/transtile.hh" +#include "octettype.hh" +#include "tilemgr/tiler.hh" + +RMINITGLOBALS('C') + + +int +main(int argc, char *argv[]) + { + vector<r_Minterval> sourceDomains; + vector<r_Minterval> targetDomains; + vector<r_Minterval> retvalDomains; + vector<r_Minterval>::iterator sourceDIt; + vector<r_Minterval>::iterator targetDIt; + vector<r_Minterval>::iterator retvalDIt; + + + vector<Tile*>::iterator sourceIt; + vector<Tile*>::iterator targetIt; + vector<Tile*>::iterator retvalIt; + + r_Minterval targetDom("[0:50,0:50]"); + r_Minterval targetInt1("[0:10,0:10]"); + r_Minterval targetInt2("[15:25,10:20]"); + r_Minterval targetInt3("[15:25,21:30]"); + r_Minterval targetInt4("[15:25,31:40]"); + r_Minterval targetInt5("[40:50,40:50]"); + r_Minterval targetInt6("[35:41,25:35]"); + r_Minterval targetInt7("[28:32,28:32]"); + r_Minterval targetInt8("[40:40,0:10]"); + r_Minterval targetInt9("[40:50,11:11]"); + r_Minterval targetInt10("[35:35,0:10]"); + r_Minterval targetInt11("[30:34,10:10]"); + OctetType* o = new OctetType(); + + char* cont1 = 0; + char* cont2 = 0; + char* cont3 = 0; + char* cont4 = 0; + char* cont5 = 0; + char* cont6 = 0; + char* cont7 = 0; + char* cont8 = 0; + char* cont9 = 0; + char* cont10 = 0; + char* cont11 = 0; + char* outc = 0; + cont1 = (char*)mymalloc(500); + cont2 = (char*)mymalloc(500); + cont3 = (char*)mymalloc(500); + cont4 = (char*)mymalloc(500); + cont5 = (char*)mymalloc(500); + cont6 = (char*)mymalloc(500); + cont7 = (char*)mymalloc(500); + cont8 = (char*)mymalloc(500); + cont9 = (char*)mymalloc(500); + cont10 = (char*)mymalloc(500); + cont11 = (char*)mymalloc(500); + outc = (char*)mymalloc(101*101); + memset(cont1, 1, 500); + memset(cont2, 2, 500); + memset(cont3, 3, 500); + memset(cont4, 4, 500); + memset(cont5, 5, 500); + memset(cont6, 6, 500); + memset(cont7, 7, 500); + memset(cont8, 8, 500); + memset(cont9, 9, 500); + memset(cont10, 10, 500); + memset(cont11, 11, 500); + memset(outc, 0, 3500); + TransTile output(targetDom, o, outc); + + TransTile* ttile1 = new TransTile(targetInt1, (const BaseType*)o, cont1); + TransTile* ttile2 = new TransTile(targetInt2, (const BaseType*)o, cont2); + TransTile* ttile3 = new TransTile(targetInt3, (const BaseType*)o, cont3); + TransTile* ttile4 = new TransTile(targetInt4, (const BaseType*)o, cont4); + TransTile* ttile5 = new TransTile(targetInt5, (const BaseType*)o, cont5); + TransTile* ttile6 = new TransTile(targetInt6, (const BaseType*)o, cont6); + TransTile* ttile7 = new TransTile(targetInt7, (const BaseType*)o, cont7); + TransTile* ttile8 = new TransTile(targetInt8, (const BaseType*)o, cont8); + TransTile* ttile9 = new TransTile(targetInt9, (const BaseType*)o, cont9); + TransTile* ttile10 = new TransTile(targetInt10, (const BaseType*)o, cont10); + TransTile* ttile11 = new TransTile(targetInt11, (const BaseType*)o, cont11); + + r_Minterval sourceDom("[5:45,5:45]"); + r_Minterval sourceInt1("[5:10,5:10]"); + r_Minterval sourceInt2("[15:25,12:45]"); + r_Minterval sourceInt3("[30:45,30:38]"); + r_Minterval sourceInt4("[40:45,40:45]"); + r_Minterval sourceInt5("[30:45,25:28]"); + r_Minterval sourceInt6("[39:41,9:11]"); + r_Minterval sourceInt7("[34:36,9:11]"); + + char* scont1 = 0; + char* scont2 = 0; + char* scont3 = 0; + char* scont4 = 0; + char* scont5 = 0; + char* scont6 = 0; + char* scont7 = 0; + scont1 = (char*)mymalloc(500); + scont2 = (char*)mymalloc(500); + scont3 = (char*)mymalloc(500); + scont4 = (char*)mymalloc(500); + scont5 = (char*)mymalloc(500); + scont6 = (char*)mymalloc(500); + scont7 = (char*)mymalloc(500); + memset(scont1, 21, 500); + memset(scont2, 22, 500); + memset(scont3, 23, 500); + memset(scont4, 24, 500); + memset(scont5, 25, 500); + memset(scont6, 26, 500); + memset(scont7, 27, 500); + TransTile* stile1 = new TransTile(sourceInt1, (const BaseType*)o, scont1); + TransTile* stile2 = new TransTile(sourceInt2, (const BaseType*)o, scont2); + TransTile* stile3 = new TransTile(sourceInt3, (const BaseType*)o, scont3); + TransTile* stile4 = new TransTile(sourceInt4, (const BaseType*)o, scont4); + TransTile* stile5 = new TransTile(sourceInt5, (const BaseType*)o, scont5); + TransTile* stile6 = new TransTile(sourceInt6, (const BaseType*)o, scont6); + TransTile* stile7 = new TransTile(sourceInt7, (const BaseType*)o, scont7); + + vector<Tile*> sourceTiles; + sourceTiles.push_back(stile1); + sourceTiles.push_back(stile2); + sourceTiles.push_back(stile3); + sourceTiles.push_back(stile4); + sourceTiles.push_back(stile5); + sourceTiles.push_back(stile6); + sourceTiles.push_back(stile7); + + vector<Tile*> targetTiles; + targetTiles.push_back(ttile1); + targetTiles.push_back(ttile2); + targetTiles.push_back(ttile3); + targetTiles.push_back(ttile4); + targetTiles.push_back(ttile5); + targetTiles.push_back(ttile6); + targetTiles.push_back(ttile7); + targetTiles.push_back(ttile8); + targetTiles.push_back(ttile9); + targetTiles.push_back(ttile10); + targetTiles.push_back(ttile11); + + vector<Tile*> retval; + + unsigned long targetTileArea = 0; + unsigned long sourceTileArea = 0; + unsigned long targetTileDomain = 0; + unsigned long updatedArea = 0; + bool intersection = false; + + r_Minterval intersectUpdateDomain; + + bool computed = true; + + cout << "Target Tiles" << endl; + for (targetIt = targetTiles.begin(); targetIt != targetTiles.end(); targetIt++) + cout << (*targetIt)->getDomain() << endl; + cout << endl << "Source Tiles" << endl; + for (sourceIt = sourceTiles.begin(); sourceIt != sourceTiles.end(); sourceIt++) + cout << (*sourceIt)->getDomain() << endl; + cout << endl; + cout << "Checking if only update, insert or update and insert" << endl; + + for (sourceIt = sourceTiles.begin(); sourceIt != sourceTiles.end(); sourceIt++) + { + intersection = false; + sourceTileArea = sourceTileArea + (*sourceIt)->getDomain().cell_count(); + cout << "SourceDomain " << (*sourceIt)->getDomain() << " source area is " << sourceTileArea << endl; + for (targetIt = targetTiles.begin(); targetIt != targetTiles.end(); targetIt++) + { + if (computed) + { + targetTileArea = targetTileArea + (*targetIt)->getDomain().cell_count(); + cout << "Target Tile " << (*targetIt)->getDomain() << " area " << targetTileArea << endl; + } + + if( (*sourceIt)->getDomain().intersects_with( (*targetIt)->getDomain() ) ) + { + cout << "Intersection" << endl; + intersection = true; + intersectUpdateDomain = (*sourceIt)->getDomain().create_intersection( (*targetIt)->getDomain() ); + cout << "Updated " << intersectUpdateDomain << " on source " << (*sourceIt)->getDomain() << " and target " << (*targetIt)->getDomain() << endl; + updatedArea = updatedArea + intersectUpdateDomain.cell_count(); + (*targetIt)->execUnaryOp(Ops::OP_IDENTITY, intersectUpdateDomain, *sourceIt, intersectUpdateDomain ); + } + } + if (!intersection) + { + // Create a new persistent tile, copy the transient data, + // and insert it into the target mdd object. + cout << "No Intersection" << endl; + TransTile* newPersTile = new TransTile((*sourceIt)->getDomain(), o, (*sourceIt)->getDataFormat()); + newPersTile->execUnaryOp(Ops::OP_IDENTITY, (*sourceIt)->getDomain(), *sourceIt, (*sourceIt)->getDomain()); + //targetObj->insertTile( newPersTile ); + updatedArea = updatedArea + (*sourceIt)->getDomain().cell_count(); + } + computed = false; + } + cout << "Source Domain " << sourceDom << " has area " << sourceDom.cell_count() << endl; + cout << "Source Tile Area " << sourceTileArea << endl; + cout << "Target Tile Area " << targetTileArea << endl; + cout << "Updated Area " << updatedArea << endl << endl; + // insert the tile + + if (sourceTileArea <= updatedArea) + { + cout << "and all sources were used" << endl; + } + else { + cout << "and there are still some cells to do" << endl << endl; + + for (retvalIt = sourceTiles.begin(); retvalIt != sourceTiles.end(); retvalIt++) + { + sourceDomains.push_back((*retvalIt)->getDomain()); + } + + for (retvalIt = targetTiles.begin(); retvalIt != targetTiles.end(); retvalIt++) + { + targetDomains.push_back((*retvalIt)->getDomain()); + } + + r_Tiler tiler(sourceDomains, targetDomains); + tiler.split(); + tiler.removeCoveredDomains(); + tiler.removeDoubleDomains(); + retvalDomains = tiler.getTiledDomains(); + cout << "we have now" << endl; + for (retvalDIt = retvalDomains.begin(); retvalDIt != retvalDomains.end(); retvalDIt++) + cout << (*retvalDIt) << endl; + tiler.mergeDomains(); + retvalDomains = tiler.getTiledDomains(); + cout << "we have now" << endl; + for (retvalDIt = retvalDomains.begin(); retvalDIt != retvalDomains.end(); retvalDIt++) + cout << (*retvalDIt) << endl; + vector<Tile*> t = tiler.generateTransTiles(sourceTiles); + for (retvalIt = targetTiles.begin(); retvalIt != targetTiles.end(); retvalIt++) + output.execUnaryOp(Ops::OP_IDENTITY, (*retvalIt)->getDomain(), (*retvalIt), (*retvalIt)->getDomain()); + for (retvalIt = t.begin(); retvalIt != t.end(); retvalIt++) + output.execUnaryOp(Ops::OP_IDENTITY, (*retvalIt)->getDomain(), (*retvalIt), (*retvalIt)->getDomain()); + RManDebug = 30; + output.printStatus(cout); + RManDebug = 1; + } + } + diff --git a/tilemgr/tile.cc b/tilemgr/tile.cc new file mode 100644 index 0000000..627a336 --- /dev/null +++ b/tilemgr/tile.cc @@ -0,0 +1,1187 @@ +#include "mymalloc/mymalloc.h" + +/* +* This file is part of rasdaman community. +* +* Rasdaman community 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 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +*/ + +/************************************************************* + * + * + * PURPOSE: + * Tiles store BLOBTiles together with their type and + * their coordinates. + * + * + * COMMENTS: + * none + * + ************************************************************/ + +static const char rcsid[] = "@(#)cachetamgr,Tile: $Id: tile.cc,v 1.79 2005/09/03 21:05:53 rasdev Exp $"; + +#include <iostream> +#include "catalogmgr/ops.hh" +#include "tile.hh" +#include "relblobif/blobtile.hh" +#include "reladminif/adminif.hh" +#include "relblobif/inlinetile.hh" +#include "compression/tilecompression.hh" +#include "raslib/rmdebug.hh" +#include "raslib/miter.hh" +#include "raslib/miterf.hh" +#include "raslib/miterd.hh" +#include "raslib/basetype.hh" + +#include <cstring> + +const Tile& +Tile::operator=(const Tile& tile) + { + if(this != &tile) + { + type = tile.type; + domain = tile.domain; + //cloning is faster than recreation + if (tile.compEngine != NULL) { + if(compEngine != NULL) { + delete compEngine; + } + compEngine = tile.compEngine->clone(); + } + blobTile->resize(tile.blobTile->getSize()); + blobTile->setDataFormat(tile.blobTile->getDataFormat()); + blobTile->setCurrentFormat(tile.blobTile->getCurrentFormat()); + memcpy(blobTile->getCells(), tile.blobTile->getCells(), blobTile->getSize()); + setParameters(tile.getParameters()); + } + return *this; + } + +Tile::Tile(const Tile& tile) + : domain(tile.domain), + type(tile.type), + blobTile((DBTile*)NULL), + //cloning is faster than recreation + compEngine(NULL), + params(NULL) + { + if (tile.compEngine != NULL) + compEngine = tile.compEngine->clone(); + if (RMInit::useTileContainer) + blobTile = new InlineTile(tile.blobTile->getSize(), tile.blobTile->getCells(), tile.blobTile->getDataFormat()); + else + blobTile = new BLOBTile(tile.blobTile->getSize(), tile.blobTile->getCells(), tile.blobTile->getDataFormat()); + blobTile->setCurrentFormat(tile.blobTile->getCurrentFormat()); + setParameters(tile.getParameters()); + } + +Tile::Tile(std::vector<Tile*>* tilesVec) + : domain(), + type(NULL), + compEngine(NULL), + params(NULL), + blobTile((DBTile*)NULL) + { + // iterators for tiles + std::vector<Tile*>::iterator tileIt = tilesVec->begin(); + std::vector<Tile*>::iterator tileEnd = tilesVec->end(); + domain = (*(tileIt++))->getDomain(); + while (tileIt != tilesVec->end()) + { + domain.closure_with((*(tileIt++))->getDomain()); + } + tileIt = tilesVec->begin(); + // initialize type with type of first tile + type = (*tileIt)->getType(); + if (RMInit::useTileContainer) + blobTile = new InlineTile(getSize(), (char)0, (*tileIt)->getDataFormat()); + else + blobTile = new BLOBTile(getSize(), (char)0, (*tileIt)->getDataFormat()); + // initialize compression with compression of first tile + //cloning is faster than recreation + if ((*tileIt)->compEngine != NULL) + compEngine = (*tileIt)->compEngine->clone(); + setParameters((*tileIt)->getParameters()); + // initialize domain + domain = (*(tileIt++))->getDomain(); + while (tileIt != tileEnd) + domain.closure_with((*(tileIt++))->getDomain()); + + // insert all tiles in the result tile + tileIt = tilesVec->begin(); + while (tileIt != tileEnd) + { + const r_Minterval& currDom = (*tileIt)->getDomain(); + copyTile(currDom, (*tileIt), currDom); + tileIt++; + } + } + +Tile::Tile(std::vector<Tile*>* tilesVec, const r_Minterval& resDom) + : params(NULL), + domain(resDom), + compEngine(NULL) + { + // iterators for tiles + std::vector<Tile*>::iterator tileIt; + // domain of the current tile + r_Minterval currDom; + + // get first Tile + tileIt = tilesVec->begin(); + // initialize type with type of first tile + type = (*tileIt)->getType(); + // initialize compression with compression of first tile + //cloning is faster than recreation + if ((*tileIt)->compEngine != NULL) + compEngine = (*tileIt)->compEngine->clone(); + setParameters((*tileIt)->getParameters()); + + // init contents + if (RMInit::useTileContainer) + blobTile = new InlineTile(getSize(), (char)0, (*tileIt)->getDataFormat()); + else + blobTile = new BLOBTile(getSize(), (char)0, (*tileIt)->getDataFormat()); + + // insert all tiles in the result tile + tileIt = tilesVec->begin(); + while (tileIt != tilesVec->end()) + { + currDom = (*tileIt)->getDomain(); + currDom.intersection_with(resDom); + + copyTile(currDom, (*tileIt), currDom); + + tileIt++; + } + } + +Tile::Tile(const Tile* projTile, const r_Minterval& projDom, const std::set<r_Dimension, std::less<r_Dimension> >* projDimSet) + : domain(projDom.dimension() - projDimSet->size()), + type(projTile->type), + compEngine(NULL), + params(NULL), + blobTile((DBTile*)NULL) + { + // calculate dimension of new Tile + r_Dimension dim = 0; + // pointer to cells in tile to be projected and new tile + char* cellTile = NULL; + char* cellProj = NULL; + + for(dim = 0; dim < projDom.dimension(); dim++) + { + // do not include dimensions projected away + std::set<r_Dimension, std::less<r_Dimension> >::const_iterator tempIt = projDimSet->find(dim); + if(tempIt == projDimSet->end()) + { + domain << projDom[dim]; + } + } + + RMDBGONCE(3, RMDebug::module_tilemgr, "Tile", "domain result: " << domain << " domain original: " << projTile->getDomain()); + + // have to initialize the uncompressed contents in case an operation is called on the tile + //cloning is faster than recreation + if (projTile->compEngine) + compEngine = projTile->compEngine->clone(); + setParameters(projTile->getParameters()); + + // init contents + if (RMInit::useTileContainer) + blobTile = new InlineTile(getSize(), (char)0, projTile->getDataFormat()); + else + blobTile = new BLOBTile(getSize(), (char)0, projTile->getDataFormat()); + // using r_Miter to iterate through tile to be projected and new tile. + r_Miter projTileIter(&projDom, &projTile->getDomain(), type->getSize(), (const char*)projTile->getContents()); + r_Miter newTileIter(&domain, &domain, type->getSize(), blobTile->getCells()); + + // identity operation for base type, used for copying + UnaryOp* op = type->getUnaryOp(Ops::OP_IDENTITY, (BaseType*)type); + + while(!projTileIter.isDone()) + { + cellTile = newTileIter.nextCell(); + cellProj = projTileIter.nextCell(); + RMDBGONCE(3, RMDebug::module_tilemgr, "TransTile", "offset in original: " << (int)(cellProj-((Tile*)projTile)->getContents()) << " {" << (int)*cellProj << "} offset in result: " << (int)((int)(cellTile-getContents())) << " {" << (int)*cellTile << "}"); + // execute operation on cell + (*op)(cellTile, cellProj); + } + + delete op; + } + +Tile::Tile(const r_Minterval& newDom, const BaseType* newType, DBTileId newBLOBTile) + : domain(newDom), + type(newType), + params(NULL), + compEngine(NULL), + blobTile(newBLOBTile) + { + RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","Tile(" << newDom << ", " << newType->getName() << ", blob)"); + } + +Tile::Tile(const r_Minterval& newDom, const BaseType* newType, r_Data_Format newFormat) + : domain(newDom), + params(NULL), + type(newType), + compEngine(NULL), + blobTile((DBTile*)NULL) + { + RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","Tile(new), size " << getSize()); + // note that the size is not correct (usually too big) for compressed + // tiles. Doesn't matter, because resize is called anyway. + if (RMInit::useTileContainer) + blobTile = new InlineTile(getSize(), (char)0, newFormat); + else + blobTile = new BLOBTile(getSize(), (char)0, newFormat); + //not neccessary now + //initCompEngine(); + } + +Tile::Tile(const r_Minterval& newDom, const BaseType* newType, char* newCells, r_Bytes newSize, r_Data_Format newFormat) + : domain(newDom), + params(NULL), + type(newType), + compEngine(NULL), + blobTile((DBTile*)NULL) + { + RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","Tile(), fmt " << newFormat << ", size " << newSize); + r_Data_Format current = r_Array; + if (!newSize) + { + // setting uncompressed contents + newSize = getSize(); + } + else { + // setting compressed contents + current = newFormat; + } + if (RMInit::useTileContainer) + blobTile = new InlineTile(newSize, newCells, newFormat); + else + blobTile = new BLOBTile(newSize, newCells, newFormat); + blobTile->setCurrentFormat(current); + free(newCells); + //not neccessary now + //initCompEngine(); + } + +Tile::Tile(const r_Minterval& newDom, const BaseType* newType, const char* newCells, bool, r_Bytes newSize, r_Data_Format newFormat) + : domain(newDom), + params(NULL), + type(newType), + compEngine(NULL), + blobTile((DBTile*)NULL) + { + RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","Tile(), fmt " << newFormat << ", size " << newSize); + r_Data_Format current = r_Array; + if (!newSize) + { + // setting uncompressed contents + newSize = getSize(); + } + else { + // setting compressed contents + current = newFormat; + } + if (RMInit::useTileContainer) + blobTile = new InlineTile(newSize, newCells, newFormat); + else + blobTile = new BLOBTile(newSize, newCells, newFormat); + blobTile->setCurrentFormat(current); + // this one doesn't do this stupid thing: free(newCells); + //not neccessary now + //initCompEngine(); + } + +void +Tile::initCompEngine() const + { + if (compEngine == NULL) + { + char* typeStruct = type->getTypeStructure(); + r_Base_Type *useType = (r_Base_Type*)(r_Type::get_any_type(typeStruct)); + compEngine = r_Tile_Compression::create(blobTile->getDataFormat(), domain, useType); + delete useType; + free(typeStruct); + } + } + +void +Tile::setCompressionFormat(r_Data_Format newFormat) + { + if (blobTile->getDataFormat() != newFormat) + { + decompress(); + delete compEngine; + char* typeStruct = type->getTypeStructure(); + r_Base_Type *useType = (r_Base_Type*)(r_Type::get_any_type(typeStruct)); + compEngine = r_Tile_Compression::create(newFormat, domain, useType); + delete useType; + free(typeStruct); + blobTile->setDataFormat(newFormat); + } + } + +void +Tile::setPersistent(bool state) + { + blobTile->setPersistent(state); + } + +r_Bytes +Tile::getCompressedSize() const + { + RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","getCompressedSize()"); + compress(); + return blobTile->getSize(); + } + +const char* +Tile::getCompressedContents() const + { + RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","getCompressedContents() const"); + compress(); + const char* cellPtr = blobTile->getCells(); + return cellPtr; + } + +bool +Tile::isPersistent() const + { + return blobTile->isPersistent(); + } + +Tile::~Tile() + { + RMDBGONCE(3, RMDebug::module_rasodmg, "Tile", "~Tile() " << (r_Ptr) this); + // this function has to check now if a tile has to be compressed. + // The old scheme of compression in AdminIf::compCompTiles does + // not work, because tiles may be destroyed before with releaseAll. + compress(); + delete compEngine; + delete [] params; + } + +DBTileId +Tile::getDBTile() + { + return blobTile; + } + +char* +Tile::execCondenseOp(CondenseOp* myOp, const r_Minterval& areaOp) + { + RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execCondenseOp()"); + char* cellOp = NULL; + char* dummy = getContents(); + r_Miter opTileIter(&areaOp, &getDomain(), getType()->getSize(), dummy); +#ifdef RMANBENCHMARK + opTimer.resume(); +#endif + + while(!opTileIter.isDone()) + { + cellOp = opTileIter.nextCell(); + // execute operation on cell + (*myOp)(cellOp); + } + +#ifdef RMANBENCHMARK + opTimer.pause(); +#endif + RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "execCondenseOp()"); + + return myOp->getAccuVal(); + } + + +void +Tile::execUnaryOp(UnaryOp* myOp, const r_Minterval& areaRes, const Tile* opTile, const r_Minterval& areaOp) + { + RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execUnaryOp()"); + char* cellRes = NULL; + const char* cellOp = NULL; + + char* dummy1 = getContents(); + const char* dummy2 = opTile->getContents(); + r_Miter resTileIter(&areaRes, &getDomain(), getType()->getSize(), dummy1); + r_Miter opTileIter(&areaOp, &opTile->getDomain(), opTile->getType()->getSize(), dummy2); + +#ifdef RMANBENCHMARK + opTimer.resume(); +#endif + + while(!resTileIter.isDone()) + { + cellRes = resTileIter.nextCell(); + cellOp = opTileIter.nextCell(); + // execute operation on cell + (*myOp)(cellRes, cellOp); + } + +#ifdef RMANBENCHMARK + opTimer.pause(); +#endif + RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "execUnaryOp()"); + } + +void +Tile::execBinaryOp(BinaryOp* myOp, const r_Minterval& areaRes, const Tile* op1Tile, const r_Minterval& areaOp1, const Tile* op2Tile, const r_Minterval& areaOp2) + + { + if ( myOp == NULL ) + { + throw r_Error (OPERANDSRESULTTYPESNOMATCH); + } + RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execBinaryOp()"); + char* cellRes = NULL; + const char* cellOp1 = NULL; + const char* cellOp2 = NULL; + + char* dummy1 = getContents(); + const char* dummy2 = op1Tile->getContents(); + const char* dummy3 = op2Tile->getContents(); + + r_Miter resTileIter(&areaRes, &getDomain(), getType()->getSize(), dummy1); + r_Miter op1TileIter(&areaOp1, &op1Tile->getDomain(), op1Tile->getType()->getSize(), dummy2); + r_Miter op2TileIter(&areaOp2, &op2Tile->getDomain(), op2Tile->getType()->getSize(), dummy3); + +#ifdef RMANBENCHMARK + opTimer.resume(); +#endif + + while(!resTileIter.isDone()) + { + cellRes = resTileIter.nextCell(); + cellOp1 = op1TileIter.nextCell(); + cellOp2 = op2TileIter.nextCell(); + // execute operation on cell + (*myOp)(cellRes, cellOp1, cellOp2); + } + +#ifdef RMANBENCHMARK + opTimer.pause(); +#endif + RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "execBinaryOp()"); + } + +void +Tile::execConstOp(BinaryOp* myOp, const r_Minterval& areaRes, const Tile* opTile, const r_Minterval& areaOp, const char* cell, int constPos) + { + RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execConstOp()"); + char* cellRes = NULL; + const char* cellOp = NULL; + char* dummy1 = getContents(); + const char* dummy2 = opTile->getContents(); + r_Miter resTileIter(&areaRes, &getDomain(), getType()->getSize(), dummy1); + r_Miter opTileIter(&areaOp, &opTile->getDomain(), opTile->getType()->getSize(), dummy2); +#ifdef RMANBENCHMARK + opTimer.resume(); +#endif + + if (constPos == 1) + { + while(!resTileIter.isDone()) + { + cellRes = resTileIter.nextCell(); + cellOp = opTileIter.nextCell(); + // execute operation on cell + (*myOp)(cellRes, cell, cellOp); + } + } + else { + while(!resTileIter.isDone()) + { + cellRes = resTileIter.nextCell(); + cellOp = opTileIter.nextCell(); + // execute operation on cell + (*myOp)(cellRes, cellOp, cell); + } + } + +#ifdef RMANBENCHMARK + opTimer.pause(); +#endif + RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "execConstOp()"); + } + +void +Tile::execMarrayOp(MarrayOp* myOp, const r_Minterval& areaRes, const r_Minterval& areaOp) + { + r_Point pRes(areaRes.dimension()); + r_Point pOp(areaOp.dimension()); + int done = 0; + int recalc = 0; + int i = 0; + int j = 0; + int innerExtent = 0; + int resSize = 0; + int opSize = 0; + int dim = 0; + char* cellRes = NULL; + const char* cellOp = NULL; + + // !!!! check, if areaRes is inside Tile + + resSize = type->getSize(); + + dim = areaRes.dimension(); + innerExtent = (areaOp.get_extent())[dim-1]; + + // initialize points + for(i = 0; i < areaRes.dimension(); i++) + { + pRes << areaRes[i].low(); + pOp << areaOp[i].low(); + } + + cellRes = getCell(calcOffset(pRes)); + // iterate over all cells +#ifdef RMANBENCHMARK + opTimer.resume(); +#endif + while(!done) + { + if(recalc) + { + cellRes = getCell(calcOffset(pRes)); + recalc = 0; + } + + (*myOp)(cellRes, pOp); + + cellRes += resSize; + + // increment coordinates + i = dim - 1; + ++pRes[i]; + ++pOp[i]; + while(pRes[i] > areaRes[i].high()) + { + recalc = 1; + pRes[i] = areaRes[i].low(); + pOp[i] = areaOp[i].low(); + i--; + if(i < 0) + { + done = 1; + break; + } + ++pRes[i]; + ++pOp[i]; + } + } +#ifdef RMANBENCHMARK + opTimer.pause(); +#endif + } + +char* +Tile::execGenCondenseOp(GenCondenseOp* myOp, const r_Minterval& areaOp) + { + r_Point pOp(areaOp.dimension()); + int done = 0; + int i = 0; + int dim = areaOp.dimension(); + + // initialize points + for(i = 0; i < areaOp.dimension(); i++) + { + pOp << areaOp[i].low(); + } + +#ifdef RMANBENCHMARK + opTimer.resume(); +#endif + // iterate over all cells + while(!done) + { + (*myOp)(pOp); + + // increment coordinates + i = dim - 1; + ++pOp[i]; + while(pOp[i] > areaOp[i].high()) + { + pOp[i] = areaOp[i].low(); + i--; + if(i < 0) + { + done = 1; + break; + } + ++pOp[i]; + } + } +#ifdef RMANBENCHMARK + opTimer.pause(); +#endif + return myOp->getAccuVal(); + } + + +#ifdef RMANDEBUG +#define CHECK_ITER_SYNC(a,b) \ + if (a.isDone() != b.isDone()) {RMDBGONCE(3, RMDebug::module_tilemgr, "Tile", "iterators out of sync!");} +#else +#define CHECK_ITER_SYNC(a,b) +#endif + +template<class T> +static inline void tile_scale_core(r_Miter &iterDest, r_MiterFloat &iterSrc, T *dummy) + { + while (!iterDest.isDone()) + { + const T* srcPtr = (const T*)iterSrc.nextCell(); + T* destPtr = (T*)iterDest.nextCell(); + *destPtr = *srcPtr; + + CHECK_ITER_SYNC(iterSrc, iterDest) + } + CHECK_ITER_SYNC(iterSrc, iterDest) + } + +#ifdef BLVAHELP + +void fast_scale_resample_array(char *dest, const char *src, const r_Minterval &destIv, const r_Minterval &srcIv, const r_Minterval &iterDom, unsigned int type_len, unsigned int length) + { + r_MiterDirect destIter((void*)dest, destIv, destIv, type_len, 1); + r_MiterDirect subIter((void*)src, srcIv, iterDom, type_len, 1); + r_MiterDirect srcIter((void*)src, srcIv, iterDom, type_len, length); + unsigned int dim = (unsigned int)srcIv.dimension(); + unsigned int i; + + for (i=0; i<dim; i++) + { + subIter.id[i].low = 0; + } + + while (srcIter.done == 0) + { + double sum = 0; + unsigned int count = 0; + + if (destIter.done != 0) cout << "dest out of sync!" << endl; + if (srcIter.id[dim-1].pos == srcIter.id[dim-1].low) + { + cout << srcIter << " : " << destIter << endl; + } + + // init sub iterator + subIter.done = 0; + for (i=0; i<dim; i++) + { + long rest; + + subIter.id[i].pos = 0; + subIter.id[i].data = srcIter.getData(); + rest = srcIter.id[i].high - srcIter.id[i].pos; + if (rest >= (long)length) rest = (long)length-1; + subIter.id[i].high = rest; + //count *= rest+1; + } + while (subIter.done == 0) + { + sum += *((const unsigned char*)(subIter.getData())); + ++subIter; + count++; + } + + cout<<"Sum="<<sum<<" count="<<count<<endl; + // use round to nearest + *((char*)(destIter.getData())) = (char)(sum / count + 0.5); + //cout << (long)(((const T*)(srcIter.getData())) - src) << " , " << (long)(((T*)(destIter.getData())) - dest) << endl; + ++srcIter; + ++destIter; + } + cout << "End: " << srcIter << " : " << destIter << endl; + if (destIter.done == 0) cout << "dest out of sync!" << endl; + } +#endif + +void +Tile::execScaleOp(const Tile* opTile, const r_Minterval& sourceDomain, const r_Point& origin, const std::vector<double>& scaleFactors) + { + // origin is not used in this version + RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execScaleOp()") + +#ifdef BLVAHELP + fast_scale_resample_array((char*)getContents(),((Tile*)opTile)->getContents(), domain, opTile->getDomain(), sourceDomain, 1, 2); +#else + + int typeLength = getType()->getSize(); + const char *srcPtr = ((Tile*)opTile)->getContents(); + + r_MiterFloat iterSrc((Tile*)opTile, (r_Minterval&)sourceDomain, domain); + r_Miter iterDest(&domain, &domain, typeLength, getContents()); + + // optimize for common basetypes + switch (typeLength) + { + case 1: + tile_scale_core(iterDest, iterSrc, (char*)0); + break; + case 2: + tile_scale_core(iterDest, iterSrc, (short*)0); + break; + case 4: + tile_scale_core(iterDest, iterSrc, (long*)0); + break; + case 8: + tile_scale_core(iterDest, iterSrc, (double*)0); + break; + default: + while (!iterDest.isDone()) + { + char *destPtr = iterDest.nextCell(); + srcPtr = iterSrc.nextCell(); + memcpy(destPtr, srcPtr, typeLength); + CHECK_ITER_SYNC(iterSrc, iterDest) + } + CHECK_ITER_SYNC(iterSrc, iterDest) + break; + } + +#endif + RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "leaving Tile::execScaleOp()") + } + +// the used version +int +Tile::scaleGetDomain(const r_Minterval& areaOp, const std::vector<double>& scaleFactors, r_Minterval &areaScaled) + { + RMDBGENTER(2, RMDebug::module_tilemgr, "Tile", "scaleGetDomain() - second version") + + try { + areaScaled= areaOp.create_scale(scaleFactors); + } + catch(r_Error& err) { + //error on scalling + RMDBGEXIT(2, RMDebug::module_tilemgr, "Tile", "scaleGetDomain(): areaOp = " << areaOp << " error performing scale") + return 0; + } + + RMDBGEXIT(2, RMDebug::module_tilemgr, "Tile", "scaleGetDomain(): areaOp = " << areaOp << ", scaled = " << areaScaled) + + return 1; + } + + +void +Tile::copyTile(const r_Minterval &areaRes, const Tile *opTile, const r_Minterval &areaOp) + { + RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "copyTile(" << areaRes << ", " << (r_Ptr)opTile << "," << areaOp << ")"); + + const char *cellOp = NULL; + char *cellRes = NULL; + + // this may trigger decompression + cellOp = opTile->getContents(); + cellRes = getContents(); + + r_Dimension dim = areaRes.dimension(); + r_Range width = areaRes[dim-1].get_extent(); + unsigned int tsize = getType()->getSize(); + unsigned int tsizeOp = opTile->getType()->getSize(); + + if (tsize != tsizeOp) { + RMDBGONCE(0, RMDebug::module_tilemgr, "Tile", "copyTile() ERROR: type sizes incompatible!" + << endl << "this type: " << getType()->getName() << "(" << tsize << "), opTile type: " + << opTile->getType()->getName() << "(" << tsizeOp << ")" ); + // FIXME here we have to check if is appropiate to continue + } + + // these iterators iterate last dimension first, i.e. minimal step size + r_MiterDirect resTileIter((void*)cellRes, getDomain(), areaRes, tsize); + r_MiterDirect opTileIter((void*)cellOp, opTile->getDomain(), areaOp, tsize); + +#ifdef RMANBENCHMARK + opTiler.resume(); +#endif + + while (!resTileIter.isDone()) + { + // copy entire line (continuous chunk in last dimension) in one go + memcpy(resTileIter.getData(), opTileIter.getData(), width * tsize); + // force overflow of last dimension + resTileIter.id[dim-1].pos += width; + opTileIter.id[dim-1].pos += width; + // iterate; the last dimension will always overflow now + ++resTileIter; + ++opTileIter; + } + +#ifdef RMANBENCHMARK + opTimer.pause(); +#endif + + RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "copyTile(" << areaRes << ", " << (r_Ptr)opTile << "," << areaOp << ")"); + } + +std::vector<Tile*>* +Tile::splitTile(r_Minterval resDom, int storageDomain) + { + // domain of current tile + r_Minterval currDom(resDom.dimension()); + // type of result tiles + const BaseType* resType; + // iterators for tiles + std::vector<Tile*>* resultVec = new std::vector<Tile*>; + // pointer to generated current tile + Tile* smallTile; + // current factor for translating + r_Point cursor(resDom.dimension()); + // origin of big tile + r_Point origin; + // size of result tiles + r_Point tileSize; + // flag + int done = 0; + // for loops + int i = 0; + + // initialize cursor + for(i = 0; i < cursor.dimension(); i++) + cursor[i] = 0; + // calculate size of Tiles + tileSize = resDom.get_extent(); + // initialize resType + resType = this->getType(); + // origin of bigTile + origin = (this->getDomain()).get_origin(); + + // initialize currDom + for(i = 0; i < cursor.dimension(); i++) + currDom << r_Sinterval(origin[i], origin[i] + tileSize[i] - 1); + // resets resDom to lower left side of bigTile + resDom = currDom; + + // intersect with bigTile + currDom.intersection_with(this->getDomain()); + initCompEngine(); + // iterate with smallTile over bigTile + while(!done) + { + currDom.intersection_with(this->getDomain()); + + // create new smallTile + smallTile = new Tile(currDom, resType, compEngine->get_data_format()); + // fill it with relevant area + smallTile->copyTile(currDom, this, currDom); + // insert it in result vector + resultVec->push_back(smallTile); + + // increment cursor, start with highest dimension + i = cursor.dimension() - 1; + cursor[i] += tileSize[i]; + // move cursor + currDom = resDom.create_translation(cursor); + while(!(currDom.intersects_with(this->getDomain()))) + { + cursor[i] = 0; + i--; + if(i < 0) + { + done = 1; + break; + } + cursor[i] += tileSize[i]; + // move cursor + currDom = resDom.create_translation(cursor); + } + } + return resultVec; + } + +void +Tile::printStatus(unsigned int level, std::ostream& stream) const + { + r_Point p(domain.dimension()); + int done = 0; + int i = 0; + const char* cell; + int dim = domain.dimension(); + + // print the contents only on very high debug level + + // initialize point + for(i = 0; i < dim; i++) + { + p << domain[i].low(); + } + + // iterate over all cells + while(!done) + { + // print cell + cell = getCell(calcOffset(p)); + type->printCell(stream, cell); + + // increment coordinate + i = dim - 1; + while(++p[i] > domain[i].high()) + { + stream << endl; + p[i] = domain[i].low(); + i--; + if(i < 0) + { + done = 1; + break; + } + } + if(i < (dim - 2)) stream << endl; + } + } + +char* +Tile::getCell(const r_Point& aPoint) + { + r_Area cellOffset = domain.cell_offset(aPoint); + return getCell(cellOffset); + } + +const char* +Tile::getCell(const r_Point& aPoint) const + { + r_Area cellOffset = domain.cell_offset(aPoint); + return getCell(cellOffset); + } + +void +Tile::setCompressionEngine(r_Tile_Compression* newCompAlg) + { + decompress(); + delete compEngine; + compEngine = newCompAlg; + blobTile->setDataFormat(compEngine->get_data_format()); + } + +const r_Minterval& +Tile::getDomain() const + { + return domain; + } + +const BaseType* +Tile::getType() const + { + return type; + } + +r_Dimension +Tile::getDimension() const + { + return domain.dimension(); + } + +r_Bytes +Tile::getSize() const + { + return domain.cell_count() * type->getSize(); + } + +r_Data_Format +Tile::getDataFormat() const + { + return blobTile->getDataFormat(); + } + +const char* +Tile::getCell(r_Area index) const + { + decompress(); + return &(blobTile->getCells()[index * type->getSize()]); + } + +char* +Tile::getCell(r_Area index) + { + decompress(); + return &(blobTile->getCells()[index * type->getSize()]); + } + +void +Tile::setCell(r_Area index, const char* newCell) + { + char* cells = getCell(index); + int typeSize = type->getSize(); + for (int i = 0; i < typeSize; i++) + cells[i] = newCell[i]; + } + +char* +Tile::getContents() + { + decompress(); + return blobTile->getCells(); + } + +const char* +Tile::getContents() const + { + decompress(); + return blobTile->getCells(); + } + +void +Tile::setContents(char* newContents) + { + decompress(); + blobTile->setCells(newContents); + } + +void +Tile::setParameters(const char *par) + { + delete [] params; + if (par != NULL) + { + params = new char[strlen(par) + 1]; + strcpy(params, par); + } + else + params = NULL; + } + +const char* +Tile::getParameters() const + { + return params; + } + +const r_Tile_Compression* +Tile::getCompressionEngine() const + { + return compEngine; + } + +void +Tile::compress() const + { + if (blobTile->getCurrentFormat() != blobTile->getDataFormat()) + { + initCompEngine(); + r_ULong compressedSize = 0; + char* compressedData = (char*)(compEngine->compress(blobTile->getCells(), compressedSize, params)); + if (!AdminIf::isReadOnlyTA()) + { + r_ULong sizee = getSize(); + if (compressedSize > sizee) + { + RMInit::logOut << "Warning: overriding compression setting(" << blobTile->getDataFormat() << ") to " + << r_Array << " for tile " << getDomain() + << " " << blobTile->getOId() << " because compressed size( " << compressedSize + << " bytes) > uncompressed size( " << sizee << " bytes)" << endl; + r_Tile_Compression* compEngineN = r_Tile_Compression::create(r_Array, getDomain(), compEngine->get_base_type()); + delete compEngine; + compEngine = compEngineN; + compEngineN = NULL; + ((DBTile*)blobTile.ptr())->setDataFormat(compEngine->get_data_format()); + free(compressedData); + compressedData = NULL; + compressedSize = sizee; + //not neccessary because already there + //blobTile->setNoModificationData(compressedData); + } + else { + blobTile->setNoModificationData(compressedData); + } + } + else { + blobTile->setNoModificationData(compressedData); + } + blobTile->setNoModificationSize(compressedSize); + blobTile->setCurrentFormat(compEngine->get_data_format()); + } + } + +bool +Tile::decompress() const + { + bool retval = true; + if (blobTile->getCurrentFormat() != r_Array) + { + initCompEngine(); + bool wrongDecompress = false; + r_Bytes compressedSize = blobTile->getSize(); + char* decompressedData = (char*)(compEngine->decompress(blobTile->getCells(), blobTile->getSize(), params)); + if (decompressedData == NULL) + { + RMInit::logOut << "Error: decompress returned NULL " << blobTile->getOId() << " " << getDomain() << endl; + wrongDecompress = true; + decompressedData = (char*)mymalloc(getSize() * sizeof(char)); + memset(decompressedData, 0, getSize()); + RMInit::logOut << "Error fixed by returning empty data. "; + if (!AdminIf::isReadOnlyTA()) + { + ((DBTile*)blobTile.ptr())->setModified(); + RMInit::logOut << "Fix was made persistent."; + } + RMInit::logOut << endl; + retval = false; + } + blobTile->setNoModificationData(decompressedData); + blobTile->setNoModificationSize(getSize()); + blobTile->setCurrentFormat(r_Array); + } + else { + if (getSize() != blobTile->getSize()) + { + RMInit::logOut << "Error: tile with wrong size " << blobTile->getOId() << " " << getDomain() << " is " << blobTile->getSize() << " should be " << getSize() << " format " << blobTile->getDataFormat() << endl; + char* tempPtr = (char*)mymalloc(getSize() * sizeof(char)); + memset(tempPtr, '\0', getSize()*sizeof(char)); + if(getSize() < blobTile->getSize()) + { + memcpy(tempPtr, blobTile->getCells(), getSize()); + } + else { + memcpy(tempPtr, blobTile->getCells(), blobTile->getSize()); + } + ((DBTile*)blobTile.ptr())->setCells(tempPtr); + blobTile->setNoModificationSize(getSize()); + RMInit::logOut << "Error fixed by resizing and copying data" << endl; + retval = false; + } + } + return retval; + } + + +r_Bytes +Tile::calcOffset(const r_Point& point) const + { + int i = 0; + r_Bytes offset = 0; + r_Bytes factor = 1; + + // calculate offset + for(i = domain.dimension() - 1; i >= 0; i--) + { + offset += (point[i] - domain[i].low()) * factor; + factor *= domain[i].high() - domain[i].low() + 1; + } + + return offset; + } diff --git a/tilemgr/tile.hh b/tilemgr/tile.hh new file mode 100644 index 0000000..5534fda --- /dev/null +++ b/tilemgr/tile.hh @@ -0,0 +1,391 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community 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 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +*/ + +/************************************************************* + * + * + * PURPOSE: + * Tile is the abstract base class for persTile, transTile + * and constTile + * + * + * COMMENTS: + * + ************************************************************/ + +#ifndef _TILE_HH_ +#define _TILE_HH_ + +#include <vector> +#include <set> + +#include "raslib/minterval.hh" // for r_Minterval +#include "raslib/point.hh" // for r_Point +#include "raslib/mddtypes.hh" // for r_Data_Format +#include "catalogmgr/ops.hh" // for Ops::OpType +#include "relcatalogif/basetype.hh" // for BaseType +#include "relblobif/tileid.hh" +#include "relblobif/dbtile.hh" +#include "reladminif/dbref.hh" + +#ifdef RMANBENCHMARK +#include "raslib/rmdebug.hh" // for RMTimer +#endif +class KeyObject; +class PersMDDObjIx; +class r_Tile_Compression; + + +//@ManMemo: Module: {\bf cachetamgr}. + +/*@Doc: +Tile can be compressed with different algorithms which are implemented as subclasses of \Ref{Compression}. For uncompressed tiles, the special +subclass NoCompression is used. + +{\bf Interdependencies} + +Tile uses a pointer to \Ref{BaseType} to store the base type of the Tile. +It uses a \Ref{r_Minterval} to store the domain of the Tile. +Pointers to Tiles are used by many classes. +Compression is done in subclasses of \Ref{Compression}. + +Persistent Tiles are created either by servercomm, when data is received from a client, or by indexif if a BLOBTile is retrieved from the +index. The query tree can also create tiles in case of INSERT or UPDATE queries, and Tile::splitTile creates new tiles. +*/ + +class Tile +{ + public: + + /// assignment operator (needed, as class uses dynamic memory). + const Tile& operator=(const Tile& cell); + + Tile(const r_Minterval& newDom, const BaseType* newType, DBTileId newBLOBTile); + /*Doc + Constructs a new Tile with basetype {\tt newType} and spatial + domain {\tt newDom}. Its contents are stored in \Ref{BLOBTile} + {\tt newBLOBTile}. The contents are potentially compressed. + */ + Tile(const Tile& tile); + /// constructs a TransTile joined out of the Tiles in {\tt tilesVec}. + Tile(std::vector<Tile*>* tilesVec); + /*@Doc: + Constructs a new Tile out of the vector {\tt tilesVec} + containing pointers to tiles. The Tile created has the + closure of the domains of all tiles in the vector as it's domain + and the same base type. The tiles should not overlap and must have + the same basetype and dimension. Non filled areas in the created + tile are of undefined value. The contents are copied, the memory + of the tiles and the vector has to be freed by the caller. The + resulting Tile is by default uncompressed. + */ + /*@ManMemo: + constructs a Tile with the domain {\tt resDom} + and the contents joined out of the Tiles in {\tt tilesVec}. + */ + Tile(std::vector<Tile*>* tilesVec, const r_Minterval& resDom); + /*@Doc: + Constructs a new Tile out of the vector {\tt tilesVec} + containing pointers to tiles. The contents which fall in the area + {\tt resDom} are copied into the new Tile. The Tile + created has the domain {\tt resDom} and the same base type as the + Tiles in {\tt tilesVec}. The tiles should not overlap and must + have the same basetype and dimension. Non filled areas in the + created tile are of undefined value. The memory of the tiles and + the vector has to be freed by the caller. Every tile in {\tt + tilesVec} has to overlap with {\tt resDom}. + */ + /// constructs Tile as projection of {\tt projTile}. + Tile(const Tile* projTile, const r_Minterval& projDom, const std::set<r_Dimension, std::less<r_Dimension> >* projDim); + /*@Doc: + Constructs a new Tile out of the projection of Tile {\tt + projTile} with the dimensions given in {\tt projDim} projected + away (zero based dimension counting!). Only the area specified in + projDom is used for the new Tile. {\tt projDom} must have the + same dimension as the domain of {\tt projTile}. Dimensions + projected away must have the coordinate to be projected at + as domain, e.g. 28:28. + */ + /*@ManMemo: constructs a Tile with base type {\tt newType} and + spatial domain {\tt newDom}. */ + Tile(const r_Minterval& newDom, const BaseType* newType, r_Data_Format newFormat = r_Array); + /*@Doc + The contents are undefined! This constructor should usually not + be used. + */ + /// constructs a Tile with contents {\tt newCells}. + Tile(const r_Minterval& newDom, const BaseType* newType, char* newCells, r_Bytes newSize = 0, r_Data_Format newFormat = r_Array); + /*Doc + Constructs a new Tile with basetype {\tt newType} and spatial + domain {\tt newDom}. The char array {\tt newCells} contains the + potentially compressed contents of the new Tile. The memory for + the cells is managed by Tile and has to be allocated with + malloc(). If newSize is 0, it is assumed to be uncompressed contents, + and the size is calculated from domain and base type. + */ + Tile(const r_Minterval& newDom, const BaseType* newType, const char* newCells, bool, r_Bytes newSize = 0, r_Data_Format newFormat = r_Array); + /*Doc + Constructs a new Tile with basetype {\tt newType} and spatial + domain {\tt newDom}. The char array {\tt newCells} contains the + potentially compressed contents of the new Tile. 'bool' is used only, + for making the difference between this constructor and the upper one. + This one doesn't delete the passed data! + If newSize is 0, it is assumed to be uncompressed contents, + and the size is calculated from domain and base type. + */ + //@Man: read methods + //@{ + /// returns the spatial domain of the tile. + const r_Minterval& getDomain() const; + /// returns the BaseType of the tile. + const BaseType* getType() const; + /// returns the dimension of the tile. + r_Dimension getDimension() const; + /// returns size of the (uncompressed) contents of the tile in chars. + r_Bytes getSize() const; + /// returns size of the contents of the tile as stored in chars. + r_Bytes getCompressedSize() const; + /// returns the format of the data maintained by the tile + r_Data_Format getDataFormat() const; + /// returns true for persistent instances. + bool isPersistent() const; + /// returns true if the contents are currently compressed and must be decompressed in order to be usefull + bool isCompressed() const; + //@} + + //@Man: functions to reading and writing the content. + //@{ + /// access to cell for reading (index is 1D) one cell length is basetype length. + const char* getCell(r_Area index) const; + /// access to cell for modifying (index is 1D). + char* getCell(r_Area index); + /// set cell (index is 1D). + void setCell(r_Area index, const char* newCell); + /// access to a cell using an r_Point. + char* getCell(const r_Point& aPoint); + /// access to a cell using an r_Point. + const char* getCell(const r_Point& aPoint) const; + /// returns pointer to (uncompressed) contents of Tile. + const char* getContents() const; + /// returns pointer to (uncompressed) contents of Tile. + char* getContents(); + /// sets (uncompressed) contents of Tile. + void setContents(char* newContents); + /*@Doc: + The memory for the cells is managed by the Tile and has to be + allocated with malloc(). Its size has to be correct according to + domain and base type of the Tile. + */ + /// returns pointer to compressed contents of Tile as stored. + const char* getCompressedContents() const; + /// returns pointer to potentially compressed contents of Tile as stored. + const r_Tile_Compression* getCompressionEngine() const; + /// this is a quick hack for BLVA (r_RLE seems not to work on DEC) + void setCompressionEngine(r_Tile_Compression* newCompEngine); + /// this is a quick hack for BLVA (r_RLE seems not to work on DEC) + void setCompressionFormat(r_Data_Format newFormat); + //@} + + //@Man: functions related to compression + //@{ + /// set parameters for compression/decompression + void setParameters(const char *par); + /// get compression/decompression parameters + const char *getParameters(void) const; + /// make sure the tile is compressed + void compress() const; + /// make sure the tile is decompressed + /// returns true if no errors were encountered and false if black data was generated + bool decompress() const; + //@} + + /// printed output for testing. + void printStatus(unsigned int level = 0, std::ostream &stream = std::cout) const; + /*@Doc: + Prints the contents of the Tile on stream. Prints every cell in + the Tile with the {\tt printCell} function of the \Ref{BaseType}. + For dimensionality > 1, 2D-slices are printed with an empty line + in between. These 2D slices cover the lowest 2 indices (0 and 1). + */ + + void setPersistent(bool state = true); + + /// splits tile in vector of tiles of smaller size. + std::vector<Tile*>* splitTile(r_Minterval resDom, int storageDomain = 0); + /*@Doc: + The Tile is split into subtiles with the same extent as {\tt + resDom}. The storage domain (pers. or transient) of the subtiles is + defined by {\tt storageDomain}. If it is null (default value) they + have the same type (\Ref{TransTile} resp. \Ref{Tile}) as self. + If {\tt storageDomain} is 1, they are persistent, if {\tt storageDomain} + has a value other than 0 or 1, they are made transient. + The algoritm starts with the smallest + coordinate in each dimension, so that if the Tile does not divide + into Tiles of extent {\tt resDom}, the last Tiles in each + dimension may be smaller. The Tiles returned as pointers have to + be freed by the caller! + */ + + + //@Man: methods for carrying out operations + //@{ + /// carries out condense function (const) + char* execCondenseOp(CondenseOp* myOp, const r_Minterval& areaOp); + /*@Doc: + The condense function {\tt myOp} is applied to all cells of self in + the area {\tt areaOp}. The result is stored in myOp which also + gives the start value for the condense operation. The return value + is a pointer to a member of myOp, so it gets invalid if myOp is + deleted! For further information on condense operations see \Ref{Ops}. + */ + + + /// carries out unary function with self as result. + void execUnaryOp(UnaryOp* myOp, const r_Minterval& areaRes, const Tile* opTile, const r_Minterval& areaOp); + /*@Doc: + The unary function {\tt myOp} is applied to all cells of the tile + {\tt opTile} in the area {\tt areaOp}. The result of the + operation is stored in self in the area {\tt areaRes}. The areas + must have the same extent, but may differ in an offset. + */ + + /// carries out binary function with self as result. + void execBinaryOp( BinaryOp* myOp, const r_Minterval& areaRes, + const Tile* op1Tile, const r_Minterval& areaOp1, + const Tile* op2Tile, const r_Minterval& areaOp2); + /*@Doc: + The binary function {\tt myOp} is applied to all cells of the tiles + {\tt op1Tile} and {\tt op2Tile} in the respective areas. The + result of the operation is stored in self in the area {\tt + areaRes}. The areas must have the same extent for all tiles. but + may differ in an offset vector. + */ + + /// carries out binary function with self as result. + virtual void execConstOp( BinaryOp* myOp, const r_Minterval& areaRes, + const Tile* opTile, const r_Minterval& areaOp, + const char* cell, int constPos = 1); + /*@Doc: + The binary function {\tt op} is applied to all cells of the tile + {\tt op1Tile} and the constant {\tt cell} in the area {\tt + areaOp}. If {\tt constPos} is 1, then {\tt const op cell} is + carried out; if it is 2, then {\tt cell op const} is carried out. + The result of the operations is stored in self in the area {\tt + areaRes}. {\tt areaOp} and {\tt areaRes} must have the same + extent, but may differ in an offset. + */ + + + /// fills tile in area {\tt areaRes} using MarrayOp {\tt myOp}. + virtual void execMarrayOp(MarrayOp* myOp, const r_Minterval& areaRes, const r_Minterval& areaOp); + /*@Doc: + {\tt myOp} maps a point to a value. It is important that the base + type specified it the same as the tile has. + */ + + /// executes general condense operation {\tt myOp} in area {\tt areaOp} (const) + static char* execGenCondenseOp(GenCondenseOp* myOp, const r_Minterval& areaOp); + /*@Doc: + {\tt myOp} maps a point to a value. The return values has the resType + defined in {\tt myOp}. The tile is not accessed (static function), + the function is defined here to be located together with the other + operation execution functions. + */ + /// executes scaling operation. + virtual void execScaleOp( const Tile* opTile, const r_Minterval& areaOp, + const r_Point& origin, + const std::vector<double>& scaleFactors); + /*@Doc: + The tile {\tt opTile} is scaled down in each dimension by the + corresponding element in vector {\tt scaleFactors}. The result + is stored in the tile on which the operation is called. Scaling + is done by using a nearest neighbour algorithm based on + {\tt origin} as the point where the scaling process started. + {\tt opTile} has to have the same dimensionality as the result + tile and scaleFactors has to have a corresponding number of + elements. + */ + //@} + /// return spatial domain of result tile for scaling in areaScaled. + /// return 0 if the result tile will be empty. + /// (the same function, but with implicit origin (0,0,...0) and working fine!) + int scaleGetDomain( const r_Minterval& areaOp, + const std::vector<double>& scaleFactors, + r_Minterval& areaScaled); + + /*@Doc: + Return result domain in areaScaled if scaling using the factors in + scaleFactors would be applied in area {\tt areaOp} with the scaling + factors specified in {\tt scaleFactors}. If the tile would become + completely empty, false is returned. This can then be used to create + a temporary tile for the result on which the {\tt execScaleOp} + function can be called. + */ + + /// virtual destructor. + virtual ~Tile(); + + /// copy a subcube from one tile to another + virtual void copyTile(const r_Minterval& areaRes, const Tile *opTile, const r_Minterval& areaOp); + /*@Doc: + The part of opTile covered by areaOp is copied to areaRes of this tile. Identical in functionality to execUnaryOp(OP_IDENTITY, ...) but much faster. + Requires matching base types and matching domains. + */ + + DBTileId getDBTile(); + /*Doc + Returns a pointer to the \Ref{BLOBTile} holding the contents of + the Tile. This function is used to persistently store the + contents of a Tile. + */ + +#ifdef RMANBENCHMARK + // RMTimer for taking O2 times. Could be protected. Is controlled + // in servercomm/servercomm2.cc. + static RMTimer opTimer; +#endif + + protected: + //@Man: utility functions used internally. + //@{ + /// calculate offset in cells + r_Bytes calcOffset(const r_Point& point) const; + // fill cells of size size with pattern newCell of size patSize. + + /// instantiate a compression engine + void initCompEngine() const; + //@} + + /// spatial domain of the tile. + r_Minterval domain; + /// pointer to base type for cells of Tile. + const BaseType* type; + /// Smart pointer to the persistent BLOBTile. + DBTileId blobTile; + /// The compression algorithm + mutable r_Tile_Compression *compEngine; + /// compression parameters + char* params; + }; + +#endif diff --git a/tilemgr/tile.icc b/tilemgr/tile.icc new file mode 100644 index 0000000..cafa4ab --- /dev/null +++ b/tilemgr/tile.icc @@ -0,0 +1 @@ +//moved to tile.cc diff --git a/tilemgr/tiler.cc b/tilemgr/tiler.cc new file mode 100644 index 0000000..9924cd4 --- /dev/null +++ b/tilemgr/tiler.cc @@ -0,0 +1,397 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community 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 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +*/ + +#include "tiler.hh" +#include "tilemgr/tile.hh" + +r_Tiler::r_Tiler(std::vector<r_Minterval>& sourceDomain2s, const std::vector<r_Minterval>& targetDomain2s) + : sourceDomains(sourceDomain2s), + targetDomains(targetDomain2s) + { + } + +void +r_Tiler::mergeDomains() + { + std::vector<r_Minterval>::iterator splitedIt; + std::vector<r_Minterval> temp; + r_Minterval tempDom; + bool merged = false; + while (!splitedDomains.empty()) + { + merged = false; + tempDom = *(splitedDomains.begin()); + splitedDomains.erase(splitedDomains.begin()); + for (splitedIt = splitedDomains.begin(); splitedDomains.end() != splitedIt; splitedIt++) + { + if (tempDom.is_mergeable(*splitedIt)) + { + //cout << "is mergeable " << tempDom << " " << *splitedIt << endl; + tempDom.closure_with(*splitedIt); + //cout << "closure " << tempDom << endl; + splitedDomains.erase(splitedIt); + merged = true; + break; + } + else { + //cout << "is not mergeable " << tempDom << " " << *splitedIt << endl; + } + } + if (merged) + splitedDomains.push_back(tempDom); + else + temp.push_back(tempDom); + } + splitedDomains = temp; + } + +void +r_Tiler::split() + { + std::vector<r_Minterval>::iterator sourceIt; + std::vector<r_Minterval>::iterator retvalIt; + std::vector<r_Minterval> splits; + std::vector<RangePair> points; + + for (sourceIt = sourceDomains.begin(); sourceIt != sourceDomains.end(); sourceIt++) + { + //cout << "starting with source domain " << *sourceIt << endl; + points = computeSplitDimensions(*sourceIt); + splits = splitMinterval(*sourceIt, points); + for (retvalIt = splits.begin(); retvalIt != splits.end(); retvalIt++) + { + splitedDomains.push_back(*retvalIt); + } + //it is either splitted and in retval or not splitted and then there is an error, because not splitted were inserted + } + } + +std::vector<RangePair> +r_Tiler::computeSplitDimensions(const r_Minterval& sourceDomain) const + { + r_Dimension dim = 0; + r_Range slow = 0; + r_Range shigh = 0; + r_Range ilow = 0; + r_Range ihigh = 0; + + std::vector<r_Minterval> intersects; + std::vector<r_Minterval>::iterator intersectIt; + std::vector<r_Minterval>::const_iterator targetIt; + + std::vector<RangePair> points; + std::vector<RangePair>::iterator pointIt; + RangePair pair; + + //cout << "\tfinding the intersections of current source with targets" << endl; + for (targetIt = targetDomains.begin(); targetIt != targetDomains.end(); targetIt++) + { + if ((*targetIt).intersects_with(sourceDomain)) + { + //cout << "\t\tsource intersected target " << *targetIt << endl; + intersects.push_back((*targetIt).create_intersection(sourceDomain)); + } + else { + //cout << "\t\tsource did not intersect target " << *targetIt << endl; + } + } + + //cout << "\titerating through intersecting domains to determine the spliting dimensions" << endl; + for (intersectIt = intersects.begin(); intersectIt != intersects.end(); intersectIt++) + { + //cout << "\t\tstarting to compute split dimensions with " << *intersectIt << endl; + for (dim = 0; dim < (*intersectIt).dimension(); dim++) + { + ilow = (*intersectIt)[dim].low(); + ihigh = (*intersectIt)[dim].high(); + slow = (sourceDomain)[dim].low(); + shigh = (sourceDomain)[dim].high(); + //cout << "\t\t\tdimension " << dim << endl; + //cout << "\t\t\tsource low " << (sourceDomain)[dim].low() << "=" << slow << ", intersect low " << (*intersectIt)[dim].low() << "=" << ilow << endl; + //cout << "\t\t\tsource high " << (sourceDomain)[dim].high() << "=" << shigh << ", intersect high " << (*intersectIt)[dim].high() << "=" << ihigh << endl; + if ((slow <= ilow) & (shigh >= ilow)) + { + pair.first = dim; + pair.second = ilow - 1; + //cout << "\t\t\tadding " << pair.second << endl; + points.push_back(pair); + } + if ((slow <= ihigh) & (shigh >= ihigh)) + { + pair.first = dim; + pair.second = ihigh; + //cout << "\t\t\tadding " << pair.second << endl; + points.push_back(pair); + } + } + //cout << "\t\tfound all split dimensions for the current source with intersect " << *intersectIt << endl; + } + //cout << "\t\t\tfound all split dimensions for source " << sourceDomain << endl; + //for (pointIt = points.begin(); pointIt != points.end(); pointIt++) + //cout << "\t\t\tsplit in dimension " << (*pointIt).first << " at coordinate " << (*pointIt).second << endl; + //cout << "try " << endl; + std::vector<RangePair> temp; + std::vector<RangePair>::iterator tempIt; + RangePair tempP; + bool tempadd = true; + temp.swap(points); + //for (pointIt = points.begin(); pointIt != points.end(); pointIt++) + //cout << "\t\t\tsplit in dimension " << (*pointIt).first << " at coordinate " << (*pointIt).second << endl; + //cout << "try end" << endl; + while (!temp.empty()) + { + tempadd = true; + tempP = *(temp.begin()); + temp.erase(temp.begin()); + for (tempIt = temp.begin(); tempIt != temp.end(); tempIt++) + { + if ((tempP.first == (*tempIt).first) & (tempP.second == (*tempIt).second)) + { + //cout << "matched" << endl; + tempadd = false; + break; + } + } + if (tempadd) + points.push_back(tempP); + } + //cout << "try end 2" << endl; + //for (pointIt = points.begin(); pointIt != points.end(); pointIt++) + //cout << "\t\t\tsplit in dimension " << (*pointIt).first << " at coordinate " << (*pointIt).second << endl; + //cout << "try end 3" << endl; + return points; + } + +std::vector<r_Minterval> +r_Tiler::splitMinterval(const r_Minterval& sourceTile, std::vector<RangePair>& points) + { + std::vector<r_Minterval> splits; + std::vector<r_Minterval> split2s; + std::vector<r_Minterval>::iterator splitIt; + std::vector<r_Minterval>::iterator split2It; + + r_Minterval splitInterval1; + r_Minterval splitInterval2; + + std::vector<RangePair>::iterator pointIt; + + bool addDomain = false; + + r_Dimension dim = 0; + r_Range low = 0; + r_Range high = 0; + r_Range splitCoordinate = 0; + + //initialize the split std::vector. the result will contain a list of splitted domains. + splits.push_back(sourceTile); + + //cout << "\t\tstarting to actually split" << endl; + for (pointIt = points.begin(); pointIt != points.end(); pointIt++) + { + split2s = std::vector<r_Minterval>(); + //cout << "\t\t\tstarting to split at dimension " << (*pointIt).first << " coordinate " << (*pointIt).second << endl; + //cout << "\t\t\titerating through all the tiles to be split, stemming from current source tile" << endl; + while (!splits.empty()) + { + splitIt = splits.begin(); + //cout << "\t\t\t\tsplitting " << (*splitIt) << endl; + addDomain = false; + splitInterval1 = r_Minterval(((*splitIt)).dimension()); + splitInterval2 = r_Minterval(((*splitIt)).dimension()); + //cout << "\t\t\t\ttrying split" << endl; + for (dim = 0; dim < ((*splitIt)).dimension(); dim++) + { + if ((dim == (*pointIt).first)) + { + high = (*splitIt)[dim].high(); + low = (*splitIt)[dim].low(); + splitCoordinate = (*pointIt).second; + if ((splitCoordinate < high) & (splitCoordinate > low)) + { + //cout << "\t\t\t\t\tsplit middle adding [" << low << ":" << splitCoordinate << "]" << endl; + splitInterval1 << r_Sinterval(low, splitCoordinate); + //cout << "\t\t\t\t\tsplit middle adding [" << splitCoordinate+1 << ":" << high << "]" << endl; + splitInterval2 << r_Sinterval(splitCoordinate + 1, high); + addDomain = true; + } + else { + if (splitCoordinate == high) + { + addDomain = true; + if (low == high) + { + //cout << "\t\t\t\t\tsplit high adding [" << low << ":" << low << "]" << endl; + splitInterval1 << r_Sinterval(low, high); + } + else { + //cout << "\t\t\t\t\tsplit high adding [" << low << ":" << high-1<<"]" << endl; + splitInterval1 << r_Sinterval(low, splitCoordinate - 1); + } + + splitInterval2 << r_Sinterval(splitCoordinate, splitCoordinate); + } + else { + if ((*pointIt).second == ((*splitIt))[dim].low()) + { + addDomain = true; + if (low == high) + { + //cout<<"\t\t\t\t\tsplit low adding ["<<low<<":"<<high<< "]"<<endl; + splitInterval1 << r_Sinterval(low, high); + } + else { + //cout<<"\t\t\t\t\tsplit low adding ["<<low+1<<":"<< high<< "]"<<endl; + splitInterval1 << r_Sinterval(low + 1, high); + } + splitInterval2<< r_Sinterval((*pointIt).second,(*pointIt).second); + } + else { + //cout << "\t\t\t\t\tno match, break" << endl; + break; + } + } + } + } + else { + //cout << "\t\t\t\t\tdimension unmatched, adding " << ((*splitIt))[dim] << endl; + splitInterval1 << ((*splitIt))[dim]; + splitInterval2 << ((*splitIt))[dim]; + } + } + if (addDomain) + { + //cout << "\t\t\t\tadding split domain 1 " << splitInterval1 << endl; + split2s.push_back(splitInterval1); + //cout << "\t\t\t\tadding split domain 2 " << splitInterval2 << endl; + split2s.push_back(splitInterval2); + } + else { + //cout << "\t\t\t\tnot adding split domains " << splitInterval1 << " " << splitInterval1 << endl; + //cout << "\t\t\t\tadding because of no splits " << (*splitIt) << endl; + split2s.push_back(*splitIt); + } + splits.erase(splitIt); + } + splits = split2s; + } + //cout << "splitMinterval computed" << endl; + //for (splitIt = splits.begin(); splitIt != splits.end(); splitIt++) + // { + //cout << (*splitIt) << endl; + // } + return splits; + } + +void +r_Tiler::removeCoveredDomains() + { + r_Minterval temp; + std::vector<r_Minterval> retval; + bool kill = false; + std::vector<r_Minterval>::iterator targetIt; + retval.swap(splitedDomains); + while (!retval.empty()) + { + temp = *(retval.begin()); + retval.erase(retval.begin()); + kill = false; + for (targetIt = retval.begin(); targetIt != retval.end(); targetIt++) + { + if ((*targetIt).intersects_with(temp)) + { + kill = true; + break; + } + } + if (!kill) + splitedDomains.push_back(temp); + } + } + +void +r_Tiler::removeDoubleDomains() + { + r_Minterval temp; + std::vector<r_Minterval> retval; + bool kill = false; + std::vector<r_Minterval>::iterator targetIt; + while (!splitedDomains.empty()) + { + temp = *(splitedDomains.begin()); + splitedDomains.erase(splitedDomains.begin()); + kill = false; + for (targetIt = targetDomains.begin(); targetIt != targetDomains.end(); targetIt++) + { + if ((*targetIt).intersects_with(temp)) + { + kill = true; + break; + } + } + if (!kill) + retval.push_back(temp); + } + retval.swap(splitedDomains); + } + +std::vector<r_Minterval> +r_Tiler::getTiledDomains() const + { + return splitedDomains; + } + +std::vector<Tile*> +r_Tiler::generateTiles(const std::vector<Tile*>& sourceTiles) const + { + std::vector<r_Minterval>::const_iterator splitedDomIt; + std::vector<Tile*>::const_iterator sourceTileIt; + std::vector<Tile*> retval; + r_Minterval dummy; + Tile* p = 0; + const BaseType* basetype = (*sourceTiles.begin())->getType(); + r_Data_Format dataformat = (*sourceTiles.begin())->getDataFormat(); + + for (splitedDomIt = splitedDomains.begin(); splitedDomIt != splitedDomains.end(); splitedDomIt++) + { + dummy = *splitedDomIt; + p = new Tile(dummy, basetype, dataformat); + //std::cout << "new tile " << dummy << " " << basetype->getName() << " " << dataformat << " size " << p->getSize() << " other size " << p->getDBTile()->getSize() << std::endl; + for (sourceTileIt = sourceTiles.begin(); sourceTileIt != sourceTiles.end(); sourceTileIt++) + { + //std::cout << " the other tile domain " << (*sourceTileIt)->getDomain() << " type " << (*sourceTileIt)->getType()->getName() << std::endl; + if (dummy.intersects_with((*sourceTileIt)->getDomain())) + { + const r_Minterval& updateDomain = dummy.create_intersection((*sourceTileIt)->getDomain()); + //std::cout << " they intersect. on " << updateDomain << std::endl; + //UnaryOp* tempOp = Ops::getUnaryOp(Ops::OP_IDENTITY, p->getType(), (*sourceTileIt)->getType(), 0, 0); + //causes fmr/abr/umr + p->copyTile(updateDomain, *sourceTileIt, updateDomain); + //p->execUnaryOp(tempOp, dummy.create_intersection((*sourceTileIt)->getDomain()), *sourceTileIt, dummy.create_intersection((*sourceTileIt)->getDomain())); + //delete tempOp; + } + } + retval.push_back(p); + } + return retval; + } + diff --git a/tilemgr/tiler.hh b/tilemgr/tiler.hh new file mode 100644 index 0000000..796ab59 --- /dev/null +++ b/tilemgr/tiler.hh @@ -0,0 +1,93 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community 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 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community 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 rasdaman community. If not, see <http://www.gnu.org/licenses/>. +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see <http://www.rasdaman.org> +* or contact Peter Baumann via <baumann@rasdaman.com>. +*/ + +#ifndef _D_TILER_ +#define _D_TILER_ + +#include "raslib/minterval.hh" +#include <vector> +#include <utility> +//#include<pair> + +class Tile; +class PersTile; +class TransTile; + +typedef std::pair<r_Range,r_Range> RangePair; +typedef std::pair<const r_Range,const r_Range> ConstRangePair; + +class r_Tiler + { + public: + r_Tiler(std::vector<r_Minterval>& sourceDomains, const std::vector<r_Minterval>& targetDomains); + /* + sourceDomains will be splitted. + targetDomains will not be touched. + */ + + void split(); + /* + will split the source domains. + */ + + void removeCoveredDomains(); + /* + removes those splited domains which are covered by target domains. + */ + + void removeDoubleDomains(); + /* + removes those splited domains which are covered by other splited domains. + */ + + void mergeDomains(); + /* + tries to merge splited domains into larger domains. + */ + + std::vector<r_Minterval> getTiledDomains() const; + /* + returns the computed domains. you must call split() first. + */ + + std::vector<Tile*> generateTiles(const std::vector<Tile*>& sourceTiles) const; + /* + uses the previously computed tiled domains to generate the output. + call split, removeCoveredDomains, removeDoubleDomains, mergeDomains first! + memory must be freed by the caller! + */ + + private: + + std::vector<r_Minterval> splitMinterval(const r_Minterval& sourceDomain, std::vector<RangePair>& splitDimensions); + + std::vector<RangePair> computeSplitDimensions(const r_Minterval& sourceDomain) const; + + std::vector<r_Minterval> splitedDomains; + + std::vector<r_Minterval> sourceDomains; + + std::vector<r_Minterval> targetDomains; + }; +#endif + diff --git a/tilemgr/transtile.cc b/tilemgr/transtile.cc new file mode 100644 index 0000000..a23f993 --- /dev/null +++ b/tilemgr/transtile.cc @@ -0,0 +1 @@ +//moved to tile diff --git a/tilemgr/transtile.hh b/tilemgr/transtile.hh new file mode 100644 index 0000000..a23f993 --- /dev/null +++ b/tilemgr/transtile.hh @@ -0,0 +1 @@ +//moved to tile |