summaryrefslogtreecommitdiffstats
path: root/indexmgr/test
diff options
context:
space:
mode:
Diffstat (limited to 'indexmgr/test')
-rw-r--r--indexmgr/test/Makefile103
-rw-r--r--indexmgr/test/test_abc.cc373
-rw-r--r--indexmgr/test/test_clusterix.cc338
-rw-r--r--indexmgr/test/test_dirix.cc357
-rw-r--r--indexmgr/test/test_expix.cc488
-rw-r--r--indexmgr/test/test_hierix.cc388
-rw-r--r--indexmgr/test/test_ix.cc517
-rw-r--r--indexmgr/test/test_ix1.cc853
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;
+ }
+
+}