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 /indexmgr/test | |
download | rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip |
Initial commitv8.0
Diffstat (limited to 'indexmgr/test')
-rw-r--r-- | indexmgr/test/Makefile | 103 | ||||
-rw-r--r-- | indexmgr/test/test_abc.cc | 373 | ||||
-rw-r--r-- | indexmgr/test/test_clusterix.cc | 338 | ||||
-rw-r--r-- | indexmgr/test/test_dirix.cc | 357 | ||||
-rw-r--r-- | indexmgr/test/test_expix.cc | 488 | ||||
-rw-r--r-- | indexmgr/test/test_hierix.cc | 388 | ||||
-rw-r--r-- | indexmgr/test/test_ix.cc | 517 | ||||
-rw-r--r-- | indexmgr/test/test_ix1.cc | 853 |
8 files changed, 3417 insertions, 0 deletions
diff --git a/indexmgr/test/Makefile b/indexmgr/test/Makefile new file mode 100644 index 0000000..5ae92c2 --- /dev/null +++ b/indexmgr/test/Makefile @@ -0,0 +1,103 @@ +# -*-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 indexmgr +# +# COMMENTS: +# List environment dependencies, known bugs, specialities etc. +# +################################################################## +# +# This is just an example Makefile for a test program. +# The dependency of the test program on the lib of the +# corresponding module is in the Makefile of the module. +# + +######################### Definitions ############################ + +# standard include with general options +include $(RMANBASE)/Makefile.inc + +# all test programs +SRCCXX= test_clusterix.cc test_expix.cc test_ix.cc \ + test_abc.cc test_dirix.cc test_hierix.cc test_ix1.cc +OBJS = ${SRCCXX:%.cc=%.o} +ALLTESTS = ${SRCCXX:%.cc=%} +MISCCLEAN = core + +# some additional flags for compiling and linking +CXXFLAGS := $(STLCXXFLAGS) $(CXXFLAGS) + +# includes in module directory +LDFLAGS += -I$(RMANBASE)/indexif +LDFLAGS := $(STLLDFLAGS) $(LDFLAGS) -L$(SUPPORT_BASE)/lib -lz + + +########################### Targets ############################## + +# make all tests +.PHONY: test +test: $(ALLTESTS) + +# test target for class Index (always make module!) +.PHONY: test_index_target +test_index_target: build_module test_dirix test_clusterix test_expix + +######################## Dependencies ############################ + +# make module +.PHONY: build_module +build_module: + cd $(RMANBASE)/indexmgr; $(MAKE) + +# can not be used as a target (module library is not remade!) + +test_abc: test_abc.o + $(PURIFY) $(CXX) -o $@ $^ -lm + +test_dirix: test_dirix.o $(INDEXMGR) $(INDEXIF) $(RASLIB) $(CACHETAMGR) $(CATALOGIF) $(BLOBIF) $(ADMINIF) $(MDDIF) + $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(LDFLAGS) -o $@ $^ -lm $(QLPARSER) + +test_ix1: test_ix1.o $(INDEXMGR) $(INDEXIF) $(RASLIB) $(CACHETAMGR) $(CATALOGIF) \ + $(BLOBIF) $(ADMINIF) $(MDDIF) $(TOOLS) $(QLPARSER) + $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(LDFLAGS) -o $@ $^ -lm $(QLPARSER) + +test_ix: test_ix.o $(RASLIB) + $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(LDFLAGS) -o $@ $^ -lm + +test_hierix: test_hierix.o $(INDEXMGR) $(INDEXIF) $(RASLIB) $(CACHETAMGR) $(CATALOGIF) $(BLOBIF) $(ADMINIF) $(MDDIF) + $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(LDFLAGS) -o $@ $^ -lm $(QLPARSER) + +test_expix: test_expix.o $(INDEXMGR) $(INDEXIF) $(RASLIB) $(CACHETAMGR) $(CATALOGIF) $(BLOBIF) $(ADMINIF) $(MDDIF) $(TOOLS) $(QLPARSER) + $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(LDFLAGS) -o $@ $^ -lm $(INDEXMGR) + +test_clusterix: test_clusterix.o $(INDEXMGR) $(INDEXIF) $(RASLIB) $(CACHETAMGR) $(CATALOGIF) $(BLOBIF) $(ADMINIF) $(MDDIF) + $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(LDFLAGS) -o $@ $^ -lm $(INDEXIF) $(INDEXMGR) + +# general rules +include $(RMANBASE)/Makefile.rel + +# automatically created dependencies +include Makefile.dep diff --git a/indexmgr/test/test_abc.cc b/indexmgr/test/test_abc.cc new file mode 100644 index 0000000..7c8160b --- /dev/null +++ b/indexmgr/test/test_abc.cc @@ -0,0 +1,373 @@ +/* +* 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>. +/ +/** + * SOURCE: testabc.cc + * + * MODULE: test for A,B,C + * + * PURPOSE: + * Tests a hierarchy of classes where each one, after insertElement( ) + * transforms itself into the superclass. Preparation for Hierarchy + * of indexes DirIx, RegDirIx, etc. + * + * COMMENTS: + * none + * +*/ + +#include <stdlib.h> +#include <iostream.h> +// #include <vector.h> + + +// extern char* myExecArgv0 = ""; + +// #include "raslib/rminit.hh" +//RMINITGLOBALS('C') + +class A +{ +public: + A( ); + A( A* a ); + virtual void insertElement( A*& a ); + virtual A* insertElementTransform( ); + static void insertElementTransformStat( A*& ); + virtual void printStatus( ); + virtual ~A( ); + int* DynAtt_A; + int StatAtt_A; +protected: + void testProtectedA( ); +}; + +A::A( ) + :StatAtt_A(1) +{ + DynAtt_A = new int; + *DynAtt_A = 2; + cout <<"A Constructor"<< endl; +} + +A::A( A* a) + :StatAtt_A( a->StatAtt_A ), DynAtt_A( a->DynAtt_A ) +{ + a->DynAtt_A = 0; +} + +void A::insertElement( A*& a ) +{ + cout <<"A::insertElement( ) "; + printStatus( ); + cout << endl; +} + +A* A::insertElementTransform( ) +{ + cout <<"A::insertElementTransform( ) "; + printStatus( ); + cout << endl; + return this; +} + +void A::insertElementTransformStat( A*& ix ) +{ + cout <<"A::insertElementTransformStat( ) "; + ix->printStatus( ); + cout << endl; +} + +void A::printStatus( ) +{ + cout <<"A: Dyn " << *DynAtt_A <<" Stat "<< StatAtt_A << endl; +} + +A::~A() +{ + cout <<"A Destructor"<< endl; + if (DynAtt_A) delete DynAtt_A; +} + +void A::testProtectedA( ) +{ + cout <<"A::testProtectedA( )"<<endl; +} + +class B: public A +{ +public: + B( ); + B( A* b ); + virtual void insertElement( A*& a ); + virtual A* insertElementTransform( ); + static void insertElementTransformStat( A*& ix ); + virtual void printStatus( ); + virtual ~B( ); + int* DynAtt_B; + int StatAtt_B; + void testProtectedB( ); +}; + +B::B( ) + :A( ),StatAtt_B(3) +{ + DynAtt_B = new int; + *DynAtt_B = 4; + cout <<"B Constructor"<< endl; +} + +B::B( A* b ) + :A(b),StatAtt_B(((B*)b)->StatAtt_B),DynAtt_B(((B*)b)->DynAtt_B) +{ + // use dynamic attributes of b, so that has to delete them + // from origin + ((B*)b)->DynAtt_B = 0; +} + +void B::insertElement( A*& a ) +{ + cout <<"B::insertElement( ) "; + printStatus( ); + cout << endl; + A* c = new A( a ); + delete a; + a = c; +} + +A* B::insertElementTransform( ) +{ + A* thisA = this; + cout <<"B::insertElementTransform( ) "; + printStatus( ); + + A* a = new A(thisA); + delete thisA; + return a; +} + +void B::insertElementTransformStat( A*& ix ) +{ + A* thisA = ix; + cout <<"B::insertElementTransformStat( ) "; + ix->printStatus( ); + + A* a = new A(thisA); + delete thisA; + ix = thisA; +} + +void B::printStatus( ) +{ + cout <<"B: Dyn " << *DynAtt_B <<" Stat "<< StatAtt_B << endl; +} +B::~B() +{ + cout <<"B Destructor"<< endl; + if (DynAtt_B) delete DynAtt_B; +} + +void B::testProtectedB( ) +{ + cout << "B::testProtectedB( ) calling A::testProtectedA( ) on itself: "<< endl; + A::testProtectedA( ); + B objB; + cout << "B::testProtectedB( ) calling A::testProtectedA( ) on another obj B: "<< endl; + objB.testProtectedA( ); + // A objA; + // cout << "B::testProtectedB( ) calling A::testProtectedA( ) on another obj A: "<< endl; + // objA.testProtectedA(); +} + +class C: public B +{ +public: + C( int ); + virtual void insertElement( A*& a ); + virtual A* insertElementTransform( ); + static void insertElementTransformStat( A*& ix ); + virtual void printStatus( ); + virtual ~C( ); + int* DynAtt_C; + int StatAtt_C; +}; + +C::C(int) + :B(), StatAtt_C(5) +{ + DynAtt_C = new int; + *DynAtt_C = 6; + cout <<"C Constructor "<< endl; +} +void C::insertElement( A*& a ) +{ + if( a != this ) + cout << "Unexpected Usage of C::insertElement( ) "<< endl; + cout <<"C::insertElement( ) "; + printStatus( ); + + B* c = new B(a); + delete a; + a = c; +} + +A* C::insertElementTransform( ) +{ + A* thisA = this; + cout <<"C::insertElementTransform( ) "; + printStatus( ); + + B* b = new B(thisA); + delete thisA; + return b; + +} + +void C::insertElementTransformStat( A*& ix ) +{ + A* thisA = ix; + cout <<"C::insertElementTransformStat( ) "; + ix->printStatus( ); + + + B* b = new B(thisA); + ix = b; + delete thisA; + +} + +void C::printStatus( ) +{ + cout <<"C: Dyn " << *DynAtt_C <<" Stat "<< StatAtt_C << endl; +} + +C::~C( ) +{ + cout <<"C Destructor"<< endl; + if (DynAtt_C) delete DynAtt_C; +} + +/************************************************************* + * Function name.: int main( ) + * + * Return value..: exit status + ************************************************************/ +int +main( ) +{ + + cout << endl << " ---------------------------------------------- " << endl; + cout << endl << " Testing insertElementTransformStat( ) -------- " <<endl; + + int i1t = 3; + cout << "Creating new C" << endl; + A *at = new C( i1t ); + cout << endl << "Inserting 1. element in C and getting B"<< endl; + at->insertElementTransformStat( at ); + cout << endl << "Inserting 2. element in B and getting A"<< endl; + at->insertElementTransformStat( at ); + cout << endl << "Inserting 3. element in A and getting A"<< endl; + at->insertElementTransformStat( at ); + cout << endl << "Inserting 4. element in A and getting A"<< endl; + at->insertElementTransformStat( at ); + cout << endl << "Destroying object"<< endl; + delete at; + + cout << endl << " ---------------------------------------------- "<< endl; + at = new C( i1t ); + cout << endl << "Inserting 1. element in C and getting B"<< endl; + at->insertElementTransformStat( at ); + cout << endl << "Destroying object"<< endl; + delete at; + + cout << endl << " ---------------------------------------------- " << endl; + + exit( 0); +/* + cout << endl << " ---------------------------------------------- " << endl; + cout << endl << " Testing insertElementTransform( ) ------------ " <<endl; + + int i1t = 3; + cout << "Creating new C" << endl; + A *at = new C( i1t ); + cout << endl << "Inserting 1. element in C and getting B"<< endl; + at = at->insertElementTransform( ); + cout << endl << "Inserting 2. element in B and getting A"<< endl; + at = at->insertElementTransform( ); + cout << endl << "Inserting 3. element in A and getting A"<< endl; + at = at->insertElementTransform( ); + cout << endl << "Inserting 4. element in A and getting A"<< endl; + at = at->insertElementTransform( ); + cout << endl << "Destroying object"<< endl; + delete at; + + cout << endl << " ---------------------------------------------- "<< endl; + at = new C( i1t ); + cout << endl << "Inserting 1. element in C and getting B"<< endl; + at = at->insertElementTransform( ); + cout << endl << "Destroying object"<< endl; + delete at; + + cout << endl << " ---------------------------------------------- " << endl; +*/ + + + +/* + B objB; + objB.testProtectedB( ); + exit( 0 ); + + int i1 = 3; + cout << "Creating new C" << endl; + A *a = new C( i1 ); + cout << endl << "Inserting 1. element in C and getting B"<< endl; + a->insertElement( a ); + cout << endl << "Inserting 2. element in B and getting A"<< endl; + a->insertElement( a ); + cout << endl << "Inserting 3. element in A and getting A"<< endl; + a->insertElement( a ); + cout << endl << "Inserting 4. element in A and getting A"<< endl; + a->insertElement( a ); + cout << endl << "Destroying object"<< endl; + delete a; + + cout << endl << " ---------------------------------------------- "<< endl; + a = new C( i1 ); + cout << endl << "Inserting 1. element in C and getting B"<< endl; + a->insertElement( a ); + cout << endl << "Destroying object"<< endl; + delete a; + + cout << endl << " ---------------------------------------------- "<< endl; + C a1( i1 ); + a = new C( i1 ); + cout << endl << "Inserting 1. element in C and getting B"<< endl; + a1.insertElement( a ); + cout << endl << "Inserting 2. element in C and getting B"<< endl; + a->insertElement( a ); + cout << endl << "Destroying object"<< endl; + delete a; + + exit( 0 ); +*/ +} diff --git a/indexmgr/test/test_clusterix.cc b/indexmgr/test/test_clusterix.cc new file mode 100644 index 0000000..92f4cf9 --- /dev/null +++ b/indexmgr/test/test_clusterix.cc @@ -0,0 +1,338 @@ +/* +* 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>. +/ +/** + * SOURCE: test_clusterix.cc + * + * MODULE: test for ClusterIx + * + * COMMENTS: + * none + * +*/ + +#include <stdlib.h> +#include <iostream.h> +#include <vector.h> + +#include "o2lib_CC.hxx" // declaration of O2-collection-classes + +#include "indexmgr/clusterix.hh" +#include "dbclusterix.hh" +#include "dbmddobjix.hh" +#include "blobtile.hh" +#include "basetype.hh" +#include "ulongtype.hh" +#include "raslib/minterval.hh" +#include "raslib/sinterval.hh" +#include "cachetamgr/perstile.hh" +#include "cachetamgr/tile.hh" + +static char O2BenchDBName[] = "ClusterIxBase"; +// This test program must use a different base because it +// doesn't use catalogif and adminif. It is not a complete RasDaBase. +static char O2BenchSchemaName[] = "TestSMSchema"; + +#include "raslib/rminit.hh" +RMINITGLOBALS('C') + +static void ClearDB( d_Database &DB ); +static void testAccessing(); +static void testConstructors(); +static void testSearch(); + + +/************************************************************* + * 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 + d_Session session; + d_Database database; + d_Transaction ta; + + // initialize the O2 session + cout << "Initializing O2 session..." << endl; + session.set_default_env(); + if (session.begin(argc, argv)){ + cerr << "Something wrong to start o2" << endl; + exit(1); + } + + // clear the DB (in case the base already exists) + cout << "Deleting contents of database..." << endl; + ClearDB(database); + + // connect to the database + cout << "Connecting to database " << O2BenchDBName + << "..." << endl; + // database.open( O2BenchDBName ); // doesn't work with O2 V.5 + + // create root collection + cout << "Creating root collection..." << endl; + ta.begin(); + database.create_persistent_root( "IndexContainer", + "d_List<d_Ref<DBClusterIx>>", + OL_CONSTANT); + ta.commit(); + + // create indexes and put them in IndexContainer + cout << "Create indices and put in IndexContainer..." << endl; + ta.begin(); + testConstructors(); + ta.commit(); + + // read index and print contents + cout << "Read indices and print contents..." << endl; + ta.begin(); + testAccessing(); + ta.commit(); + + // test search operation and print contents + cout << "Search a rectangular region and print contents..." << endl; + ta.begin(); + testSearch(); + ta.commit(); + + cout << "Ending O2 session..." << endl; + database.close(); + session.end(); +} + +/************************************************************* + * Function......: testConstructors() + * + * Arguments.....: none + * Return value..: none + * Description...: constructs Indices and inserts them + * in root collection. + ************************************************************/ + +static void testConstructors() +{ + ClusterIx* indexObj2; + ULongType anyType; + char anyCell[4]; + + cout << "....testConstructors"<< endl; + + // read root object + d_List<DBMDDObjIxId> indexList("IndexContainer"); + + // create Index Object + cout << " indexObj1" << endl; + + cout << " tile 1 = nil, 10-12, 20-24 "<< endl; + r_Sinterval limits1Obj1(10l,12l); + r_Sinterval limits2Obj1(20l,24l); + r_Minterval dom(2); + dom << limits1Obj1 << limits2Obj1; + PersTile* tile1Obj1 = new PersTile( dom, &anyType, (const char*) anyCell); + + cout << " tile 2 = nil, 0-400, 22-24 "<< endl; + dom[0].set_interval(0l,400l); + dom[1].set_interval(22l,24l); + PersTile* tile2Obj1 = new PersTile( dom, &anyType, (const char*) anyCell); + + cout << " tile 3 = nil, 0-600, 10-1000 "<< endl; + dom[0].set_interval(0l,600l); + dom[1].set_interval(10l,1000l); + PersTile* tile3Obj1 = new PersTile( dom, &anyType, (const char*) anyCell); + + vector<PersTile*> newTiles; + newTiles.push_back(tile1Obj1); + newTiles.push_back(tile2Obj1); + newTiles.push_back(tile3Obj1); + + ClusterIx* indexObj1 = new ClusterIx(newTiles); + indexList.insert_element_last(indexObj1->getDBMDDObjIxId()); + + // create DBclusterix Object + + cout << " indexObj2 "<< endl; + cout << " tile 1 = nil, 0-19, 20-59, 30-59 "<< endl; + r_Sinterval limits1Obj2(0l,19l); + r_Sinterval limits2Obj2(20l,59l); + r_Sinterval limits3Obj2(30l,59l); + r_Minterval dom2(3); + dom2 << limits1Obj2 << limits2Obj2 << limits3Obj2; + PersTile* tile1Obj2 = new PersTile( dom2, &anyType, (const char*) anyCell); + indexObj2 = new ClusterIx(tile1Obj2); + + cout << " tile 2 = nil, 20-39, 60-79, 60-89 "<< endl; + dom2[0].set_interval(20l,39l); + dom2[1].set_interval(60l,79l); + dom2[2].set_interval(60l,89l); + PersTile* tile2Obj2 = new PersTile( dom2, &anyType, (const char*) anyCell); + indexObj2->insertTile(tile2Obj2); + indexList.insert_element_last(indexObj2->getDBMDDObjIxId()); + + delete indexObj1; + delete indexObj2; +} + +/************************************************************* + * Function......: testAccessing() + * + * Arguments.....: none + * Return value..: none + * Description...: reads DBClusterIx's and shows contents + ************************************************************/ + +static void testAccessing() +{ + DBMDDObjIxId accessedIndex; + + cout << "....testAccessing"<<endl; + + // read root object + d_List< DBMDDObjIxId > indexList("IndexContainer"); + // used for iterating + d_Iterator< DBMDDObjIxId > indexIt = indexList.create_iterator(); + + for( int i = 1 ; indexIt.not_done(); i++, indexIt.advance()) + { + accessedIndex = indexIt.get_element(); + cout << " --"<<i<<". index object in list:" << endl; + accessedIndex->printStatus(); + cout<<endl; + } + +} + +/************************************************************* + * Function......: testSearch() + * + * Arguments.....: none + * Return value..: none + * Description...: reads Index's and shows contents + ************************************************************/ + +static void testSearch() +{ + + DBMDDObjIxId accessedIndex; + ULongType anyType; + + cout << "....testSearch"<<endl; + + // read root object + d_List< DBMDDObjIxId > indexList("IndexContainer"); + // used for iterating + d_Iterator< DBMDDObjIxId > indexIt = indexList.create_iterator(); + + for( int i = 0 ; indexIt.not_done(); i++, indexIt.advance()) + { + vector< Tile* >* entriesList; + + accessedIndex = indexIt.get_element(); + + if (i == 0 || i == 1) + { + r_Minterval searchInt1(2); + r_Minterval searchInt2(3); + + cout << " -- " << i+1 << ". index object in list. Search for:"; + switch (i) { + case 0: searchInt1[0].set_interval(10l,20l); + searchInt1[1].set_interval(10l,30l); + cout << " 10-20, 10-30" << endl; + entriesList = accessedIndex->intersect(searchInt1, &anyType); + break; + case 1: searchInt2[0].set_interval(10l,20l); + searchInt2[1].set_interval(10l,30l); + searchInt2[2].set_interval(40l,50l); + cout << " 10-20, 10-30, 40-50" <<endl; + entriesList = accessedIndex->intersect(searchInt2, &anyType); + break; + default: break; + } + cout << " -- Search result: " << endl; + vector<Tile*>::iterator entryIt = entriesList->begin(); + + // O2 d_List d_Iterator< d_Ref<TilesIxEntry> > entryIt = entriesList->create_iterator(); + // O2 d_List for ( ; entryIt.not_done() ; entryIt.advance() ) + // O2 d_List entryIt.get_element()->printStatus(); + + while (entryIt != entriesList->end()) + { + // (*entryIt)->printStatus(); + r_Minterval tileInterval = (*entryIt)->getDomain(); + int dimensionality = tileInterval.dimension(); + + cout << " PersTile printStatus"; + cout << " domain == " << dimensionality << ": "; + for (int i = 0; i <dimensionality; i++) + cout << tileInterval[i].low() << "-" << tileInterval[i].high() <<", "; + cout << endl; + + entryIt++; + } + } + + // release(entriesList->begin(), entriesList->end()); + for( vector<Tile*>::iterator entIt = entriesList->begin(); + entIt != entriesList->end(); + entIt++ ) + delete *entIt; + + delete entriesList; + + } + +} +/************************************************************* + * Function......: clearDB( d_Database &DB ) + * + * Arguments.....: none + * DB: reference to a d_Database-object to use + * Return value..: none + * Description...: delete the O2-base (in case it already + * existed) and recreates an empty base + ************************************************************/ + +static void ClearDB( d_Database &DB ) +{ + d_Transaction trans; + trans.begin(); + + cout << "Destroying " << O2BenchDBName << endl; + + // destroy the database in case it already exists + DB.destroy( O2BenchDBName ); + + // and create a new one + cout << "Creating " << O2BenchDBName <<" on schema " + << O2BenchSchemaName << endl; + DB.create( O2BenchDBName, O2BenchSchemaName ); + + trans.commit(); +} diff --git a/indexmgr/test/test_dirix.cc b/indexmgr/test/test_dirix.cc new file mode 100644 index 0000000..801d974 --- /dev/null +++ b/indexmgr/test/test_dirix.cc @@ -0,0 +1,357 @@ +/* +* 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>. +/ +/** + * SOURCE: test_dirix.cc + * + * MODULE: test for DirIx + * + * PURPOSE: + * instantiates DBDirIx objects and reads them + * + * COMMENTS: + * none + * +*/ + +#include <stdlib.h> +#include <iostream.h> +#include <vector.h> + +#define TEST_PROTECTED + +#include "o2lib_CC.hxx" // declaration of O2-collection-classes + +#include "indexmgr/dirix.hh" +#include "dbdirix.hh" +#include "dbmddobjix.hh" +#include "blobtile.hh" +#include "basetype.hh" +#include "ulongtype.hh" +#include "raslib/minterval.hh" +#include "raslib/sinterval.hh" +#include "cachetamgr/perstile.hh" +#include "cachetamgr/tile.hh" +#include "indexmgr/persdirix.hh" +#include "indexmgr/regdirix.hh" + +static char O2BenchDBName[] = "DirIxBase"; +// This test program must use a different base because it +// doesn't use catalogif and adminif. It is not a complete RasDaBase. +static char O2BenchSchemaName[] = "TestSMSchema"; + +extern char* myExecArgv0 = ""; + +#include "raslib/rminit.hh" +RMINITGLOBALS('C') + +static void ClearDB( d_Database &DB ); +static void testAccessing(); +static void testConstructors(); +static void testSearch(); + +/************************************************************* + * 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 + d_Session session; + d_Database database; + d_Transaction ta; + + // initialize the O2 session + cout << "Initializing O2 session..." << endl; + session.set_default_env(); + if (session.begin(argc, argv)){ + cerr << "Something wrong to start o2" << endl; + exit(1); + } + + // clear the DB (in case the base already exists) + cout << "Deleting contents of database..." << endl; + ClearDB(database); + + // connect to the database + cout << "Connecting to database " << O2BenchDBName + << "..." << endl; + // database.open( O2BenchDBName ); // doesn't work with O2 V.5 + + // create root collection + cout << "Creating root collection..." << endl; + ta.begin(); + /* + database.create_persistent_root( "IndexContainer", + "d_List<d_Ref<DBDirIx>>", + OL_CONSTANT); + */ + ta.commit(); + + + // create indexes and put them in IndexContainer + cout << "Create indices and put in IndexContainer..." << endl; + ta.begin(); + testConstructors(); + ta.commit(); + + // read index and print contents + cout << "Read indices and print contents..." << endl; + ta.begin(); + testAccessing(); + ta.commit(); + + // test search operation and print contents + cout << "Search a rectangular region and print contents..." << endl; + ta.begin(); + testSearch(); + ta.commit(); + + cout << "Ending O2 session..." << endl; + database.close(); + session.end(); +} + +/************************************************************* + * Function......: testConstructors() + * + * Arguments.....: none + * Return value..: none + * Description...: constructs Indices and inserts them + * in root collection. + ************************************************************/ + +static void testConstructors() +{ + ULongType anyType; + char anyCell[4]; + + cout << "....testConstructors"<< endl; + + // read root object + d_List<DBMDDObjIxId> indexList("IndexContainer"); + + // create Index Object + cout << " indexObj1" << endl; + + r_Minterval dom( "[10:12,20:24]"); + cout << " tile 1 = nil, "<< dom << endl; + PersTile* tile1Obj1 = + new PersTile( dom, ( const BaseType* ) &anyType, (const char*) anyCell); + + dom = r_Minterval( "[0:400,22:24]"); + cout << " tile 2 = nil, "<< dom << endl; + PersTile* tile2Obj1 = + new PersTile( dom, ( const BaseType* ) &anyType, (const char*) anyCell); + + dom = r_Minterval( "[0:600,10:1000]"); + cout << " tile 3 = nil, "<< dom << endl; + PersTile* tile3Obj1 = + new PersTile( dom, ( const BaseType* ) &anyType, (const char*) anyCell); + + vector<Tile*> newTiles; + newTiles.push_back(tile1Obj1); + newTiles.push_back(tile2Obj1); + newTiles.push_back(tile3Obj1); + + PersDirIx* pd1 = + new PersDirIx( tile1Obj1->getDimension( ), ( const BaseType* ) &anyType ); + RegDirIx<PersDirIx, Tile >* indexObj1 = new RegDirIx<PersDirIx, Tile >( pd1 ); + MultiDimIx<Tile>::insertObjectsTransform( newTiles, indexObj1 ); + // indexObj1->insertObjectsTransform( newTiles, indexObj1 ); + indexList.insert_element_last(pd1->getDBMDDObjIxId()); + + // create DBDirIx Object + + cout << " indexObj2 "<< endl; + r_Minterval dom2( "[0:19,20:59,30:59]"); + cout << " tile 1 = nil, "<< dom2 << endl; + PersTile* tile1Obj2 = + new PersTile( dom2, ( const BaseType* ) &anyType, (const char*) anyCell); + PersDirIx* pd2 = + new PersDirIx( tile1Obj2->getDimension( ), ( const BaseType* ) &anyType ); + RegDirIx<PersDirIx, Tile>* indexObj2 = new RegDirIx<PersDirIx, Tile>( pd2 ); + indexObj2->insertObject( tile1Obj2 ); + + dom2 = r_Minterval( "[20:39,60:79,60:89]"); + cout << " tile 2 = nil, "<< dom2 << endl; + PersTile* tile2Obj2 = + new PersTile( dom2, ( const BaseType* ) &anyType, (const char*) anyCell); + indexObj2->insertObject(tile2Obj2); + indexList.insert_element_last(pd2->getDBMDDObjIxId()); + + // PerDirIx doesn't free tiles + delete tile1Obj1; + delete tile2Obj1; + delete tile3Obj1; + + delete tile1Obj2; + delete tile2Obj2; + delete indexObj1; + delete indexObj2; +} + +/************************************************************* + * Function......: testAccessing() + * + * Arguments.....: none + * Return value..: none + * Description...: reads DBDirIx's and shows contents + ************************************************************/ + +static void testAccessing() +{ + DBMDDObjIxId accessedIndex; + + cout << "....testAccessing"<<endl; + + // read root object + d_List< DBMDDObjIxId > indexList("IndexContainer"); + // used for iterating + d_Iterator< DBMDDObjIxId > indexIt = indexList.create_iterator(); + + for( int i = 1 ; indexIt.not_done(); i++, indexIt.advance()) + { + accessedIndex = indexIt.get_element(); + cout << " --"<<i<<". index object in list:" << endl; + accessedIndex->printStatus(); + cout<<endl; + } + +} + +/************************************************************* + * Function......: testSearch() + * + * Arguments.....: none + * Return value..: none + * Description...: reads Index's and shows contents + ************************************************************/ + +static void testSearch() +{ + + DBMDDObjIxId accessedIndex; + ULongType anyType; + + cout << "....testSearch"<<endl; + + // read root object + d_List< DBMDDObjIxId > indexList("IndexContainer"); + // used for iterating + d_Iterator< DBMDDObjIxId > indexIt = indexList.create_iterator(); + + for( int i = 0 ; indexIt.not_done(); i++, indexIt.advance()) + { + vector< Tile* >* entriesList; + + accessedIndex = indexIt.get_element(); + + if (i == 0 || i == 1) + { + r_Minterval searchInt1(2); + r_Minterval searchInt2(3); + + cout << " -- " << i+1 << ". index object in list. Search for:"; + switch (i) { + case 0: searchInt1[0].set_interval(10l,20l); + searchInt1[1].set_interval(10l,30l); + cout << " 10-20, 10-30" << endl; + entriesList = ((d_Ref< DBDirIx>) accessedIndex)->intersect(searchInt1, &anyType); + break; + case 1: searchInt2[0].set_interval(10l,20l); + searchInt2[1].set_interval(10l,30l); + searchInt2[2].set_interval(40l,50l); + cout << " 10-20, 10-30, 40-50" <<endl; + entriesList = ((d_Ref<DBDirIx>)accessedIndex)->intersect(searchInt2, &anyType); + break; + default: break; + } + cout << " -- Search result: " << endl; + vector<Tile*>::iterator entryIt = entriesList->begin(); + + // O2 d_List d_Iterator< d_Ref<TilesIxEntry> > entryIt = entriesList->create_iterator(); + // O2 d_List for ( ; entryIt.not_done() ; entryIt.advance() ) + // O2 d_List entryIt.get_element()->printStatus(); + + while (entryIt != entriesList->end()) + { + // (*entryIt)->printStatus(); + r_Minterval tileInterval = (*entryIt)->getDomain(); + int dimensionality = tileInterval.dimension(); + + cout << " PersTile printStatus"; + cout << " domain == " << dimensionality << ": "; + for (int i = 0; i <dimensionality; i++) + cout << tileInterval[i].low() << "-" << tileInterval[i].high() <<", "; + cout << endl; + + entryIt++; + } + } + + // release(entriesList->begin(), entriesList->end()); + for( vector<Tile*>::iterator entIt = entriesList->begin(); + entIt != entriesList->end(); + entIt++ ) + delete *entIt; + + delete entriesList; + + } + +} +/************************************************************* + * Function......: clearDB( d_Database &DB ) + * + * Arguments.....: none + * DB: reference to a d_Database-object to use + * Return value..: none + * Description...: delete the O2-base (in case it already + * existed) and recreates an empty base + ************************************************************/ + +static void ClearDB( d_Database &DB ) +{ + d_Transaction trans; + trans.begin(); + + cout << "Destroying " << O2BenchDBName << endl; + + // destroy the database in case it already exists + DB.destroy( O2BenchDBName ); + + // and create a new one + cout << "Creating " << O2BenchDBName <<" on schema " + << O2BenchSchemaName << endl; + DB.create( O2BenchDBName, O2BenchSchemaName ); + + trans.commit(); +} diff --git a/indexmgr/test/test_expix.cc b/indexmgr/test/test_expix.cc new file mode 100644 index 0000000..fc178a0 --- /dev/null +++ b/indexmgr/test/test_expix.cc @@ -0,0 +1,488 @@ +/* +* 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>. +/ +/** + * SOURCE: test_expix.cc + * + * MODULE: test for DirIx<T> + * + * PURPOSE: + * instantiates DirIx objects, inputs tiles and reads them, comparing + * performance for different indexes (for instance, DirIx<PersDirIx> vs. + * DirIx<TransDirIx>. Uses O2 directly. + * + * COMMENTS: + * none + * +*/ + +#include <stdlib.h> +#include <iostream.h> +#include <vector.h> + +#include "o2lib_CC.hxx" // declaration of O2-collection-classes + +#include "indexmgr/transmddobjix.hh" +#include "indexmgr/persmddobjix.hh" +#include "indexmgr/dirix.hh" +#include "indexmgr/transdirix.hh" +#include "dbdirix.hh" +#include "dbmddobjix.hh" +#include "blobtile.hh" +#include "basetype.hh" +#include "ulongtype.hh" +#include "raslib/minterval.hh" +#include "raslib/sinterval.hh" +#include "cachetamgr/perstile.hh" +#include "cachetamgr/tile.hh" +#include "tools/timer.hh" +#include "indexmgr/persdirix.hh" + +static char O2BenchDBName[] = "DirIxBase"; +// This test program must use a different base because it +// doesn't use catalogif and adminif. It is not a complete RasDaBase. +static char O2BenchSchemaName[] = "TestSMSchema"; + +extern char* myExecArgv0 = ""; + +#include "raslib/rminit.hh" +RMINITGLOBALS('C') + +static void ClearDB( d_Database &DB ); +static void testAccessing(); + +static void testTransDirIx(); +static void testDirIx(); + + +/************************************************************* + * 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 + d_Session session; + d_Database database; + d_Transaction ta; + + // initialize the O2 session + cout << "Initializing O2 session..." << endl; + session.set_default_env(); + if (session.begin(argc, argv)){ + cerr << "Something wrong to start o2" << endl; + exit(1); + } + + // clear the DB (in case the base already exists) + cout << "Deleting contents of database..." << endl; + ClearDB(database); + + // connect to the database + cout << "Connecting to database " << O2BenchDBName + << "..." << endl; + // database.open( O2BenchDBName ); // doesn't work with O2 V.5 + + // create root collection + cout << "Creating root collection..." << endl; + ta.begin(); + // database.create_persistent_root( "IndexContainer", + // "d_List<d_Ref<DBDirIx>>", + // OL_CONSTANT); + ta.commit(); + + /* + cout << "Testing TransDirIx..." << endl; + ta.begin(); + testTransDirIx( ); + ta.commit(); + */ + + cout << "Testing DirIx..." << endl; + ta.begin(); + testDirIx( ); + ta.commit(); + + cout << endl; + cout << "Ending O2 session..." << endl; + database.close(); + session.end(); + + return 0; +} + + +void +testTransDirIx( ) +{ + + cout << "....testTransDirIx"<< endl; + + TransDirIx* ti = new TransDirIx( 2 ); + cout << "TransDirIx just created: "<< endl; + ti->printStatus( ); + + ULongType anyType; + char anyCell[4]; + + TransTile* ttArray[12]; + + for( long j = 0; j < 12 ; j++) + { + r_Minterval dom(2); + dom << r_Sinterval( j, j+ 5 ) << r_Sinterval( j , j+5 ); + TransTile* tt = new TransTile( dom, (BaseType* ) &anyType, anyCell ); + ttArray[j] = tt; + } + + for( j = 0; j < 10 ; j++) + { + cout << "Insert Tile Last " << ttArray[j]->getDomain( ) << endl; + ti->insertObjectLast( ttArray[j] ); + ti->printStatus( ); + } + + cout << "Insert Tile pos 5 " << ttArray[10]->getDomain( ) << endl; + ti->insertObject( ttArray[10], 5 ); + ti->printStatus( ); + + cout << "Insert Tile First " << ttArray[11]->getDomain( ) << endl; + ti->insertObjectFirst( ttArray[11] ); + ti->printStatus( ); + + delete ti; +} + +void +testDirIx( ) +{ + cout << "....testDirIx"<< endl; + + ULongType anyType; + char anyCell[4]; + + // TransDirIx* t = new TransDirIx( 2 ); + // PersDirIx* t = new PersDirIx( 2, &anyType ); + + // char index[] = "MDDObjIx* DirIx<TransDIrIx>"; + // char index[] = "MDDObjIx* DirIx<PersDirIx>"; + // char index[] = "MDDObjIx* PersMDDObjIx "; + // char index[] = "TransMDDObjIx* DirIx<TransDirIx> "; + char index[] = "PersMDDObjIx* DirIx< > "; + // MDDObjIx* /* DirIx< TransDirIx >* */ di = new DirIx< TransDirIx >( t ); + // DirIx< PersDirIx >* di = new DirIx< PersDirIx >( t ); + MDDStorage ms1; + ms1.setIndexType( MDDStorage::DirTilesIx ); + PersMDDObjIx* di = new PersMDDObjIx( 2, &anyType, &ms1 ); + // TransMDDObjIx* di = new TransMDDObjIx( 2, 0 ); + + // char index1[] = "TransMDDObjIx* RegDirIx<TransDirIx>"; + char index1[] = "PersMDDObjIx* RegDirIx< >"; + // char index1[] = "TransMDDObjIx* "; + // TransMDDObjIx* di1 = new TransMDDObjIx( 2, 1 ); + // DirIx< TransDirIx >* di1 = new DirIx< TransDirIx >( t ); + MDDStorage ms; + ms.setIndexType( MDDStorage::RegDirIx ); + PersMDDObjIx* di1 = new PersMDDObjIx( 2, &anyType, &ms ); + + cout << "Comparison of Index " << index << endl; + cout << "with Index1 " << index1 << endl; + + // NumTiles should be a square from something: + unsigned const sqrtnumTiles = 32; + unsigned const NumTiles = sqrtnumTiles * sqrtnumTiles ; + unsigned const NumIntersections = 30; + + // cout << "Index " << index << " just created: "<< endl; + // di->printStatus( ); + + + cout <<"Random insertion of tiles into the indexe(s) ..." << endl; + Tile* ttArray[NumTiles]; Tile* tt1Array[NumTiles]; + unsigned alreadyUsed[NumTiles]; + + long j = 0; + + for( long k = 0; k < sqrtnumTiles ; k++ ) + { + for( long l = 0; l < sqrtnumTiles ; l++) + { + r_Minterval dom(2); + // dom << r_Sinterval( k*5 , k*5+5-1 ) << r_Sinterval( l*5 , l*5+5-1 ); + dom << r_Sinterval( k , k ) << r_Sinterval( l , l ); + + // Tile* tt = new TransTile( dom, (BaseType* ) &anyType, anyCell ); + Tile* tt = new PersTile( dom, (const BaseType* ) &anyType, anyCell ); + // Tile* tt1 = new TransTile( dom, (BaseType* ) &anyType, anyCell ); + Tile* tt1 = new PersTile( dom, (const BaseType* ) &anyType, anyCell ); + + ttArray[j] = tt; tt1Array[j] = tt1; + alreadyUsed[j]=0; + j++; + } + } + + cout <<" j "<< j << endl; + + for( j = 0; j < NumTiles ; j++) + { + int ixToUse = rand( ) % NumTiles; + if ( alreadyUsed[ ixToUse ] ) + { + // calculate another index; + ixToUse = 0; + for( int i = 0; !ixToUse && i < NumTiles; i++ ) + { + if ( !alreadyUsed[i] ) ixToUse = i; + } + } + alreadyUsed[ ixToUse ] = 1; + cout << "Insert Tile ttArray[ " << ixToUse << " ] : "; + cout << ttArray[ixToUse]->getDomain( ) << endl; + + // Index + di->insertTile( ttArray[ ixToUse ] ); + // Index 1 + di1->insertTile( tt1Array[ ixToUse ] ); + // di->printStatus( ); + } + + cout << index << " contents: "<< endl; + di->printStatus( ); + + cout << index1 << " contents: "<< endl; + di1->printStatus( ); + cout << endl; + + r_Minterval cd = di->getCurrentDomain( ); + + r_Minterval badQuery1("[33:43,139:149]"); + // not bad r_Minterval badQuery1("[65:75,32:42]"); + + r_Minterval badQuery2("[139:149,144:154]"); + + r_Minterval badQuery3("[43:53,81:91]"); + // not bad r_Minterval badQuery3("[107:117,53:63]"); + + r_Minterval badQuery4("[37:47,151:161]"); + // not bad r_Minterval badQuery4("[89:99,11:21]"); + + r_Minterval badQuery5("[71:81,113:123]"); // not bad + + // test extreme cases: no intersection at all with the current domain + r_Minterval badQuery6("[161:162,113:113]"); + + // test extreme cases: no intersection at all with the current domain + r_Minterval badQuery7("[170:172,140:140]"); + + for( int i = 0; i < NumIntersections; i++ ) + { + Timer time; Timer time1; + RMTimer* rtime = new RMTimer( "DirIx", "intersect" ); + RMTimer* rtime1 = new RMTimer( "RegDirIx", "intersect" ); + r_Minterval intRegion( 2 ); + long l1 = cd.get_origin( )[0]; + long l2 = cd.get_origin( )[1]; + long h1 = cd.get_high( )[0]; + long h2 = cd.get_high( )[1]; + long length1 = h1 - l1 +1; + long length2 = h2 - l2 +1; + l1 = l1 + rand( ) % length1; + l2 = l2 + rand( ) % length2; + h1 = l1 + (rand( ) % (h1-l1+1) ); + h2 = l2 + (rand( ) % (h2-l2+1) ); + intRegion << r_Sinterval( l1,h1) << r_Sinterval( l2,h2); + +/* + if ( i == NumIntersections - 1 ) + intRegion = badQuery1; + if ( i == NumIntersections - 2 ) + intRegion = badQuery2; + if ( i == NumIntersections - 3 ) + intRegion = badQuery3; + if ( i == NumIntersections - 4 ) + intRegion = badQuery4; + if ( i == NumIntersections - 5 ) + intRegion = badQuery5; +*/ + if ( i == NumIntersections - 6 ) + intRegion = badQuery6; + if ( i == NumIntersections - 7 ) + intRegion = badQuery7; + + + cout << "Intersect with "<< intRegion << endl; + + // Index + time.start( ); rtime->start( ); + vector< Tile* >* rqResult = di->intersect( intRegion ); + rtime->stop( ); time.stop( ); + if ( rqResult ) + { + cout << index << endl << " No. of tiles, time , time/noTiles = " + << rqResult->size( ) << " , "<< time << " , "; + if ( rqResult->size( ) ) cout << time.ellapsed_sec( )/rqResult->size( ) << endl; + } + else + cout << "No tiles intersected "<< endl; + delete rtime; + + // Index 1 + time1.start( ); rtime1->start( ); + vector< Tile* >* rqResult1 = di1->intersect( intRegion ); + rtime1->stop( ); time1.stop( ); + if ( rqResult1 ) + { + cout << index1 << endl << " No. of tiles, time1, time1/noTiles = " + << rqResult1->size( ) << " , "<< time1 << " , "; + if ( rqResult1->size( ) ) cout << time1.ellapsed_sec( )/rqResult1->size( ) << endl; + } + else + cout << "No tiles intersected "<< endl; + delete rtime1; + + + // Index + cout << "Result " << index << endl; + if ( rqResult ) + { + for( int j = 0; j < rqResult->size( ); j++) + cout << ( *rqResult )[j]->getDomain( ) << endl; + delete rqResult; + } + + // Index1 + cout << "Result " << index1 << endl; + if ( rqResult1 ) + { + for( j = 0; j < rqResult1->size( ); j++) + cout << ( *rqResult1 )[j]->getDomain( ) << endl; + delete rqResult1; + } + cout << endl; + } + + for( i = 0; i < NumIntersections; i++ ) + { + Timer time; Timer time1; + r_Point pnt(2); + RMTimer* rtime = new RMTimer( "DirIx", "Point query" ); + RMTimer* rtime1 = new RMTimer( "RegDirIx", "Point query" ); + long l1 = cd.get_origin( )[0]; + long l2 = cd.get_origin( )[1]; + long length1 = cd.get_high( )[0] - l1; + long length2 = cd.get_high( )[1] - l2; + l1 = l1 + rand( ) % length1; + l2 = l2 + rand( ) % length2; + pnt << l1 << l2; + + cout << "Point query with "<< pnt << endl; + + + // Index + time.start( ); rtime->start( ); + Tile* rqResult = di->containPointQuery( pnt ); + rtime->stop( ); time.stop( ); + cout << index << " tile, time = " + << rqResult->getDomain( ) << " , "<< time << endl; + delete rtime; + + // Index 1 + time1.start( ); rtime1->start( ); + Tile* rqResult1 = di1->containPointQuery( pnt ); + rtime1->stop( ); time1.stop( ); + cout << index1 << " tile, time1 = " + << rqResult1->getDomain( ) << " , "<< time1 << endl; + delete rtime1; + + cout << endl; + } + + delete di; + delete di1; +} + +/************************************************************* + * Function......: testAccessing() + * + * Arguments.....: none + * Return value..: none + * Description...: reads DBDirIx's and shows contents + ************************************************************/ + +static void testAccessing() +{ + DBMDDObjIxId accessedIndex; + + cout << "....testAccessing"<<endl; + + // read root object + d_List< DBMDDObjIxId > indexList("IndexContainer"); + // used for iterating + d_Iterator< DBMDDObjIxId > indexIt = indexList.create_iterator(); + + for( int i = 1 ; indexIt.not_done(); i++, indexIt.advance()) + { + accessedIndex = indexIt.get_element(); + cout << " --"<<i<<". index object in list:" << endl; + accessedIndex->printStatus(); + cout<<endl; + } + +} + + +/************************************************************* + * Function......: clearDB( d_Database &DB ) + * + * Arguments.....: none + * DB: reference to a d_Database-object to use + * Return value..: none + * Description...: delete the O2-base (in case it already + * existed) and recreates an empty base + ************************************************************/ + +static void ClearDB( d_Database &DB ) +{ + d_Transaction trans; + trans.begin(); + + cout << "Destroying " << O2BenchDBName << endl; + + // destroy the database in case it already exists + DB.destroy( O2BenchDBName ); + + // and create a new one + cout << "Creating " << O2BenchDBName <<" on schema " + << O2BenchSchemaName << endl; + DB.create( O2BenchDBName, O2BenchSchemaName ); + + trans.commit(); +} diff --git a/indexmgr/test/test_hierix.cc b/indexmgr/test/test_hierix.cc new file mode 100644 index 0000000..306d1bc --- /dev/null +++ b/indexmgr/test/test_hierix.cc @@ -0,0 +1,388 @@ +/* +* 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>. +/ +/** + * SOURCE: test_hierix.cc + * + * MODULE: test for PersHierIx + * + * PURPOSE: + * instantiates DBDirIx objects and reads them + * + * COMMENTS: + * none + * +*/ + +#include <stdlib.h> +#include <iostream.h> +#include <vector.h> + +#define TEST_PROTECTED + +#include "o2lib_CC.hxx" // declaration of O2-collection-classes + + +#include "dbhierix.hh" +#include "dbdirix.hh" +#include "dbmddobjix.hh" + +#include "blobtile.hh" +#include "basetype.hh" +#include "ulongtype.hh" +#include "raslib/minterval.hh" +#include "raslib/sinterval.hh" +#include "cachetamgr/perstile.hh" +#include "cachetamgr/tile.hh" +#include "indexmgr/persdirix.hh" +#include "indexmgr/regdirix.hh" +#include "indexmgr/pershierix.hh" +#include "indexmgr/dirix.hh" +#include "indexmgr/rptreeix.hh" + +static char O2BenchDBName[] = "HierIxBase"; +// This test program must use a different base because it +// doesn't use catalogif and adminif. It is not a complete RasDaBase. +static char O2BenchSchemaName[] = "TestSMSchema"; + +extern char* myExecArgv0 = ""; + +#include "raslib/rminit.hh" +RMINITGLOBALS('C') + +static void ClearDB( d_Database &DB ); +static void testAccessing(); +static void testConstructors(); +static void testSearch(); + +/************************************************************* + * 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 + d_Session session; + d_Database database; + d_Transaction ta; + + // initialize the O2 session + cout << "Initializing O2 session..." << endl; + session.set_default_env(); + if (session.begin(argc, argv)){ + cerr << "Something wrong to start o2" << endl; + exit(1); + } + + // clear the DB (in case the base already exists) + cout << "Deleting contents of database..." << endl; + ClearDB(database); + + // connect to the database + cout << "Connecting to database " << O2BenchDBName + << "..." << endl; + // database.open( O2BenchDBName ); // doesn't work with O2 V.5 + + // create root collection + cout << "Creating root collection..." << endl; + ta.begin(); + database.create_persistent_root( "HierIndexContainer", + "d_List<d_Ref<DBDirIx>>", + OL_CONSTANT); + ta.commit(); + + + // create indexes and put them in HierIndexContainer + cout << "Create indices and put in HierIndexContainer..." << endl; + ta.begin(); + testConstructors(); + ta.commit(); + + // read index and print contents + cout << "Read indices and print contents..." << endl; + ta.begin(); + testAccessing(); + ta.commit(); + + // test search operation and print contents + // cout << "Search a rectangular region and print contents..." << endl; + // ta.begin(); + // testSearch(); + //ta.commit(); + + cout << "Ending O2 session..." << endl; + database.close(); + session.end(); +} + +/************************************************************* + * Function......: testConstructors() + * + * Arguments.....: none + * Return value..: none + * Description...: constructs Indices and inserts them + * in root collection. + ************************************************************/ + +static void testConstructors() +{ + ULongType anyType; + char anyCell[4]; + RPlusTreeIx< Tile >* rtix; + + cout << "....testConstructors"<< endl; + + // read root object + d_List<DBMDDObjIxId> indexList("HierIndexContainer"); + + + // create Index Object + cout << " indexObj1" << endl; + + r_Minterval dom( "[10:12,20:24]"); + cout << " tile 1 = nil, "<< dom << endl; + PersTile* tile1Obj1 = + new PersTile( dom, ( const BaseType* ) &anyType, (const char*) anyCell); + + dom = r_Minterval( "[0:400,22:24]"); + cout << " tile 2 = nil, "<< dom << endl; + PersTile* tile2Obj1 = + new PersTile( dom, ( const BaseType* ) &anyType, (const char*) anyCell); + + dom = r_Minterval( "[0:600,10:1000]"); + cout << " tile 3 = nil, "<< dom << endl; + PersTile* tile3Obj1 = + new PersTile( dom, ( const BaseType* ) &anyType, (const char*) anyCell); + + vector<Tile*> newTiles; + newTiles.push_back(tile1Obj1); + newTiles.push_back(tile2Obj1); + newTiles.push_back(tile3Obj1); + + PersDirIx* pd1 = + new PersDirIx( tile1Obj1->getDimension( ), ( const BaseType* ) &anyType ); + pd1->insertObject( tile1Obj1, 0 ); + pd1->insertObject( tile2Obj1, 1 ); + pd1->insertObject( tile3Obj1, 2 ); + + // pd1->insertObjects( newTiles ); + + indexList.insert_element_last(pd1->getDBMDDObjIxId()); + + // create DBDirIx Object + + cout << " indexObj2 "<< endl; + // cout << " tile 1 = nil, 0-19, 20-59, 30-59 "<< endl; + r_Minterval dom2( "[0:19,20:59,30:59]"); + cout << " tile 1 = nil, "<< dom2 << endl; + + PersTile* tile1Obj2 = + new PersTile( dom2, ( const BaseType* ) &anyType, (const char*) anyCell); + PersDirIx* pd2 = + new PersDirIx( tile1Obj2->getDimension( ), ( const BaseType* ) &anyType ); + pd2->insertObject( tile1Obj2, 0 ); + // RegDirIx<PersDirIx, Tile>* indexObj2 = new RegDirIx<PersDirIx, Tile>( pd2 ); + // indexObj2->insertObject( tile1Obj2 ); + + // cout << " tile 2 = nil, 20-39, 60-79, 60-89 "<< endl; + dom2 = r_Minterval( "[20:39,60:79,60:89]"); + cout << " tile 2 = nil, "<< dom2 << endl; + + PersTile* tile2Obj2 = + new PersTile( dom2, ( const BaseType* ) &anyType, (const char*) anyCell); + pd2->insertObject( tile2Obj2, 1 ); + // indexObj2->insertObject(tile2Obj2); + indexList.insert_element_last(pd2->getDBMDDObjIxId()); + + + PersHierIx* hierIxObj = + new PersHierIx( pd1->getDimension( ),( const BaseType* ) &anyType ); + rtix = new RPlusTreeIx< Tile >( hierIxObj ); + + DirIx< PersHierIx, PersIx >* hix = new DirIx< PersHierIx, PersIx >( hierIxObj ); + + // hierIxObj->insertObject( pd1, 0 ); + // hierIxObj->insertObject( pd2, 1 ); + r_Minterval domain( pd1->getDomain( ) ); + // domain.closure_with( pd2->getDomain( + hix->insertObject( pd1 ); + hix->insertObject( pd2 ); + indexList.insert_element_last(hierIxObj->getDBMDDObjIxId()); + + // PerDirIx doesn't free tiles + delete tile1Obj1; + delete tile2Obj1; + delete tile3Obj1; + + delete tile1Obj2; + delete tile2Obj2; + // delete pd1; + // delete pd2; + // delete hierIxObj; + delete hix; +} + +/************************************************************* + * Function......: testAccessing() + * + * Arguments.....: none + * Return value..: none + * Description...: reads DBDirIx's and shows contents + ************************************************************/ + +static void testAccessing() +{ + DBMDDObjIxId accessedIndex; + + cout << "....testAccessing"<<endl; + + // read root object + d_List< DBMDDObjIxId > indexList("HierIndexContainer"); + // used for iterating + d_Iterator< DBMDDObjIxId > indexIt = indexList.create_iterator(); + + for( int i = 1 ; indexIt.not_done(); i++, indexIt.advance()) + { + accessedIndex = indexIt.get_element(); + cout << " --"<<i<<". index object in list:" << endl; + accessedIndex->printStatus(); + cout<<endl; + } + +} + +/************************************************************* + * Function......: testSearch() + * + * Arguments.....: none + * Return value..: none + * Description...: reads Index's and shows contents + ************************************************************/ + +static void testSearch() +{ + + DBMDDObjIxId accessedIndex; + ULongType anyType; + + cout << "....testSearch"<<endl; + + // read root object + d_List< DBMDDObjIxId > indexList("HierIndexContainer"); + // used for iterating + d_Iterator< DBMDDObjIxId > indexIt = indexList.create_iterator(); + + for( int i = 0 ; indexIt.not_done(); i++, indexIt.advance()) + { + vector< Tile* >* entriesList; + + accessedIndex = indexIt.get_element(); + + if (i == 0 || i == 1) + { + r_Minterval searchInt1(2); + r_Minterval searchInt2(3); + + cout << " -- " << i+1 << ". index object in list. Search for:"; + switch (i) { + case 0: searchInt1[0].set_interval(10l,20l); + searchInt1[1].set_interval(10l,30l); + cout << " 10-20, 10-30" << endl; + entriesList = ((d_Ref< DBDirIx>) accessedIndex)->intersect(searchInt1, &anyType); + break; + case 1: searchInt2[0].set_interval(10l,20l); + searchInt2[1].set_interval(10l,30l); + searchInt2[2].set_interval(40l,50l); + cout << " 10-20, 10-30, 40-50" <<endl; + entriesList = ((d_Ref<DBDirIx>)accessedIndex)->intersect(searchInt2, &anyType); + break; + default: break; + } + cout << " -- Search result: " << endl; + vector<Tile*>::iterator entryIt = entriesList->begin(); + + // O2 d_List d_Iterator< d_Ref<TilesIxEntry> > entryIt = entriesList->create_iterator(); + // O2 d_List for ( ; entryIt.not_done() ; entryIt.advance() ) + // O2 d_List entryIt.get_element()->printStatus(); + + while (entryIt != entriesList->end()) + { + // (*entryIt)->printStatus(); + r_Minterval tileInterval = (*entryIt)->getDomain(); + int dimensionality = tileInterval.dimension(); + + cout << " PersTile printStatus"; + cout << " domain == " << dimensionality << ": "; + for (int i = 0; i <dimensionality; i++) + cout << tileInterval[i].low() << "-" << tileInterval[i].high() <<", "; + cout << endl; + + entryIt++; + } + } + + // release(entriesList->begin(), entriesList->end()); + for( vector<Tile*>::iterator entIt = entriesList->begin(); + entIt != entriesList->end(); + entIt++ ) + delete *entIt; + + delete entriesList; + + } + +} +/************************************************************* + * Function......: clearDB( d_Database &DB ) + * + * Arguments.....: none + * DB: reference to a d_Database-object to use + * Return value..: none + * Description...: delete the O2-base (in case it already + * existed) and recreates an empty base + ************************************************************/ + +static void ClearDB( d_Database &DB ) +{ + d_Transaction trans; + trans.begin(); + + cout << "Destroying " << O2BenchDBName << endl; + + // destroy the database in case it already exists + DB.destroy( O2BenchDBName ); + + // and create a new one + cout << "Creating " << O2BenchDBName <<" on schema " + << O2BenchSchemaName << endl; + DB.create( O2BenchDBName, O2BenchSchemaName ); + + trans.commit(); +} diff --git a/indexmgr/test/test_ix.cc b/indexmgr/test/test_ix.cc new file mode 100644 index 0000000..424140c --- /dev/null +++ b/indexmgr/test/test_ix.cc @@ -0,0 +1,517 @@ +/* +* 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>. +/ +/** + * SOURCE: test_ix.cc + * + * MODULE: test for RasDaMan tiles indexes + * + * PURPOSE: + * Compares RPTreeIx's to DirIx's + * + * COMMENTS: + * none + * +*/ + +#include <stdlib.h> +#include <iostream.h> +#include <vector.h> + +#include "raslib/minterval.hh" +#include "raslib/sinterval.hh" +#include "raslib/rmdebug.hh" + + +#include <math.h> + +extern char* myExecArgv0 = ""; + +unsigned maximumFill = 10; + +#include "raslib/rminit.hh" +RMINITGLOBALS('C') + + +void calculateGrid( const r_Minterval& baseTile, + const r_Minterval& gridDesc, + long& numberParts, + vector<r_Minterval>*& grid ); //r_Minterval*& grid ); + + +float calculateAlignFactor( const vector<r_Minterval>& partition); + +int isDisjunctive( const vector<r_Minterval>& parts ); + +void createTilesDomains( ofstream& outRndPopFile, + ofstream& outRndBMFile, + ofstream& outPopFile, + ofstream& outBMFile, + float alignFactor, + vector< r_Minterval >*& tgIntsVec, + int numberTiles, + unsigned dim ); +int randomInsertion = 1; +int seqInsertion = 1; + +/************************************************************* + * 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 + + if( argc < 4 ) { + cout << "Usage: test_ix <dim> <numberTiles> <alignFactor> [-r|-s]" << endl; + cout << " -s only sequential insertion " << endl; + cout << " -r only random insertion " << endl; + cout << " default - both sequential and random " << endl; + return -1; + } + + unsigned dim; + unsigned numberTiles; + float af; + dim = atoi( argv[1]); + numberTiles = atoi( argv[2]); + af = atof( argv[3] ); + if ( dim < 2 || dim > 8 ) + { + cout << " Error : dimensionality outside supported limits !" << endl; + return -1; + } + if ( numberTiles > 100000 || numberTiles < 50 ) + { + cout << " Error : number of tiles outside supported limits !" << endl; + return -1; + } + if ( af < 0.05 || af > 1 ) + { + cout << " Error : alignment fator outside supported limits !" << endl; + return -1; + } + + if ( argc == 5 && strcmp(argv[4], "-r") == 0 ) + { + seqInsertion = 0; + } + else if ( argc == 5 && strcmp(argv[4], "-s") == 0 ) + { + randomInsertion = 0; + } + + + cout << "Dimensionality " << dim << endl; + cout << "Number of Tiles " << numberTiles << endl; + cout << "Alignment factor " << af << endl; + cout << "RandomInsertion "; + + if ( randomInsertion ) + cout << "RandomInsertion " << endl; + if ( seqInsertion ) + cout << "SequentialInsertion " << endl; + + vector< r_Minterval >* tgIntsVec; + + + char namePopFile[100]; + char nameRndPopFile[100]; + char nameBMFile[100]; + char nameRndBMFile[100]; + int afint = af*100; + + sprintf( nameRndPopFile, "ix%dd%dn%dafrndpop.txt", dim, numberTiles, afint); + sprintf( nameRndBMFile, "ix%dd%dn%dafrnd.bm", dim, numberTiles, afint); + sprintf( namePopFile, "ix%dd%dn%dafpop.txt", dim, numberTiles, afint); + sprintf( nameBMFile, "ix%dd%dn%daf.bm", dim, numberTiles, afint); + + ofstream ixStreamPopResults( namePopFile ); + ofstream ixStreamRndPopResults( nameRndPopFile ); + ofstream ixStreamBMResults( nameBMFile ); + ofstream ixStreamRndBMResults( nameRndBMFile ); + if ( randomInsertion ) + { + cout << "nameRndPopFile " << nameRndPopFile << endl; + cout << "nameRndBMFile " << nameRndBMFile << endl; + // system("/usr/bin/date + if ( !ixStreamRndPopResults || !ixStreamRndBMResults ) + { + cout <<"Error: one file could not be openened" << endl; + return -1; + } + } + if ( seqInsertion ) + { + cout << "namePopFile " << namePopFile << endl; + cout << "nameBMFile " << nameBMFile << endl; + // system("/usr/bin/date + if ( !ixStreamPopResults || !ixStreamBMResults ) + { + cout <<"Error: one file could not be openened" << endl; + return -1; + } + } + + + cout << "Dim " << dim << endl; + cout << "NTiles wanted " << numberTiles << endl; + cout << "AlignFactor wanted " << af << endl; + + + createTilesDomains( ixStreamRndPopResults, ixStreamRndBMResults, + ixStreamPopResults, ixStreamBMResults, af, tgIntsVec, + numberTiles, dim ); + numberTiles = tgIntsVec->size( ); // integer arithmetic error + + + ixStreamPopResults.close( ); + ixStreamBMResults.close( ); + ixStreamRndPopResults.close( ); + ixStreamRndBMResults.close( ); + + return 0; +} + + +/************************************************************************* + * + * + ************************************************************************/ +void +calculateGrid( const r_Minterval& baseTile, + const r_Minterval& gridDesc, + long& numberParts, + vector< r_Minterval>*& grid ) // grid r_Minterval*& grid) +{ + cout << "calculateGrid( " << baseTile << ", "<< gridDesc << ") "<< endl; + numberParts = gridDesc.cell_count( ); + grid = new vector<r_Minterval>(numberParts); //new r_Minterval[numberParts]; + r_Point ix( baseTile.dimension( )); + r_Point ext = baseTile.get_extent( ); + for ( int i= 0; i < numberParts ; i++ ) + { + ix = gridDesc.cell_point( i )* ext; + (*grid)[i] = baseTile.create_translation( ix ); + // grid[i] = r_Minterval( baseTile.create_translation( ix ) ); + } + +} + +/************************************************************************* + * + * + ************************************************************************/ +void +createTilesDomains( ofstream& outRndPopFile, // file for test_populate + ofstream& outRndBMFile, // file for benchmark + ofstream& outPopFile, // file for test_populate + ofstream& outBMFile, // file for benchmark + float alignFactor, + vector< r_Minterval >*& tgIntsVec, + int numberTiles, + unsigned dim ) +{ + + if( alignFactor > 1 || alignFactor == 0 ) + { + cout <<"Error: invalid alignment factor." << endl; + exit(0); + } + + cout << "Alignment factor wanted " << alignFactor << endl; + cout << "Number of tiles, dim " << numberTiles << ", "<< dim << endl; + + // number of partitions of the total grid + double ntgdouble = numberTiles/alignFactor; + // cout <<"Number of tiles in total grid (double)== " << ntgdouble << endl; + long ntg = ntgdouble; + cout <<"Number of tiles in total grid (long)== " << ntg << endl; + + // r_Minterval* tgInts; + + float f = float (1/ float(dim) ); + long n = pow( ntg, f); + cout <<"Number of tiles in d-1 first directions (n) == " << n << endl; + r_Minterval tile(dim); + const unsigned tileLength = 3; + r_Minterval totalGrid( dim ); + for (int i = 0; i < dim -1; i++ ) + { + tile[i].set_interval( r_Range( 0 ), tileLength-1 ); + totalGrid[i].set_interval( r_Range( 0 ), n-1 ); + } + long n1 = pow(n,dim-1); + n1 = ntg/n1; + cout << "Number of tiles in direction d (n1) == " << n1 << endl; + tile[dim-1].set_interval( r_Range( 0 ), tileLength-1 ); + totalGrid[dim-1].set_interval( r_Range( 0 ), n1-1 ); + + long ntg1; + calculateGrid( tile, totalGrid, ntg1, tgIntsVec ); + + if ( ntg1 < numberTiles ) + { + cout <<"Error: number of partitions in total grid less than numberTiles"; + cout <<"Exiting the program (integer arithmetic)"<< endl; + // exit(0); + } + + if ( ntg1 != ntg ) + { + cout << "Warning: number of partitions in total grid is not as expected " << endl; + cout << "Alignment factor won't be as expected (integer arithmetic)"<< endl; + } + + cout << endl; + + //tgIntsVec = new vector< r_Minterval >( tgInts, tgInts+ntg1 ); + + // delete tgInts; // ???? + + cout << "Number of tiles in total grid " << ntg1 << endl; + /* + for( i =0; i < tgIntsVec->size( ); i++ ) + cout << "Interval "<< i << (*tgIntsVec)[i] <<endl; + */ + int numberMerges = ntg1-numberTiles; + int cont = 1; + for ( i = 0; i < numberMerges && cont ; ) + { + int found = 0; + int r = rand( ) % (tgIntsVec->size( ) ); + // merge randomly + int notFinished = 1; + + int contr = 1; + for( int ri = 0; contr && cont ; ri++) + { + notFinished = 1; + int init = rand( ) % tgIntsVec->size( ); + for( int j = init; notFinished ; ) + { + // cout <<"i,j"<< i <<","<< j<<endl; + if( (*tgIntsVec)[j].is_mergeable( (*tgIntsVec)[r]) ) + { + + if ( i % 100 == 0 ) + cout << numberMerges-i << ". Merging j,r "<< j <<","<< r << " " + << (*tgIntsVec)[j] << ", " << (*tgIntsVec)[r] << " resulting "; + /* + cout << numberMerges-i << ". Merging j,r "<< j <<","<< r << " " + << (*tgIntsVec)[j] << ", " << (*tgIntsVec)[r] << " resulting "; + */ + + (*tgIntsVec)[j] = (*tgIntsVec)[j].closure_with( (*tgIntsVec)[r] ); + tgIntsVec->erase( tgIntsVec->begin( ) + r ); + + if ( i % 100 == 0 ) + { + if ( r < j ) + cout << (*tgIntsVec)[j-1] <<endl; + else + cout << (*tgIntsVec)[j] <<endl; + } + + i++; + notFinished = 0; + found = 1; + } + j = (j+1) % tgIntsVec->size( ); + if ( j == init ) + notFinished = 0; + } + // cout << " r == " << r << ", j == " << j << " , notFinished == " << notFinished << endl; + // cout << " ri == " << ri << " , tgIntsVec->size( ) " << tgIntsVec->size( ) << endl; + r = (r+1) % tgIntsVec->size( ); + if ( found ) + contr = 0; // already found + else + { + if ( ri >= tgIntsVec->size( ) ) + cont = 0; // no more merges possible + else + r = (r+1) % tgIntsVec->size( ); + } + } + } + + cout << "======================================================="<< endl; + cout << "Results : "<< endl; + cout << " Alignement Factor wanted :" << alignFactor << endl; + cout << " Number of Resulting Tiles " << tgIntsVec->size( ) << endl; + + cout << " Resulting Tiles " << endl; + + unsigned ntilesObta = tgIntsVec->size( ); + cout << "NTiles obtained " << ntilesObta << endl; + + float faObta = float ( tgIntsVec->size( ))/ntg1; + cout <<" Alignment factor obtained "<< faObta << endl; + + /* + * Benchmark file format: + * Dim \t ntiles \t af \t random \t h \t occ + */ + if ( seqInsertion ) + { + outBMFile << dim << "\t"; + outBMFile << ntilesObta << "\t"; + outBMFile << faObta << "\t"; + outBMFile << "0\t"; + } + if ( randomInsertion ) + { + outRndBMFile << dim << "\t"; + outRndBMFile << ntilesObta << "\t"; + outRndBMFile << faObta << "\t"; + outRndBMFile <<"1\t"; + } + + // Visual_Tiling_2D visTil( dom, "TilesImage"); + + /* + * Pop file format: + * Database: BmarkIxBase + * + * MDDColl: Ix2D_1000N_5AF_Set; Char2DSet + * + * MDDObj: [ 0:*, 0:*] ; Char2D + * + * HowToStore: + * IndexType: R+TreeIx + */ + char collRndName[100]; + char collName[100]; + char collTypeName[100]; + char mddTypeName[100]; + int faInt = faObta*100; + if ( randomInsertion ) + sprintf( collRndName, "Ix%dD_%dN_%dAF_RND_Set", dim, ntilesObta, faInt); + if ( seqInsertion ) + sprintf( collName, "Ix%dD_%dN_%dAF_Set", dim, ntilesObta, faInt); + r_Minterval dom( dim ); + for ( int d = 0; d < dim; d++ ) + dom[d].set_interval((r_Range)0,'*'); + + sprintf( collTypeName, "Char%dDSet", dim); + sprintf( mddTypeName, "Char%dD", dim ); + + if ( seqInsertion ) + { + outPopFile << "Database: BmarkIxBase " << endl << endl; + outPopFile << "MDDColl: " << collName << "; " << collTypeName << endl<< endl; + outPopFile << "MDDObj: " << dom << " ; " << mddTypeName << endl; + outPopFile << "HowToStore:" << endl; + outPopFile << "IndexType: R+TreeIx " << endl << endl; + } + if ( randomInsertion ) + { + outRndPopFile << "Database: BmarkIxBase " << endl << endl; + outRndPopFile << "MDDColl: " << collRndName << "; " << collTypeName << endl<< endl; + outRndPopFile << "MDDObj: " << dom << " ; " << mddTypeName << endl; + outRndPopFile << "HowToStore:" << endl; + outRndPopFile << "IndexType: R+TreeIx " << endl << endl; + } + if ( seqInsertion ) + { + for( i = 0; i < tgIntsVec->size( ); i++ ) + { + outPopFile <<"Tile : "<< " "<< (*tgIntsVec)[i] << "; 0x0000" << endl; + } + } + if ( randomInsertion ) + { + unsigned vecSz = tgIntsVec->size( ); + vector< r_Minterval >* tgIntsVec2; + tgIntsVec2 = new vector<r_Minterval>(vecSz); + unsigned tix = i; + for( i = 0; i < vecSz; i++ ) + { + tix = rand( ) % tgIntsVec->size( ); + outRndPopFile <<"Tile : "<< " "<< (*tgIntsVec)[tix] << "; 0x0000" << endl; + (*tgIntsVec2)[i] = (*tgIntsVec)[tix]; + tgIntsVec->erase( tgIntsVec->begin( ) + tix ); + } + vector< r_Minterval >* tmpIntsVec; + tmpIntsVec = tgIntsVec; + tgIntsVec = tgIntsVec2; + delete tmpIntsVec; + } + + /* For debugging purposes: + if( !isDisjunctive( *tgIntsVec )) + { + cout <<"Error: Nondisjunctive partition, exiting program "<< endl; + exit( 0); + } + else cout <<" Disjunctive partition OK " << endl; + */ + + if( tgIntsVec->size( ) != numberTiles ) + { + cout <<"Error: tgIntsVec->size( ) != numberTiles "<< endl; + // exit( 0); + } + // calculateAlignFactor( tgIntsVec ); + +} + + +/************************************************************************* + * + * + ************************************************************************/ +float +calculateAlignFactor( const vector<r_Minterval>& part ) +{ + float fa; + // for ( int i = 0; i < part.size( ); i++ ) ; + + return fa; +} + +/************************************************************************* + * + * + ************************************************************************/ +int isDisjunctive( const vector<r_Minterval>& parts ) +{ + for( int i = 0; i < parts.size( ); i++ ) + { + r_Minterval inter = parts[i]; + for( int j = i+1; j < parts.size( ); j++ ) + { + if( inter.intersects_with( parts[j] )) + return 0; + } + } + return 1; +} + diff --git a/indexmgr/test/test_ix1.cc b/indexmgr/test/test_ix1.cc new file mode 100644 index 0000000..73c5323 --- /dev/null +++ b/indexmgr/test/test_ix1.cc @@ -0,0 +1,853 @@ +/* +* 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>. +/ +/** + * SOURCE: test_ix.cc + * + * MODULE: test for RasDaMan tiles indexes + * + * PURPOSE: + * Compares RPTreeIx's to DirIx's + * + * COMMENTS: + * none + * +*/ + +#include "mymalloc/mymalloc.h" + +#include <stdlib.h> +#include <iostream.h> +#include <vector.h> + + +#include "o2lib_CC.hxx" // declaration of O2-collection-classes +#include <o2.h> // O2 Engine +#include <o2_error.h> // O2 error from O2 Engine + +#include "dbmddobjix.hh" +#include "basetype.hh" +#include "chartype.hh" +#include "raslib/minterval.hh" +#include "raslib/sinterval.hh" +#include "cachetamgr/perstile.hh" +#include "tools/timer.hh" +#include "indexmgr/persdirix.hh" +#include "indexmgr/pershierix.hh" +#include "indexmgr/rptreeix.hh" +#include "indexmgr/dirix.hh" +#include "raslib/rmdebug.hh" + + +#include <math.h> + +// This test program must use a different base because it +// doesn't use catalogif and adminif. It is not a complete RasDaBase. +static char O2BenchDBName[] = "TestIxBase"; +static char O2BenchSchemaName[] = "TestSMSchema"; + +extern char* myExecArgv0 = ""; + +unsigned maximumFill = 10; + +#include "raslib/rminit.hh" +RMINITGLOBALS('C') + +static void ClearDB( d_Database &DB ); + +// indexType 1 : R+ tree, 2: DirIx +static void testPopulateIx( int indexType, + const vector< r_Minterval >& tilesDoms ); + +// static void createTilesArr( Tile** tiles, float alignFactor, int numberTiles ); + + +void testCompareIxs( ); + +void calculateGrid( const r_Minterval& baseTile, + const r_Minterval& gridDesc, + long& numberParts, + vector<r_Minterval>*& grid ); //r_Minterval*& grid ); + +static void testCompareIxs( char* index, char* index1, + MultiDimIx<Tile>* ix, MultiDimIx<Tile>* ix1, + r_Minterval* searchInts, int numInts); + +float calculateAlignFactor( const vector<r_Minterval>& partition); + +int isDisjunctive( const vector<r_Minterval>& parts ); + +void createTilesDomains( ofstream& outPopFile, + ofstream& outBMFile, + float alignFactor, + vector< r_Minterval >*& tgIntsVec, + int numberTiles, + unsigned dim ); +int randomInsertion; + +/************************************************************* + * 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 + d_Session session; + d_Database database; + d_Transaction ta; + + if( argc < 4 ) { + cout << "Usage: test_ix <dim> <numberTiles> <alignFactor> [-r]" << endl; + return -1; + } + + unsigned dim; + unsigned numberTiles; + float af; + dim = atoi( argv[1]); + numberTiles = atoi( argv[2]); + af = atof( argv[3] ); + if ( dim < 2 || dim > 8 ) + { + cout << " Error : dimensionality outside supported limits !" << endl; + return -1; + } + if ( numberTiles > 100000 || numberTiles < 50 ) + { + cout << " Error : number of tiles outside supported limits !" << endl; + return -1; + } + if ( af < 0.05 || af > 1 ) + { + cout << " Error : alignment fator outside supported limits !" << endl; + return -1; + } + + if ( argc == 5 && strcmp(argv[4], "-r") == 0 ) + randomInsertion = 1; + else + randomInsertion = 0; + + + cout << "Dimensionality " << dim << endl; + cout << "Number of Tiles " << numberTiles << endl; + cout << "Alignment factor " << af << endl; + cout << "RandomInsertion "; + if ( randomInsertion ) + cout << " yes " << endl; + else + cout << " no " << endl; + + /* + // initialize the O2 session + cout << "Initializing O2 session..." << endl; + session.set_default_env(); + if (session.begin(argc, argv)){ + cerr << "Something wrong to start o2" << endl; + exit(1); + } + + // connect to the database + cout << "Connecting to database " << O2BenchDBName + << "..." << endl; + try{ + database.open( O2BenchDBName ); // doesn't work with O2 V.5 + } + catch( ...) + { + cout << "Could not open database. Exiting "<< endl; + session.end(); + return -1; + } + + + // create root collection + cout << "Checking root collection..." << endl; + ta.begin(); + Handle collHandle = 0; + collHandle = o2_get_root((char*)"HierIndexContainer"); + + if (!collHandle) + { + cout << "Collection doesn't exist yet, creating collection ... "<< endl; + // if root name isn't used yet, create new root name for MDD collection + // I don't know if this is needed. It works without it. + o2_unref_handle( collHandle ); + database.create_persistent_root( "HierIndexContainer", + "d_List<d_Ref<DBMDDObjIx>>", + OL_CONSTANT); + } + else + { + cout << "Collection exists already, does nothing. "<< endl; + // if it exists already, doesn't do anything + // I don't know if this is needed. It works without it. + o2_unref_handle(collHandle); + } + */ + /* + int exists = 1; + try{ + d_List< DBMDDObjIxId > indexList("HierIndexContainer"); + } + catch( ...) + { + cout << "Persistent root does't exist" << endl; + exists =0; + } + if ( !exists ) + database.create_persistent_root( "HierIndexContainer", + "d_List<d_Ref<DBMDDObjIx>>", + OL_CONSTANT); + */ + // ta.commit(); + + + vector< r_Minterval >* tgIntsVec; + + + char namePopFile[100]; + char nameBMFile[100]; + int afint = af*100; + if ( randomInsertion ) + { + sprintf( namePopFile, "ix%dd%dn%dafrndpop.txt", dim, numberTiles, afint); + sprintf( nameBMFile, "ix%dd%dn%dafrnd.bm", dim, numberTiles, afint); + } + else + { + sprintf( namePopFile, "ix%dd%dn%dafpop.txt", dim, numberTiles, afint); + sprintf( nameBMFile, "ix%dd%dn%daf.bm", dim, numberTiles, afint); + } + cout << "namePopFile " << namePopFile << endl; + cout << "nameBMFile " << nameBMFile << endl; + + ofstream ixStreamPopResults(namePopFile); + ofstream ixStreamBMResults(nameBMFile); + + // system("/usr/bin/date + if ( !ixStreamPopResults || !ixStreamBMResults ) + { + cout <<"Error: one file could not be openened" << endl; + return -1; + } + + cout << "Dim " << dim << endl; + cout << "NTiles wanted " << numberTiles << endl; + cout << "AlignFactor wanted " << af << endl; + + + // numberTiles = 80 * i; + createTilesDomains( ixStreamPopResults, ixStreamBMResults, af, tgIntsVec, numberTiles, dim ); + numberTiles = tgIntsVec->size( ); // integer arithmetic error + + /* + cout << "Populating Index 1..." << endl; + ta.begin( ); + testPopulateIx( 1, *tgIntsVec ); + ta.commit( ); + + cout << "Populating Index 2..." << endl; + ta.begin( ); + testPopulateIx( 2, *tgIntsVec ); + ta.commit( ); + + delete tgIntsVec; + + cout <<"Testing two indexes ..."<< endl; + ta.begin( ); + testCompareIxs( ); + ta.commit( ); + + cout << endl; + cout << "Ending O2 session..." << endl; + database.close(); + session.end(); + */ + + ixStreamPopResults.close( ); + ixStreamBMResults.close( ); + + return 0; +} + +/************************************************************************* + * + * + ************************************************************************/ +void +testPopulateIx( int indexType, const vector< r_Minterval >& tilesDomains ) +{ + CharType anyType; + char* anyCells; + const int numberTiles = tilesDomains.size( ); + const int dim = tilesDomains[1].dimension( ); + + + cout << "....testPopulateIx"<< endl; + d_List< DBMDDObjIxId > indexList("HierIndexContainer"); + + PersDirIx* ix = new PersDirIx( dim, &anyType ); + + MultiDimIx< Tile >* rix; + + cout << "Ix of type "; + switch( indexType ) + { + case 1: + cout << "RPlusTree "; + rix = new RPlusTreeIx<Tile>( ix, maximumFill ); + break; + case 2: + cout << "DirIx "; + rix = new DirIx< PersDirIx, Tile >( ix ); + break; + // to be extended + default: + cout <<"Error "<<endl; + exit( 2 ); + } + + cout << "just created: "<< endl; + rix->printStatus( ); + + Tile* tiles[100000]; + + for( int i = 0; i < tilesDomains.size( ); i++ ) + { + anyCells = (char*)mymalloc(tilesDomains[i].cell_count() * anyType.getSize()); + tiles[i] = + new PersTile( tilesDomains[i], (const BaseType*) &anyType, anyCells); + } + + + cout << endl; + for( i = 0; i < numberTiles ; i++ ) + { + cout << endl << "Insert new tile " << i << " " << tiles[i]->getDomain( )<< endl; + + rix->insertObject( tiles[i] ); + + // rix->printStatus( ); + // cout << endl; + } + cout << endl << "Finished, index contents: " << endl; + rix->printStatus( ); + cout << endl; + indexList.insert_element_last( ( (PersIx*) (rix->getIxDS( )) )->getDBMDDObjIxId( ) ); + for( i = 0; i < numberTiles ; i++ ) + delete tiles[i]; + delete rix; +} + +/************************************************************************* + * + * + ************************************************************************/ +void +calculateGrid( const r_Minterval& baseTile, + const r_Minterval& gridDesc, + long& numberParts, + vector< r_Minterval>*& grid ) // grid r_Minterval*& grid) +{ + cout << "calculateGrid( " << baseTile << ", "<< gridDesc << ") "<< endl; + numberParts = gridDesc.cell_count( ); + grid = new vector<r_Minterval>(numberParts); //new r_Minterval[numberParts]; + r_Point ix( baseTile.dimension( )); + r_Point ext = baseTile.get_extent( ); + for ( int i= 0; i < numberParts ; i++ ) + { + ix = gridDesc.cell_point( i )* ext; + (*grid)[i] = baseTile.create_translation( ix ); + // grid[i] = r_Minterval( baseTile.create_translation( ix ) ); + } + +} + +/************************************************************************* + * + * + ************************************************************************/ +void +createTilesDomains( ofstream& outPopFile, // file for test_populate + ofstream& outBMFile, // file for benchmark + float alignFactor, + vector< r_Minterval >*& tgIntsVec, + int numberTiles, + unsigned dim ) +{ + + if( alignFactor > 1 || alignFactor == 0 ) + { + cout <<"Error: invalid alignment factor." << endl; + exit(0); + } + + cout << "Alignment factor wanted " << alignFactor << endl; + cout << "Number of tiles, dim " << numberTiles << ", "<< dim << endl; + + // number of partitions of the total grid + double ntgdouble = numberTiles/alignFactor; + // cout <<"Number of tiles in total grid (double)== " << ntgdouble << endl; + long ntg = ntgdouble; + cout <<"Number of tiles in total grid (long)== " << ntg << endl; + + // r_Minterval* tgInts; + + float f = float (1/ float(dim) ); + long n = pow( ntg, f); + cout <<"Number of tiles in d-1 first directions (n) == " << n << endl; + r_Minterval tile(dim); + const unsigned tileLength = 5; + r_Minterval totalGrid( dim ); + for (int i = 0; i < dim -1; i++ ) + { + tile[i].set_interval( r_Range( 0 ), tileLength-1 ); + totalGrid[i].set_interval( r_Range( 0 ), n-1 ); + } + long n1 = pow(n,dim-1); + n1 = ntg/n1; + cout << "Number of tiles in direction d (n1) == " << n1 << endl; + tile[dim-1].set_interval( r_Range( 0 ), tileLength-1 ); + totalGrid[dim-1].set_interval( r_Range( 0 ), n1-1 ); + + long ntg1; + calculateGrid( tile, totalGrid, ntg1, tgIntsVec ); + + if ( ntg1 < numberTiles ) + { + cout <<"Error: number of partitions in total grid less than numberTiles"; + cout <<"Exiting the program (integer arithmetic)"<< endl; + // exit(0); + } + + if ( ntg1 != ntg ) + { + cout << "Warning: number of partitions in total grid is not as expected " << endl; + cout << "Alignment factor won't be as expected (integer arithmetic)"<< endl; + } + + cout << endl; + + //tgIntsVec = new vector< r_Minterval >( tgInts, tgInts+ntg1 ); + + // delete tgInts; // ???? + + cout << "Number of tiles in total grid " << ntg1 << endl; + /* + for( i =0; i < tgIntsVec->size( ); i++ ) + cout << "Interval "<< i << (*tgIntsVec)[i] <<endl; + */ + int numberMerges = ntg1-numberTiles; + int cont = 1; + for ( i = 0; i < numberMerges && cont ; ) + { + int found = 0; + int r = rand( ) % (tgIntsVec->size( ) ); + // merge randomly + int notFinished = 1; + + int contr = 1; + for( int ri = 0; contr && cont ; ri++) + { + notFinished = 1; + int init = rand( ) % tgIntsVec->size( ); + for( int j = init; notFinished ; ) + { + // cout <<"i,j"<< i <<","<< j<<endl; + if( (*tgIntsVec)[j].is_mergeable( (*tgIntsVec)[r]) ) + { + + if ( i % 100 == 0 ) + cout << numberMerges-i << ". Merging j,r "<< j <<","<< r << " " + << (*tgIntsVec)[j] << ", " << (*tgIntsVec)[r] << " resulting "; + /* + cout << numberMerges-i << ". Merging j,r "<< j <<","<< r << " " + << (*tgIntsVec)[j] << ", " << (*tgIntsVec)[r] << " resulting "; + */ + + (*tgIntsVec)[j] = (*tgIntsVec)[j].closure_with( (*tgIntsVec)[r] ); + tgIntsVec->erase( tgIntsVec->begin( ) + r ); + + if ( i % 100 == 0 ) + { + if ( r < j ) + cout << (*tgIntsVec)[j-1] <<endl; + else + cout << (*tgIntsVec)[j] <<endl; + } + + i++; + notFinished = 0; + found = 1; + } + j = (j+1) % tgIntsVec->size( ); + if ( j == init ) + notFinished = 0; + } + // cout << " r == " << r << ", j == " << j << " , notFinished == " << notFinished << endl; + // cout << " ri == " << ri << " , tgIntsVec->size( ) " << tgIntsVec->size( ) << endl; + r = (r+1) % tgIntsVec->size( ); + if ( found ) + contr = 0; // already found + else + { + if ( ri >= tgIntsVec->size( ) ) + cont = 0; // no more merges possible + else + r = (r+1) % tgIntsVec->size( ); + } + } + } + + cout << "======================================================="<< endl; + cout << "Results : "<< endl; + cout << " Alignement Factor wanted :" << alignFactor << endl; + cout << " Number of Resulting Tiles " << tgIntsVec->size( ) << endl; + + cout << " Resulting Tiles " << endl; + + unsigned ntilesObta = tgIntsVec->size( ); + cout << "NTiles obtained " << ntilesObta << endl; + + float faObta = float ( tgIntsVec->size( ))/ntg1; + cout <<" Alignment factor obtained "<< faObta << endl; + + /* + * Benchmark file format: + * Dim \t ntiles \t af \t random \t h \t occ + */ + outBMFile << dim << "\t"; + outBMFile << ntilesObta << "\t"; + outBMFile << faObta << "\t"; + if ( randomInsertion ) + outBMFile <<"1\t"; + else + outBMFile << "0\t"; + + // Visual_Tiling_2D visTil( dom, "TilesImage"); + + /* + * Pop file format: + * Database: BmarkIxBase + * + * MDDColl: Ix2D_1000N_5AF_Set; Char2DSet + * + * MDDObj: [ 0:*, 0:*] ; Char2D + * + * HowToStore: + * IndexType: R+TreeIx + */ + char collName[100]; + char collTypeName[100]; + char mddTypeName[100]; + int faInt = faObta*100; + if ( randomInsertion ) + sprintf( collName, "Ix%dD_%dN_%dAF_RND_Set", dim, ntilesObta, faInt); + else + sprintf( collName, "Ix%dD_%dN_%dAF_Set", dim, ntilesObta, faInt); + r_Minterval dom( dim ); + for ( int d = 0; d < dim; d++ ) + dom[d].set_interval((r_Range)0,'*'); + + sprintf( collTypeName, "Char%dDSet", dim); + sprintf( mddTypeName, "Char%dD", dim ); + outPopFile << "Database: BmarkIxBase " << endl << endl; + outPopFile << "MDDColl: " << collName << "; " << collTypeName << endl<< endl; + outPopFile << "MDDObj: " << dom << " ; " << mddTypeName << endl; + outPopFile << "HowToStore:" << endl; + outPopFile << "IndexType: R+TreeIx " << endl << endl; + if ( randomInsertion ) + { + unsigned vecSz = tgIntsVec->size( ); + vector< r_Minterval >* tgIntsVec2; + tgIntsVec2 = new vector<r_Minterval>(vecSz); + unsigned tix = i; + for( i = 0; i < vecSz; i++ ) + { + tix = rand( ) % tgIntsVec->size( ); + outPopFile <<"Tile : "<< " "<< (*tgIntsVec)[tix] << "; 0x0000" << endl; + (*tgIntsVec2)[i] = (*tgIntsVec)[tix]; + tgIntsVec->erase( tgIntsVec->begin( ) + tix ); + } + vector< r_Minterval >* tmpIntsVec; + tmpIntsVec = tgIntsVec; + tgIntsVec = tgIntsVec2; + delete tmpIntsVec; + } + else + { + for( i = 0; i < tgIntsVec->size( ); i++ ) + { + outPopFile <<"Tile : "<< " "<< (*tgIntsVec)[i] << "; 0x0000" << endl; + } + } + + /* For debugging purposes: + if( !isDisjunctive( *tgIntsVec )) + { + cout <<"Error: Nondisjunctive partition, exiting program "<< endl; + exit( 0); + } + else cout <<" Disjunctive partition OK " << endl; + */ + + if( tgIntsVec->size( ) != numberTiles ) + { + cout <<"Error: tgIntsVec->size( ) != numberTiles "<< endl; + // exit( 0); + } + // calculateAlignFactor( tgIntsVec ); + +} + +/************************************************************************* + * + * + ************************************************************************/ +/* +void +createTilesArr( Tile** tiles, + float alignFactor, + vector< r_Minterval >* tgIntsVec ) +{ + + ULongType anyType; + char* anyCells; + + for( i = 0; i < tgIntsVec->size( ); i++ ) + { + anyCells = (char*)malloc(tilesDomains[i].cell_count() * anyType.getSize()); + tiles[i] = + new PersTile( (*tgIntsVec)[i], (const BaseType*) &anyType, anyCells); + } + +} +*/ + +/************************************************************************* + * + * + ************************************************************************/ +float +calculateAlignFactor( const vector<r_Minterval>& part ) +{ + float fa; + // for ( int i = 0; i < part.size( ); i++ ) ; + + return fa; +} + +/************************************************************************* + * + * + ************************************************************************/ +int isDisjunctive( const vector<r_Minterval>& parts ) +{ + for( int i = 0; i < parts.size( ); i++ ) + { + r_Minterval inter = parts[i]; + for( int j = i+1; j < parts.size( ); j++ ) + { + if( inter.intersects_with( parts[j] )) + return 0; + } + } + return 1; +} + +/************************************************************* + * Function name.: + * void + * testCompareIxs( char* index, char* index1, ) + * + * Arguments.....: + * index : name of first index + * index1: name of second index + * + ************************************************************/ +void +testCompareIxs( ) +{ + DBMDDObjIxId accessedIndex; + CharType anyType; + // char anyCell[4]; + cout << "....testCompareIxs"<<endl; + + // read root object + d_List< DBMDDObjIxId > indexList("HierIndexContainer"); + // used for iterating + d_Iterator< DBMDDObjIxId > indexIt = indexList.create_iterator(); + + MultiDimIx< Tile >* ix = 0; + MultiDimIx< Tile >* ix1 = 0; + PersIx* dix; + PersIx* dix1; + + for( int i = 1 ; indexIt.not_done(); i++, indexIt.advance()) + { + accessedIndex = indexIt.get_element(); + cout << " --"<<i<<". index object in list:" << endl; + accessedIndex->printStatus(); + if (accessedIndex->isRoot( ) && accessedIndex->isLeaf( ) ) + { + // to avoid mem leaks in repeated executions of this test program + if ( ix1 ) delete ix1; + cout << endl << "Creating DirIx ... "; + dix1 = new PersDirIx( accessedIndex, (const BaseType*) &anyType ); + ix1 = new DirIx< PersDirIx, Tile >( (PersDirIx*)dix1 ); + } + else + { + // to avoid mem leaks in repeated executions of this test program + if ( ix ) delete ix; + cout << endl << "Creating R+-tree ... "; + dix = new PersHierIx( accessedIndex, (const BaseType*) &anyType ); + ix = new RPlusTreeIx<Tile>( dix,maximumFill ); + } + cout << endl; + } + cout <<"OK"<<endl; + + const int numInts = 30; + r_Minterval searchInts[numInts]; + + for( i = 0; i < numInts ; i++ ) + { + r_Range l1= rand( ) % 25; r_Range l2 = rand( ) % 30; + searchInts[i] = r_Minterval( 2 ); + searchInts[i] << r_Sinterval( l1, l1+rand() % 50 ); + searchInts[i] << r_Sinterval( l2, l2 +rand( ) % 50 ); + + /* + searchInts[0] = r_Minterval( "[0:100,0:100]"); + searchInts[1] = r_Minterval( "[150:200,100:250]"); + searchInts[2] = r_Minterval( "[100:300,250:400]"); + searchInts[1] = r_Minterval( "[50:100,100:250]"); + searchInts[1] = r_Minterval( "[50:73,90:94]"); + */ + } + + testCompareIxs( "R+-tree ", "DirIx ", ix, ix1, searchInts, numInts); + + delete ix; delete ix1; +} + +/************************************************************************* + * + * + ************************************************************************/ +void +testCompareIxs( char* index, char* index1, + MultiDimIx<Tile>* ix, MultiDimIx<Tile>* ix1, + r_Minterval* searchInts, int numInts) +{ + cout << "....testCompareIxs"<< endl; + + //ULongType anyType; + // char anyCell[4]; + + + cout << "Comparison of Index " << index << endl; + cout << "with Index1 " << index1 << endl; + + for( int i = 0; i < numInts; i++ ) + { + Timer time; Timer time1; + RMTimer* rtime = new RMTimer( index, "intersect" ); + RMTimer* rtime1 = new RMTimer( index1, "intersect" ); + + cout << "Intersect with "<< searchInts[i] << endl; + + // Index + time.start( ); rtime->start( ); + vector< Tile* >* rqResult = ix->intersect( searchInts[i] ); + int num, num1; + rtime->stop( ); time.stop( ); + if ( rqResult ) + { + num = rqResult->size( ); + cout << index << endl << " No. of tiles, time , time/noTiles = " + << rqResult->size( ) << " , "<< time << " , "; + if ( rqResult->size( ) ) cout << time.ellapsed_sec( )/rqResult->size( ) << endl; + } + else + { + cout << "No tiles intersected "<< endl; + num = 0; + } + delete rtime; + + // Index 1 + time1.start( ); rtime1->start( ); + vector< Tile* >* rqResult1 = ix1->intersect( searchInts[i] ); + rtime1->stop( ); time1.stop( ); + if ( rqResult1 ) + { + num1 = rqResult1->size( ); + cout << index1 << endl << " No. of tiles, time1, time1/noTiles = " + << rqResult1->size( ) << " , "<< time1 << " , "; + if ( rqResult1->size( ) ) cout << time1.ellapsed_sec( )/rqResult1->size( ) << endl; + } + else + { + cout << "No tiles intersected "<< endl; + num1 = 0; + } + delete rtime1; + if ( num != num1 ) + cout << "Error !!!!" << endl; + + // Index + cout << "Result " << index << endl; + if ( rqResult ) + { + for( int j = 0; j < rqResult->size( ); j++) + { + cout << ( *rqResult )[j]->getDomain( ) << endl; + delete (*rqResult)[j]; + } + delete rqResult; + } + + // Index1 + cout << "Result " << index1 << endl; + if ( rqResult1 ) + { + for( int j = 0; j < rqResult1->size( ); j++) + { + cout << ( *rqResult1 )[j]->getDomain( ) << endl; + delete (*rqResult1)[j]; + } + delete rqResult1; + } + cout << endl; + } + +} |