/* * 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 . * * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / rasdaman GmbH. * * For more information please see * or contact Peter Baumann via . / /** * SOURCE: test_expix.cc * * MODULE: test for DirIx * * PURPOSE: * instantiates DirIx objects, inputs tiles and reads them, comparing * performance for different indexes (for instance, DirIx vs. * DirIx. Uses O2 directly. * * COMMENTS: * none * */ #include #include #include #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>", // 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"; // char index[] = "MDDObjIx* DirIx"; // char index[] = "MDDObjIx* PersMDDObjIx "; // char index[] = "TransMDDObjIx* DirIx "; 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"; 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"< 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 << " --"<printStatus(); cout<