summaryrefslogtreecommitdiffstats
path: root/mddmgr
diff options
context:
space:
mode:
authorConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
committerConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
commit8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 (patch)
treebd328a4dd4f92d32202241b5e3a7f36177792c5f /mddmgr
downloadrasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip
Initial commitv8.0
Diffstat (limited to 'mddmgr')
-rw-r--r--mddmgr/Makefile.am37
-rw-r--r--mddmgr/mddcoll.cc411
-rw-r--r--mddmgr/mddcoll.hh254
-rw-r--r--mddmgr/mddcolliter.cc110
-rw-r--r--mddmgr/mddcolliter.hh97
-rw-r--r--mddmgr/mddcolliter.icc0
-rw-r--r--mddmgr/mddobj.cc392
-rw-r--r--mddmgr/mddobj.hh255
-rw-r--r--mddmgr/test/Makefile109
-rw-r--r--mddmgr/test/test_extbmarkint.cc374
-rw-r--r--mddmgr/test/test_extendobjs.cc324
-rw-r--r--mddmgr/test/test_mddjoin.cc228
-rw-r--r--mddmgr/test/test_mddobj.cc473
-rw-r--r--mddmgr/test/test_mddops.cc335
-rw-r--r--mddmgr/test/test_persmddcoll.cc768
-rw-r--r--mddmgr/test/test_persmddobj.cc1125
-rw-r--r--mddmgr/test/test_transmddcoll.cc180
-rw-r--r--mddmgr/test/test_transmddobj.cc443
18 files changed, 5915 insertions, 0 deletions
diff --git a/mddmgr/Makefile.am b/mddmgr/Makefile.am
new file mode 100644
index 0000000..5aac570
--- /dev/null
+++ b/mddmgr/Makefile.am
@@ -0,0 +1,37 @@
+# -*-Makefile-*- (for Emacs)
+#
+# This file is part of rasdaman community.
+#
+# Rasdaman community is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Rasdaman community is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+# rasdaman GmbH.
+#
+# For more information please see <http://www.rasdaman.org>
+# or contact Peter Baumann via <baumann@rasdaman.com>.
+#
+# MAKEFILE FOR:
+# cachetamgr
+#
+# COMMENTS:
+#
+##################################################################
+
+AM_CXXFLAGS=@BASEDBCXXFLAGS@
+
+noinst_LIBRARIES= libmddmgr.a
+libmddmgr_a_SOURCES= mddobj.cc mddobj.hh \
+ mddcoll.cc mddcoll.hh \
+ mddcolliter.cc mddcolliter.icc mddcolliter.hh
+
diff --git a/mddmgr/mddcoll.cc b/mddmgr/mddcoll.cc
new file mode 100644
index 0000000..56a1afe
--- /dev/null
+++ b/mddmgr/mddcoll.cc
@@ -0,0 +1,411 @@
+/*
+* 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: mddcoll.cc
+ *
+ * MODULE: cachetamgr
+ * CLASS: MDDColl
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+
+#include "mymalloc/mymalloc.h"
+
+#include <iostream>
+#include "mddcoll.hh"
+#include "mddcolliter.hh"
+#include "relmddif/dbmddset.hh"
+#include "relcatalogif/mdddomaintype.hh"
+#include "relcatalogif/settype.hh"
+#include "mddobj.hh"
+#include "relmddif/dbmddobj.hh"
+#include "reladminif/objectbroker.hh"
+#include "raslib/rmdebug.hh"
+#include "reladminif/oidif.hh"
+#include "relcatalogif/collectiontype.hh" // from base catalogif DBMS interface module
+#include "reladminif/databaseif.hh"
+#include "relmddif/dbmddset.hh"
+#include "reladminif/eoid.hh"
+#include "catalogmgr/typefactory.hh"
+#include "tilemgr/tile.hh"
+
+#include <cstring>
+
+MDDColl::MDDColl(const CollectionType* newType, const char* name)
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDColl", "MDDColl(" << newType->getName() << ", " << (name?name:"null") << ") " << (r_Ptr)this);
+ const char* theName = name;
+ if (theName == NULL)
+ {
+ theName = "rasdaman temporary collection";
+ }
+ dbColl = new DBMDDSet(theName, newType);
+ }
+
+const char*
+MDDColl::getName() const
+ {
+ return dbColl->getName();
+ }
+
+const CollectionType*
+MDDColl::getCollectionType() const
+ {
+ return dbColl->getCollType();
+ }
+
+unsigned long
+MDDColl::getCardinality() const
+ {
+ return dbColl->getCardinality();
+ }
+
+bool
+MDDColl::getOId(OId& pOId) const
+ {
+ if (isPersistent())
+ {
+ pOId = dbColl->getOId();
+ return true;
+ }
+ return false;
+ }
+
+bool
+MDDColl::getEOId(EOId& pEOId) const
+ {
+ if (isPersistent())
+ {
+ pEOId = dbColl->getEOId();
+ return true;
+ }
+ return false;
+ }
+
+void
+MDDColl::insert(const MDDObj* newObj)
+ {
+ RMDBGIF(0, RMDebug::module_mddmgr, "MDDColl", if (newObj == 0) \
+ { \
+ RMInit::dbgOut << "MDDColl::insert(const MDDObj*) assertion failed" << endl;\
+ throw r_Error(MDD_NOT_VALID);\
+ })
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDColl", "insert(" << (r_Ptr)newObj << ")")
+ dbColl->insert(newObj->getDBMDDObjId());
+ insertIntoCache(newObj);
+ RMDBGIF(2, RMDebug::module_mddmgr, "MDDColl", dbColl->printStatus(0, RMInit::dbgOut);)
+ }
+
+void
+MDDColl::releaseAll() {
+ MDDObj* tempMDD = 0;
+ while (!mddCache.empty()){
+ tempMDD = (*mddCache.begin()).second;
+ (*mddCache.begin()).second = NULL;
+ delete tempMDD;
+ mddCache.erase(mddCache.begin());
+ }
+}
+
+MDDColl::~MDDColl()
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDColl", "~MDDColl() " << (r_Ptr)this);
+ if (isPersistent())
+ releaseAll();
+ //else released by release transfer structures
+ }
+
+MDDColl::MDDColl(const DBMDDSetId& coll)
+ :dbColl(coll)
+ {
+ }
+
+DBMDDSetId
+MDDColl::getDBMDDSet() const
+ {
+ return dbColl;
+ }
+
+void
+MDDColl::insertIntoCache(const MDDObj* objToInsert) const
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDColl", "insertIntoCache(" << (r_Ptr)objToInsert << ")")
+ mddCache[objToInsert->getDBMDDObjId().ptr()] = (MDDObj*)objToInsert;
+ }
+
+MDDObj*
+MDDColl::getMDDObj(const DBMDDObj* objToGet) const
+ {
+ MDDObj* persMDDObjToGet = NULL;
+ MDDObjMap::const_iterator i = mddCache.find((DBMDDObj*)objToGet);
+ if (i != mddCache.end())
+ persMDDObjToGet = (MDDObj*)(*i).second;
+ else {
+ persMDDObjToGet = new MDDObj((DBMDDObj*)objToGet);
+ insertIntoCache(persMDDObjToGet);
+ }
+ return persMDDObjToGet;
+ }
+
+bool
+MDDColl::isPersistent() const
+ {
+ return dbColl->isPersistent();
+ }
+
+void
+MDDColl::printStatus(unsigned int level, std::ostream& stream) const
+ {
+ dbColl->printStatus(level, stream);
+ char* indent = new char[level*2 +1];
+ for (int j = 0; j < level*2 ; j++)
+ indent[j] = ' ';
+ indent[level*2] = '\0';
+ stream << indent;
+ for (MDDObjMap::iterator i = mddCache.begin(); i != mddCache.end(); i++)
+ {
+ stream << (r_Ptr)(*i).second;
+ }
+ delete[] indent;
+ indent=0;
+ }
+
+MDDCollIter*
+MDDColl::createIterator() const
+ {
+ MDDCollIter* iter = new MDDCollIter((MDDColl*)this);
+ return iter;
+ }
+
+void
+MDDColl::remove(const MDDObj* obj)
+ {
+ if (obj != NULL)
+ {
+ DBMDDObjId t2 = obj->getDBMDDObjId();
+ dbColl->remove(t2);
+
+ //remove from cache ;(
+ MDDObjMap::iterator i = mddCache.find(t2.ptr());
+ if(i != mddCache.end())
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDColl", "remove(" << (r_Ptr)obj << ") found in cache")
+ mddCache.erase(i);
+ }
+ else
+ {
+ RMDBGONCE(0, RMDebug::module_mddmgr, "MDDColl", "remove(" << (r_Ptr)obj << ") not in collection cache")
+ }
+ }
+ else {
+ RMDBGONCE(0, RMDebug::module_mddmgr, "MDDColl", "remove(MDDObj*) NULL");
+ throw r_Error(MDD_NOT_VALID);
+ }
+ }
+
+/*
+void
+MDDColl::removeFromCache(const PersMDDObj* objToRemove)
+ {
+ DBMDDObj* objIdVoidAddress = objToRemove->getDBMDDObjId().ptr();
+ MDDObjMap::iterator i = mddCache.find(objIdVoidAddress);
+
+ if (i != mddCache.end())
+ {
+ persMDDObjToRemove = (*i).second;
+ (*i).second = NULL;
+ delete persMDDObjToRemove;
+ mddCache.erase(i);
+ RMDBGIF(0, RMDebug::module_mddmgr, "MDDColl", \
+ if (mddCache.find(objIdVoidAddress) != mddCache.end()) \
+ { \
+ RMInit::dbgOut << "MDDColl::removeMDDObjfromCache() object multiple times in cache" << endl; \
+ throw r_Error(MDD_EXISTS_MULTIPLE_TIMES); \
+ })
+ }
+ else {
+ RMDBGONCE(0, RMDebug::module_mddmgr, "MDDColl", "removeMDDObjfromCache(" << objToRemove << ") not in collection")
+ }
+ }
+*/
+
+void
+MDDColl::removeAll()
+ {
+ dbColl->removeAll();
+ }
+
+
+const char*
+MDDColl::AllCollectionnamesName = "RAS_COLLECTIONNAMES";
+
+MDDColl*
+MDDColl::createMDDCollection(const char* name, const CollectionType* ct) throw (r_Error)
+ {
+ if (name == NULL)
+ {
+ RMDBGONCE(0, RMDebug::module_mddmgr, "MDDColl", "createMDDColl(NULL, colltype)")
+ throw r_Error(r_Error::r_Error_NameNotUnique);
+ }
+ if (ct == NULL)
+ {
+ RMDBGONCE(0, RMDebug::module_mddmgr, "MDDColl", "createMDDColl(" << name << ", NULL)")
+ throw r_Error(COLLTYPE_NULL);
+ }
+ if (!ct->isPersistent())
+ {
+ r_Error t(209);
+ t.setTextParameter("type", ct->getName());
+ RMDBGONCE(0, RMDebug::module_mddmgr, "MDDColl", "createMDDColl(" << name << ", " << ct->getName() << " not persistent)")
+ throw t;
+ }
+ // may generate an exception:
+ DBMDDSetId newDBColl = new DBMDDSet(name, ct);
+ return new MDDColl(newDBColl);
+ }
+
+MDDColl*
+MDDColl::createMDDCollection(const char* name, const OId& o, const CollectionType* ct) throw (r_Error)
+ {
+ // may generate an exception:
+ if (name == NULL)
+ {
+ RMDBGONCE(0, RMDebug::module_mddmgr, "MDDColl", "createMDDColl(NULL, " << o << ", colltype)")
+ throw r_Error(r_Error::r_Error_NameNotUnique);
+ }
+ if (ct == NULL)
+ {
+ RMDBGONCE(0, RMDebug::module_mddmgr, "MDDColl", "createMDDColl(" << name << ", " << o << ", NULL)")
+ throw r_Error(COLLTYPE_NULL);
+ }
+ if (!ct->isPersistent())
+ {
+ r_Error t(209);
+ t.setTextParameter("type", ct->getName());
+ RMDBGONCE(0, RMDebug::module_mddmgr, "MDDColl", "createMDDColl(" << name << ", " << o << ", " << ct->getName() << " not persistent)")
+ throw t;
+ }
+ DBMDDSetId newDBColl = new DBMDDSet(name, o, ct);
+ return new MDDColl(newDBColl);
+ }
+
+bool
+MDDColl::dropMDDCollection(const char* name)
+ {
+ return DBMDDSet::deleteDBMDDSet(name);
+ }
+
+bool
+MDDColl::dropMDDCollection(const OId& o)
+ {
+ return DBMDDSet::deleteDBMDDSet(o);
+ }
+
+MDDColl*
+MDDColl::getMDDCollection(const OId& collOId) throw (r_Error)
+ {
+ RMDBGENTER(2, RMDebug::module_mddmgr, "MDDColl", "getMDDCollection(" << collOId << ")")
+ DBMDDSetId t(collOId);
+ //this will throw an exception
+ t->isModified();
+ MDDColl* retval = new MDDColl(t);
+ RMDBGEXIT(2, RMDebug::module_mddmgr, "MDDColl", "getMDDCollection(" << collOId << ") " << retval)
+ return retval;
+ }
+
+MDDColl*
+MDDColl::getMDDCollection(const char* collName) throw (r_Error)
+ {
+ RMDBGENTER(2, RMDebug::module_mddmgr, "MDDColl", "getMDDCollection(" << collName << ")")
+ MDDColl* retval = 0;
+ DBMDDSetId dbset;
+ if (strcmp(collName, AllCollectionnamesName) == 0)
+ {
+ r_Minterval transDomain("[0:*]");
+ r_Minterval nameDomain("[0:0]");
+ const BaseType* bt = TypeFactory::mapType("Char");
+ MDDDomainType* mt = new MDDDomainType("RAS_NAMETYPE", bt, transDomain);
+ TypeFactory::addTempType(mt);
+ CollectionType* ct = new SetType("RAS_NAMESETTYPE", mt);
+ TypeFactory::addTempType(ct);
+ retval = new MDDColl(ct, AllCollectionnamesName);
+ OIdSet* list = ObjectBroker::getAllObjects(OId::MDDCOLLOID);
+ MDDObj* transObj = 0;
+ Tile* transTile = 0;
+ char* transName = 0;
+ const char* nameBuffer = 0;
+ r_Range namelen = 0;
+ while (!list->empty())
+ {
+ dbset = *(list->begin());
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDColl", "Coll OId : " << dbset.getOId())
+ nameBuffer = dbset->getName();
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDColl", "Coll Name : " << nameBuffer)
+ namelen = strlen(nameBuffer);
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDColl", "Coll Name Len: " << namelen)
+ transName = (char*)mymalloc(sizeof(char) * (namelen + 1));
+ memset(transName, 0, namelen + 1);
+ strcpy(transName, nameBuffer);
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDColl", "Domain : " << namelen)
+ nameDomain[0].set_high((r_Range)namelen);
+ transObj = new MDDObj(mt, nameDomain);
+ transTile = new Tile(nameDomain, bt, transName, 0, r_Array);
+ transObj->insertTile(transTile);
+ retval->insert(transObj);
+ list->erase(list->begin());
+ }
+ delete list;
+ }
+ else {
+ dbset = DBMDDSet::getDBMDDSet(collName);
+ retval = new MDDColl(dbset);
+ }
+ RMDBGEXIT(2, RMDebug::module_mddmgr, "MDDColl", "getMDDCollection(" << collName << ") " << retval)
+ return retval;
+ }
+
+bool
+MDDColl::removeMDDObject(const OId& collOId, const OId& mddOId)
+ {
+ bool retval = true;
+ DBMDDSetId coll(collOId);
+ DBMDDObjId mdd(mddOId);
+
+ if (coll.is_null())
+ {//does not exist
+ retval = false;
+ }
+ else {
+ if (mdd.is_null())
+ {
+ retval = false;
+ }
+ else {
+ coll->remove(mdd);
+ }
+ }
+ return retval;
+ }
+
diff --git a/mddmgr/mddcoll.hh b/mddmgr/mddcoll.hh
new file mode 100644
index 0000000..c44cb8f
--- /dev/null
+++ b/mddmgr/mddcoll.hh
@@ -0,0 +1,254 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: mddcoll.hh
+ *
+ * MODULE: cachetamgr
+ * CLASS: MDDColl
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _MDDCOLL_HH_
+#define _MDDCOLL_HH_
+
+#include <iostream>
+#include <map>
+#include <stdlib.h>
+
+#include "mddobj.hh"
+#include "mddcolliter.hh"
+#include "mddcoll.hh"
+#include "reladminif/oidif.hh"
+#include "raslib/error.hh"
+#include "relmddif/mddid.hh"
+#include "relcatalogif/collectiontype.hh" // from catalogif base DBMS interface module
+
+class CollectionType;
+class DatabaseIf;
+
+//@ManMemo: Module: {\bf cachetamgr}
+/*@Doc:
+ An MDDColl object is a collection of references to MDD objects.
+ This class is the abstract base class for all persistent and
+ transient collection classes.
+
+ The objects pointed to by the collection exist in a storage domain
+ which may be either the main memory for the transient collections
+ or the database for the persistent cases.
+
+ An MDDColl is responsible for managing the memory allocated for the
+ MDDObjs which belong to it. In the future, more functions will be provided
+ to allow selected releasing or keeping of MDD objects in an MDDColl.
+
+ {\bf Example }
+
+ {\tt MDDObj* accessedObj; }
+
+ {\tt MDDColl* mddObjsColl; }
+
+ {\tt mddObjsColl = new ... }
+
+ {\tt // Initialize mddObjsColl to a PersMDDColl or TransMDDColl. }
+
+ {\tt MDDCollIter* objsIt = mddObjsColl->createIterator(); }
+
+ {\tt for(int i = 1 ; objsIt->notDone(); i++, objsIt->advance()) }
+
+ {\tt \{ }
+
+ {\tt accessedObj = objsIt->getElement(); }
+
+ {\tt ...}
+
+ {\tt } }
+
+ {\tt delete objsIt; // Deallocate iterator. }
+
+ {\tt ... // Here accessedObj may be used. }
+
+ {\tt mddObjsColl->releaseAll(); }
+
+ {\bf {\tt ... // In this part accessedObj is no longer valid. } }
+
+ {\tt delete mddObjsColl; }
+*/
+
+class MDDColl
+ {
+
+ public:
+ ///transient collection
+ MDDColl(const CollectionType* newType, const char* name = 0);
+
+ static const char* AllCollectionnamesName;
+
+ static MDDColl* getMDDCollection(const char* collName) throw (r_Error);
+ /**
+ Retrieve a mdd collection from database.
+ Throws r_Error::r_Error_ObjectUnknown if the name is unknown.
+ */
+
+ static MDDColl* getMDDCollection(const OId& collOId) throw (r_Error);
+ /**
+ Retrieve a mdd collection from database.
+ Throws r_Error::r_Error_ObjectUnknown if the oid is unknown.
+ */
+
+ static MDDColl* createMDDCollection(const char* name, const CollectionType* ct) throw (r_Error);
+ /**
+ Throws r_Error::r_Error_NameNotUnique if the name exists already or is NULL.
+ */
+
+ static MDDColl* createMDDCollection(const char* name, const OId& o, const CollectionType* ct) throw (r_Error);
+ /**
+ Throws r_Error::r_Error_NameNotUnique if the name exists already or is NULL.
+ Throws r_Error::r_Error_OIdNotUnique if the oid exists already.
+ */
+ static bool dropMDDCollection(const char* name);
+ /**
+ Delete a mdd collection from database.
+ Returns false if the name is unknown.
+ */
+
+ static bool dropMDDCollection(const OId& id);
+ /**
+ Delete a mdd collection from database.
+ Returns false if the oid is unknown.
+ */
+
+ static bool removeMDDObject(const OId& coll, const OId& id);
+ /**
+ Remove an mdd object from the collection.
+ Returns always true.
+ */
+
+ void printStatus(unsigned int level = 0, ostream& stream = cout) const;
+ /**
+ Prints current status of the MDD Collection.
+ */
+
+ const CollectionType* getCollectionType() const;
+ /**
+ Returns the type of this MDD collection.
+ */
+
+ unsigned long getCardinality() const;
+ /**
+ Returns the cardinality of the collection.
+ */
+
+ bool getOId(OId& pOId) const;
+ /**
+ Returns true if collection has an OId.
+ */
+
+ bool getEOId(EOId& pEOId) const;
+ /**
+ Returns true0 if collection has an EOId.
+ */
+
+ void insert(const MDDObj* newObj);
+ /**
+ Inserts reference to MDD object into the collection.
+ If the type of the object (transient/persistent) does not fit the collection an exception is thrown.
+ */
+
+ MDDCollIter* createIterator() const;
+ /**
+ Creates a new iterator for this collection. Returns a pointer to the new allocated iterator object. Returned pointer must be freed afterwards.
+ */
+
+ void remove(const MDDObj* obj);
+ /**
+ Remove reference to MDD object from the current collection. The object itself is not obligatorily destroyed from the storage domain where it exists. If the object does not live in the collection nothing is done.
+ */
+
+ void removeAll();
+ /**
+ Empties the current collection by removing all references to MDD objects from it.
+ The objects are not obligatorily destroyed from the storage domain where they exist.
+ */
+
+ void releaseAll();
+ /**
+ Releases all dynamic memory allocated for the current collection.
+ This method has to be called explicitely, since the destructor doesn't deallocate memory for the elements of the collection.
+ The reason for this is to allow the user to use MDDObjs from this collection, even after the collection itself is no longer in main memory.
+ This is only true for transient collections.
+ */
+
+ bool isPersistent() const;
+ /**
+ Tells if collection is persistent.
+ */
+
+ const char* getName() const;
+
+ ~MDDColl();
+ /**
+ Doesn't free main memory allocated for the objects of the collection.
+ See ReleaseAll() for an explanation on this issue. Even if it does nothing, it has to be defined because derived classes may have non-trivial destructors.
+ */
+ protected:
+
+ friend class MDDCollIter;
+
+ MDDObj* getMDDObj(const DBMDDObj*) const;
+ /**
+ Will get from cache/instantiate and return an MDDObj.
+ Instantiation: it will just create a new one if isPersistent() == true -> passing it a oid that does not belong to the collection -> problem.
+ **/
+
+ MDDColl(const DBMDDSetId& coll);
+
+ DBMDDSetId getDBMDDSet() const;
+ /**
+ Return the reference to the actual persistent object in the base DBMS.
+ returned reference must be const -> impossible
+ */
+
+ void insertIntoCache(const MDDObj* objToInsert) const;
+ /**
+ Insert persistent MDD object in the internal cache.
+ */
+
+ //void removeFromCache(DBMDDObjId& objToGet);
+
+ DBMDDSetId dbColl;
+ /**
+ Pointer to the actual class stored in the base DBMS.
+ Based on the Base DBMS DBMDDSet class from relmddif.
+ */
+
+ typedef std::map<DBMDDObj*, MDDObj*, std::less<DBMDDObj*> > MDDObjMap;
+ mutable MDDObjMap mddCache;
+ /**
+ The mdd objs that are instantiated may not be twice in memory. Therefore it has to be checked if an mdd obj was already created for a specific dbmddobj.
+ This is achieved by maintaining this map.
+ */
+ };
+
+#endif
+
diff --git a/mddmgr/mddcolliter.cc b/mddmgr/mddcolliter.cc
new file mode 100644
index 0000000..bcf5092
--- /dev/null
+++ b/mddmgr/mddcolliter.cc
@@ -0,0 +1,110 @@
+/*
+* 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: persmddcolliter.cc
+ *
+ * MODULE: cachetamgr
+ * CLASS: MDDCollIter
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+
+#include <iostream>
+
+#include "mddcolliter.hh"
+#include "mddcoll.hh"
+#include "mddobj.hh"
+#include "relmddif/dbmddobj.hh"
+#include "relmddif/dbmddset.hh"
+#include "reladminif/dbobjectiditerator.hh"
+#include "raslib/rmdebug.hh"
+
+MDDCollIter::MDDCollIter(MDDColl* targetColl)
+ : dbIter(0),
+ persColl(targetColl)
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDCollIter", "MDDCollIter(" << targetColl->getName() << ")");
+ dbColl = targetColl->getDBMDDSet();
+ dbIter = dbColl->newIterator();
+ }
+
+void
+MDDCollIter::printStatus(unsigned int level, ostream& stream) const
+ {
+ stream << " MDDCollIter printStatus: " ;
+ }
+
+MDDObj*
+MDDCollIter::getElement() const
+ {
+ RMDBGENTER(2, RMDebug::module_mddmgr, "MDDCollIter", "getElement()");
+ // Initialization to null: make sure null pointer is returned if the
+ // collection is empty or if the iterator has come to the end already
+
+ MDDObj* persEl = NULL;
+
+ if (dbIter->not_done())
+ {
+ DBMDDObjId el = dbIter->get_element();
+
+ if (!el.is_null())
+ {
+ persEl = persColl->getMDDObj((DBMDDObj*)el);
+ }
+ }
+
+ // persEl is null if there is nothing to return
+ RMDBGEXIT(2, RMDebug::module_mddmgr, "MDDCollIter", "getElement() " << (r_Ptr)persEl);
+ return persEl;
+ }
+
+void
+MDDCollIter::reset()
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDCollIter", "reset()");
+ dbIter->reset();
+ }
+
+bool
+MDDCollIter::notDone() const
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDCollIter", "notDone()");
+ return dbIter->not_done();
+ }
+
+void
+MDDCollIter::advance()
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDCollIter", "advance()");
+ dbIter->advance();
+ }
+
+MDDCollIter::~MDDCollIter()
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDCollIter", "~MDDCollIter()");
+ delete dbIter;
+ dbIter = NULL;
+ }
+
diff --git a/mddmgr/mddcolliter.hh b/mddmgr/mddcolliter.hh
new file mode 100644
index 0000000..0f86209
--- /dev/null
+++ b/mddmgr/mddcolliter.hh
@@ -0,0 +1,97 @@
+#ifndef _MDDCOLLITER_HH_
+#define _MDDCOLLITER_HH_
+
+class MDDCollIter;
+class MDDColl;
+class MDDObj;
+
+#include "mddobj.hh"
+#include "relmddif/mddid.hh" // from mddif interface module
+
+#include <stdlib.h>
+#include <iostream>
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: persmddcolliter.hh
+ *
+ * MODULE: cachetamgr
+ * CLASS: MDDCollIter
+ *
+ * COMMENTS:
+ * Check List:
+ * - printStatus
+ * - Functionality: stream operator, inc/dec operators,...
+ *
+*/
+
+
+//@ManMemo: Module: {\bf cachetamgr}
+/*@Doc:
+ A MDDCollIter represents an iterator for a persistent MDD collection.
+ If a collection is changed (elements are removed or added to/from the
+ collection) between creation of an iterator for it and the execution of
+ other operations on the iterator, the behavior of the istent Iterator
+ is undefined.
+ The {\tt MDDColl::createIterator()} for the object to be scanned should
+ be used to create a new iterator object.
+*/
+
+class MDDCollIter
+ {
+ public:
+ void printStatus(unsigned int level = 0, ostream& stream = cout) const;
+
+ void reset();
+
+ bool notDone() const;
+
+ void advance();
+
+ MDDObj* getElement() const;
+
+ ~MDDCollIter();
+
+ protected:
+
+ friend class MDDColl;
+
+ MDDCollIter(MDDColl* targetColl);
+ /**
+ Constructor - to be used only by MDDColl
+ The iterator is reset after it is created.
+ */
+
+ private:
+
+ // Corresponding iterator in the base DBMS.
+ DBMDDObjIdIter* dbIter;
+
+ // dbColl has to be kept because of error control.
+ DBMDDSetId dbColl;
+
+ // Collection to iterate.
+ MDDColl* persColl;
+ };
+
+#endif
diff --git a/mddmgr/mddcolliter.icc b/mddmgr/mddcolliter.icc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mddmgr/mddcolliter.icc
diff --git a/mddmgr/mddobj.cc b/mddmgr/mddobj.cc
new file mode 100644
index 0000000..59cc4aa
--- /dev/null
+++ b/mddmgr/mddobj.cc
@@ -0,0 +1,392 @@
+/*
+* 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: persmddobj.cc
+ *
+ * MODULE: cachetamgr
+ * CLASS: MDDObj
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+
+#include "mymalloc/mymalloc.h"
+
+static const char rcsid[] = "@(#)persmddobj, PersMDDObj: $Id: mddobj.cc,v 1.26 2005/07/06 22:43:20 rasdev Exp $";
+
+#include <iostream>
+#include <stdlib.h>
+#include <cstring>
+
+#include "mddobj.hh"
+#include "relmddif/dbmddobj.hh"
+#include "relindexif/indexid.hh"
+#include "reladminif/eoid.hh"
+
+#include "tilemgr/tile.hh"
+#include "relcatalogif/mdddomaintype.hh"
+#include "raslib/mddtypes.hh"
+#include "raslib/rmdebug.hh"
+#include "indexmgr/mddobjix.hh"
+
+const r_Minterval&
+MDDObj::checkStorage(const r_Minterval& domain2) throw (r_Error)
+ {
+ r_Minterval domain(domain2.dimension());
+ if (myStorageLayout->getIndexType() == r_Reg_Computed_Index)
+ {
+ if (myStorageLayout->getTilingScheme() != r_RegularTiling)
+ {
+ RMInit::logOut << "MDDObj::checkStorage(" << domain2 << ") the rc index needs a regular tiling defined" << endl;
+ throw r_Error(RCINDEXWITHOUTREGULARTILING);
+ }
+ r_Dimension dim = domain2.dimension();
+ // make sure the tileConfig is fixed
+ r_Minterval tileConfig = myStorageLayout->getTileConfiguration();
+ myStorageLayout->setTileConfiguration(tileConfig);
+ r_Point mddDomainExtent = domain2.get_extent();
+ r_Point tileConfigExtent = tileConfig.get_extent();
+ for (r_Dimension i = 0; i < dim; i++)
+ {
+ if (!domain2[i].is_high_fixed() || !domain2[i].is_low_fixed() || !tileConfig[i].is_high_fixed() || !tileConfig[i].is_low_fixed())
+ {
+ RMInit::logOut << "MDDObj::checkStorage(" << domain2 << ") the rc index needs a domain and tile configuration with fixed domains in all dimensions. Dimension " << i << " seems not to be fixed." << endl;
+ throw r_Error(RCINDEXWITHINCOMPATIBLEMARRAYTYPE);
+ }
+ if (mddDomainExtent[i]%tileConfigExtent[i] != 0)
+ {
+ RMInit::logOut << "MDDObj::checkStorage(" << domain2 << ") the tile configuration (" << tileConfig << ") does not fit the domain of the marray (" << domain << ")." << endl;
+ throw r_Error(TILECONFIGMARRAYINCOMPATIBLE);
+ }
+ }
+ }
+ return domain2;
+ }
+
+MDDObj::MDDObj(const MDDBaseType* mddType, const r_Minterval& domain)
+ : myMDDIndex(NULL),
+ myDBMDDObj(),
+ myStorageLayout(NULL)
+ {
+ if (!mddType)
+ {
+ RMInit::logOut << "MDD type is NULL. Please report query or raslib program to Customer Support." << endl;
+ throw r_Error(MDDTYPE_NULL);
+ }
+
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(" << mddType->getName() << ", " << domain << ") " << (r_Ptr)this);
+ myStorageLayout = new StorageLayout(r_Directory_Index);
+ myMDDIndex = new MDDObjIx(*myStorageLayout, domain);
+ myDBMDDObj = new DBMDDObj(mddType, domain, myMDDIndex->getDBMDDObjIxId(), myStorageLayout->getDBStorageLayout());
+ }
+
+MDDObj::MDDObj(const MDDBaseType* mddType, const r_Minterval& domain, const OId& newOId, const StorageLayout& ms) throw (r_Error)
+ : myMDDIndex(NULL),
+ myDBMDDObj(),
+ myStorageLayout(NULL)
+ {
+ if (!mddType)
+ {
+ RMInit::logOut << "MDD type is NULL. Please report query or raslib program to Customer Support." << endl;
+ throw r_Error(MDDTYPE_NULL);
+ }
+
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(" << mddType->getName() << ", " << domain << ", " << newOId << ", " << ms.getDBStorageLayout().getOId() << ") " << (r_Ptr)this);
+ myStorageLayout = new StorageLayout(ms);
+ myMDDIndex = new MDDObjIx(*myStorageLayout, checkStorage(domain), mddType->getBaseType());
+ myDBMDDObj = new DBMDDObj(mddType, domain, myMDDIndex->getDBMDDObjIxId(), ms.getDBStorageLayout(), newOId);
+ }
+
+MDDObj::MDDObj(const DBMDDObjId& dbmddobj) throw(r_Error)
+ : myMDDIndex(NULL),
+ myDBMDDObj(dbmddobj),
+ myStorageLayout(NULL)
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(DBRef " << dbmddobj.getOId() << ") " << (r_Ptr)this);
+ myStorageLayout = new StorageLayout(myDBMDDObj->getDBStorageLayout());
+ myMDDIndex = new MDDObjIx(myDBMDDObj->getDBIndexDS(), *myStorageLayout, myDBMDDObj->getMDDBaseType()->getBaseType());
+ }
+
+MDDObj::MDDObj(const OId& givenOId) throw(r_Error)
+ : myMDDIndex(NULL),
+ myDBMDDObj(OId()),
+ myStorageLayout(NULL)
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(" << givenOId << ") " << (r_Ptr)this);
+ myDBMDDObj = DBMDDObjId(givenOId);
+ myStorageLayout = new StorageLayout(myDBMDDObj->getDBStorageLayout());
+ myMDDIndex = new MDDObjIx(myDBMDDObj->getDBIndexDS(), *myStorageLayout, myDBMDDObj->getMDDBaseType()->getBaseType());
+ }
+
+MDDObj::MDDObj(const MDDBaseType* mddType, const r_Minterval& domain, const StorageLayout& ms)
+ : myMDDIndex(NULL),
+ myDBMDDObj(OId()),
+ myStorageLayout(NULL)
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(" << mddType->getName() << ", " << domain << ", " << ms.getDBStorageLayout().getOId() << ") " <<(r_Ptr)this);
+ if (!mddType)
+ {
+ RMInit::logOut << "MDD type is NULL. Please report query or raslib program to Customer Support." << endl;
+ throw r_Error(MDDTYPE_NULL);
+ }
+ myStorageLayout = new StorageLayout(ms);
+ myMDDIndex = new MDDObjIx(*myStorageLayout, checkStorage(domain), mddType->getBaseType());
+ myDBMDDObj = new DBMDDObj(mddType, domain, myMDDIndex->getDBMDDObjIxId(), ms.getDBStorageLayout());
+ myDBMDDObj->setPersistent();
+ }
+
+
+/*
+insert tile:
+ tiles may have to be retiled.
+ the storage layout returns the domains into which the tile should be divided before insertion.
+ if there is not enough data to fill a complete layout domain, then 0 will be set.
+*/
+void
+MDDObj::insertTile(Tile* newTile)
+ {
+ RMDBGENTER(2, RMDebug::module_mddmgr, "MDDObj", "insertTile(Tile " << newTile->getDomain() << ")")
+ std::vector <r_Minterval> layoutDoms = myStorageLayout->getLayout(newTile->getDomain());
+RMDBGIF(10, RMDebug::module_mddmgr, "printlayoutdoms", \
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "storage layout returned the following domains") \
+ for (std::vector <r_Minterval>::iterator domit = layoutDoms.begin(); domit != layoutDoms.end(); domit++) \
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", *domit) \
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "end of storage layout domains"))
+
+ Tile* tile = NULL;
+ Tile* tile2 = NULL;
+ r_Area tempArea = 0;
+ r_Area completeArea = 0;
+ r_Minterval tempDom;
+ r_Minterval tileDom = newTile->getDomain();
+ std::vector<Tile*>* indexTiles = NULL;
+ char* newContents = NULL;
+ size_t sizeOfData = 0;
+ bool checkEquality = true;
+ for (std::vector<r_Minterval>::iterator it = layoutDoms.begin(); it != layoutDoms.end(); it++)
+ {
+ if (checkEquality && tileDom == *it)
+ {// normal case. just insert the tile.
+ // this case also means that there was no insertion in the previous loops
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "tile domain is same as layout domain, just inserting data")
+ myMDDIndex->insertTile((Tile*)newTile);
+ // set to NULL so it will not get deleted at the end of the method
+ newTile = NULL;
+ if (layoutDoms.size() != 1)
+ {
+ RMInit::logOut << "MDDObj::insertTile(Tile " << tileDom << ") the layout has more than one element but the tile domain completely covers the layout domain" << endl;
+ throw r_Error(LAYOUTALGORITHMPROBLEM);
+ }
+ }
+ else {// we need to check if there is already a tile defined here
+ // this could have been created in a previous loop run
+ // we are using retiling here. *it is therefore an indivisible layout domain.
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "tile domain (" << tileDom << ") is not the same as layout domain (" << *it << ")")
+ indexTiles = myMDDIndex->intersect(*it);
+ if (indexTiles)
+ {// there was a tile in the run before, which overlapped with this layout domain
+ // there may only be one entry in the index for this domain.
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "found tiles (" << indexTiles->size() << ") in layout domain " << *it)
+ if (indexTiles->size() != 1)
+ {
+ RMInit::logOut << "MDDObj::insertTile(Tile " << tileDom << ") the index contains many entries for one layout domain" << endl;
+ throw r_Error(LAYOUTALGORITHMPROBLEM);
+ }
+ // update the existing tile with the new data
+ tempDom = (*it).create_intersection(tileDom);
+ (*(indexTiles->begin()))->copyTile(tempDom, newTile, tempDom);
+ //RMInit::dbgOut << "updated tile to" << endl;
+ // (*(indexTiles->begin()))->printStatus(99,RMInit::dbgOut);
+ }
+ else {// there was no tile overlapping the current layout domain yet
+ // create a new tile covering the whole layout domain
+ // must be computed everytime because layoutDoms may change in size
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "found no tiles in layout domain " << *it)
+ // generate a tile of the domain : layout domain
+ completeArea = (*it).cell_count();
+ sizeOfData = sizeof(char) * completeArea * getMDDBaseType()->getBaseType()->getSize();
+ newContents = (char*)mymalloc(sizeOfData);
+ // initialise to 0
+ memset(newContents, 0, sizeOfData);
+ tile = new Tile(*it, getMDDBaseType()->getBaseType(), newContents, 0, newTile->getDataFormat());
+ tile->setParameters(newTile->getParameters());
+ tempDom = (*it).create_intersection(tileDom);
+ // only update the actual data - the rest was set to 0
+ tile->copyTile(tempDom, newTile, tempDom);
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "created tile with domain " << tile->getDomain())
+ //RMInit::dbgOut << "insert tile" << endl;
+ // tile->printStatus(99,RMInit::dbgOut);
+ //FIXME: should not be neccessary
+ tile->compress();
+ myMDDIndex->insertTile((Tile*)tile);
+ }
+ }
+ checkEquality = false;
+ }
+ if (newTile)
+ {
+ RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "have to delete newTile")
+ if (newTile->isPersistent())
+ ((Tile*)newTile)->getDBTile()->setPersistent(false);
+ delete newTile;
+ }
+ RMDBGEXIT(2, RMDebug::module_mddmgr, "MDDObj", "insertTile(Tile)")
+ }
+
+std::vector< Tile* >*
+MDDObj::intersect(const r_Minterval& searchInter) const
+ {
+ std::vector<Tile*>* retval = myMDDIndex->intersect(searchInter);
+RMDBGIF(10, RMDebug::module_mddmgr, "printtiles", \
+ if (retval) \
+ { \
+ int t = RManDebug; \
+ RManDebug = 0; \
+ for (std::vector<Tile*>::iterator it = retval->begin(); it != retval->end();it++) \
+ { \
+ RMInit::dbgOut << "FOUND " << (*it)->getDomain() << " " << endl; \
+ (*it)->printStatus(0, RMInit::dbgOut); \
+ } \
+ RManDebug = t; \
+ })
+ return retval;
+ }
+
+std::vector< Tile* >*
+MDDObj::getTiles() const
+ {
+ return myMDDIndex->getTiles();
+ }
+
+char*
+MDDObj::pointQuery(const r_Point& searchPoint)
+ {
+ return myMDDIndex->pointQuery(searchPoint);
+ }
+
+const char*
+MDDObj::pointQuery(const r_Point& searchPoint) const
+ {
+ return myMDDIndex->pointQuery(searchPoint);
+ }
+
+DBMDDObjId
+MDDObj::getDBMDDObjId() const
+ {
+ return myDBMDDObj;
+ }
+
+const MDDBaseType*
+MDDObj::getMDDBaseType() const
+ {
+ return myDBMDDObj->getMDDBaseType();
+ }
+
+r_Minterval
+MDDObj::getDefinitionDomain() const
+ {
+ return myDBMDDObj->getDefinitionDomain();
+ }
+
+r_Minterval
+MDDObj::getCurrentDomain() const
+ {
+ return myMDDIndex->getCurrentDomain();
+ }
+
+const char*
+MDDObj::getCellTypeName() const
+ {
+ return myDBMDDObj->getCellTypeName();
+ }
+
+const BaseType*
+MDDObj::getCellType() const
+ {
+ return myDBMDDObj->getCellType();
+ }
+
+r_Dimension
+MDDObj::getDimension() const
+ {
+ return myDBMDDObj->dimensionality();
+ }
+
+bool
+MDDObj::isPersistent() const
+ {
+ return myDBMDDObj->isPersistent();
+ }
+
+
+int
+MDDObj::getOId(OId* pOId) const
+ {
+ *pOId = myDBMDDObj->getOId();
+ return (pOId->getCounter() == 0);
+ }
+
+int
+MDDObj::getEOId(EOId* pEOId) const
+ {
+ *pEOId = myDBMDDObj->getEOId();
+ return (pEOId->getCounter() == 0);
+ }
+
+void
+MDDObj::printStatus(unsigned int level, std::ostream& stream) const
+ {
+ myDBMDDObj->printStatus(level, stream);
+ myMDDIndex->printStatus(level, stream);
+ }
+
+void
+MDDObj::removeTile(Tile*& tileToRemove)
+ {
+ int found = myMDDIndex->removeTile(tileToRemove);
+ if (found)
+ {
+ // frees its memory. Persistent freeing??
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "removeTile() about to delete tile")
+ ((Tile*) tileToRemove)->getDBTile().delete_object();
+ delete tileToRemove;
+ tileToRemove = 0;
+ }
+ }
+
+MDDObj::~MDDObj()
+ {
+ RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "~MDDObj() " << (r_Ptr)this)
+
+ delete myMDDIndex;
+ myMDDIndex = NULL;
+ delete myStorageLayout;
+ myStorageLayout = NULL;
+ }
+
+void
+MDDObj::releaseTiles()
+ {
+ myMDDIndex->releasePersTiles();
+ }
diff --git a/mddmgr/mddobj.hh b/mddmgr/mddobj.hh
new file mode 100644
index 0000000..a444681
--- /dev/null
+++ b/mddmgr/mddobj.hh
@@ -0,0 +1,255 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: mddobj.hh
+ *
+ * MODULE: cachetamgr
+ * CLASS: MDDObj
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _MDDOBJ_HH_
+#define _MDDOBJ_HH_
+
+#include <vector>
+
+#include "tilemgr/tile.hh"
+#include "relcatalogif/mddbasetype.hh" // from catalogif base DBMS class
+#include "raslib/minterval.hh"
+#include "storagemgr/sstoragelayout.hh"
+#include "relmddif/mddid.hh"
+
+class MDDObjIx;
+
+//@ManMemo: Module: {\bf cachetamgr}
+/*@Doc:
+
+An MDDObj object (Multidimensional Discrete Data Object) is a multidimensional array of cells of a fixed base type.
+Each MDDObj object keeps information about its cell base type, definition domain, the storage layout and the index.
+Actual data is stored in tiles which are linked to the MDDObj via the index.
+
+When the object is first created, a spatial {\bf definition domain} for the object is given, which specifies the extents of the object array. This is expressed through an interval which may have open bounds along some (or all) directions.
+An open bound along a direction specifies that the object may grow arbitrarily along this direction.
+
+At each point in time, an MDDObj has a fixed {\bf current domain} which specifies the actual extent of the object at the moment.
+The current domain is an interval with fixed bounds corresponding to the coverage of all the tiles already inserted in the MDDObj.
+The current domain should be a subinterval of the definition domain, so that tiles inserted in the object should always be completely contained in the definition domain of the object. This is not checked here!
+
+Objects of this class provide the needed functionality of MDDObjs to the RasDaMan server, namely, access to the tiles (which are the actual units of execution, processing and management internally at the server).
+
+Even though tiles are the units of execution in RasDaMan, once a tile is inserted in an MDDObj, it is no longer an independent entity. It should only be deleted from its storage domain through the MDD object it belongs to. Each MDDObj is responsible for managing its own tiles, including deallocation of memory occupied by the tiles.
+The memory management is delegated to the index. Only when the MDDObjIx is deleted the tiles that were accessed during the transaction will be removed from memory.
+
+*/
+class MDDObj
+ {
+ public:
+ //@Man: Constructors
+ //@{
+
+ MDDObj(const MDDBaseType* mddType, const r_Minterval& domain);
+ /**
+ Creates a new transient MDD object with definition domain {\tt domain } and type (\tt mddType).
+ The newly created object has no tiles.
+ */
+
+ /// Creates a new persistent MDD object using preallocated OId {\ttnewOId}.
+ MDDObj(const MDDBaseType* mddType, const r_Minterval& domain, const OId& newOId, const StorageLayout& ms) throw (r_Error);
+ /**
+ Creates a new persistent MDD object with definition domaini {\tt domain} and type (\tt mddType).
+ The newly created object has no tiles.
+ {\ttnewOId } must have been previously allocated with {\tt OIdIf::allocateOId() }
+ Throws an exception if the object already exists or if the OId is not valid.
+ */
+
+ /// Opens an existent transient/persistent MDD object
+ MDDObj(const DBMDDObjId& dbmddobj) throw (r_Error);
+ /**
+ Throws an exception if the object does not exists.
+ */
+
+ /// Opens an existent persistent MDD object which has the OIdi {\tt givenOId }
+ MDDObj(const OId& givenOId) throw (r_Error);
+ /**
+ Throws an exception if the object does not exists.
+ */
+
+ ///
+ MDDObj(const MDDBaseType* mddType, const r_Minterval& domain, const StorageLayout& ms);
+ /**
+ Creates a new persistent MDD object with definition domain {\tt domain}, storage layout {\tt ms} and type {\tt mddType}.
+ The newly created object has no tiles.
+ */
+
+ //@}
+
+ //@Man: Object Identification:
+ //@{
+ int getOId(OId* pOId) const;
+ /**
+ returns 0 if object has an OId.
+ */
+
+ int getEOId(EOId* pEOId) const;
+ /**
+ returns 0 if object has an EOId.
+ */
+ //@}
+
+ //@Man: Printing the status of the object.
+ //@{
+ /// Prints current status of the object.
+ void printStatus(unsigned int level = 0, std::ostream& stream = std::cout) const;
+ //@}
+
+ //@Man: Insertion of new tiles in the MDD object:
+ //@{
+ /**
+ After insertion of tiles in an MDDObj, the object becomes responsible for managing the memory allocated for the tiles inserted.
+ Deallocation is done by the destructor of the index which is called in ~MDDObj.
+ When new tiles are inserted in an MDDObj, the current domain for the object is updated. This information is kept in the index.
+ Neither type nor domain compatibility is checked.
+ */
+
+ /// Inserts new tile into the object.
+ void insertTile(Tile* newTile);
+
+ //@}
+
+ //@Man: Removal of tiles from the MDD object:
+ //@{
+ /**
+ */
+ void removeTile(Tile*& tileToRemove);
+ /**
+ Removes tile from the object.
+ This functon is not implemented yet.
+ */
+ //@}
+
+ //@Man: Retrieval of tiles from the MDD object:
+ //@{
+ /**
+ The methods which allow access to tiles of the MDDObj return pointers to tiles in the object, which continue being managed by the MDDObject. For that reason, the caller should not free the returned pointers to tiles.
+ */
+
+ /// Finds all tiles of the object which intersect searchInter.
+ std::vector< Tile* >* intersect(const r_Minterval& searchInter) const;
+ /**
+ Returns a vector of pointers to the intersected tiles which belong to the MDDObj.
+ The returned vector but not the tiles must be freed by the caller.
+ */
+
+ /// Returns all the tiles belonging to the object.
+ std::vector< Tile* >* getTiles() const;
+ /**
+ Returns a vector with all the tiles which belong to the MDDObj.
+ The returned vector but not the tiles must be freed by the caller.
+ */
+
+ /// Gets the cell with coordinates {\tt searchPoint} in the MDD.
+ const char* pointQuery(const r_Point& searchPoint) const;
+ /**
+ Returns null pointer if cell doesnt exist in the object.
+ */
+
+ /// Gets the cell with coordinates {\tt searchPoint} in the MDD.
+ char* pointQuery(const r_Point& searchPoint);
+ /**
+ Returns null pointer if cell doesnt exist in the object.
+ */
+ //@}
+
+
+ //@Man: Cell and domain properties of the MDD Object:
+ //@{
+
+ /// Returns the MDDBaseType of the object.
+ const MDDBaseType* getMDDBaseType() const;
+
+ /// Returns the domain of the object as it was given in the definition.
+ r_Minterval getDefinitionDomain() const;
+
+ /// Returns the current domain for the object.
+ r_Minterval getCurrentDomain() const;
+
+ /// Get cell type name.
+ const char* getCellTypeName() const;
+
+ /// Get base type.
+ const BaseType* getCellType() const;
+
+ /// Returns the dimensionality of the object.
+ r_Dimension getDimension() const;
+ //@}
+
+
+ //@Man: Miscellaneous Methods
+ //@{
+ ///This method is used to get around a bug in the qlparser.
+// void setDoNotUseThisMethodItIsABugFix(bool yes);
+
+ ///This method is used to get around a bug in the qlparser.
+// bool isDoNotUseThisMethodItIsABugFix() const;
+
+ /// Tells if object is persistent.
+ bool isPersistent() const;
+
+ /// Returns a pointer to the actual object in the base DBMS.
+ DBMDDObjId getDBMDDObjId() const;
+ //@}
+
+ //@Man: Destructor
+ //@{
+ /// Destructor - frees dynamic memory.
+ ~MDDObj();
+ //@}
+
+ /// release all tiles from the index
+ void releaseTiles();
+
+ protected:
+
+ /// does some consistency checks for regular tiling with rc index
+ const r_Minterval& checkStorage(const r_Minterval& domain) throw (r_Error);
+
+ ///The data class that holds all information
+ DBMDDObjId myDBMDDObj;
+
+ ///The index class that is used to access tile, before deleting thems
+ MDDObjIx* myMDDIndex;
+
+ ///The storage class which is reponsible for the tiling
+ StorageLayout* myStorageLayout;
+
+// bool doNotUseThisBugFix;
+ /**
+ The qlparser deletes transient mdd objects also in some cases (when passing transient mddobjs to a transient collection) this is bad.
+ Therefore the qlparser checks for transient mdds if they have this switch set to on, before deleting them.
+ */
+
+ };
+
+#endif
diff --git a/mddmgr/test/Makefile b/mddmgr/test/Makefile
new file mode 100644
index 0000000..c5e03c8
--- /dev/null
+++ b/mddmgr/test/Makefile
@@ -0,0 +1,109 @@
+# -*-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 mddmgr
+#
+# COMMENTS:
+#
+##################################################################
+######################### Definitions ############################
+
+# standard include with general options
+include $(RMANBASE)/Makefile.inc
+
+# all test programs
+SRCCXX = test_extendobjs.cc test_mddobj.cc test_persmddcoll.cc test_transmddcoll.cc \
+ test_extbmarkint.cc test_mddjoin.cc test_mddops.cc test_persmddobj.cc \
+ test_transmddobj.cc
+
+OBJS = ${SRCCXX:%.cc=%.o}
+
+ALLTESTS = ${SRCCXX:%.cc=%}
+
+MISCCLEAN = core
+
+# Sun Solaris: -lposix4 is needed for test_tile because of clock_gettime
+ifeq ($(OSTYPE),$(OSTYPE_SOLARIS))
+ LDFLAGS += -lposix4
+endif
+
+ALLFLAGS = $(BASEDBLDFLAGS) $(LDFLAGS) $(STLLDFLAGS) -L$(SUPPORT_BASE)/lib -lz
+
+MAINLIBS = $(RASLIB) $(CACHETAMGR) $(MDDIF) $(CATALOGIF) \
+ $(INDEXMGR) $(BLOBIF) $(ADMINIF) $(QLPARSER) $(INDEXIF)
+
+########################### Targets ##############################
+
+# make all tests
+.PHONY: test
+test: ALLTESTS
+
+
+######################## Dependencies ############################
+
+test_persmddcoll: test_persmddcoll.o $(MAINLIBS)
+ $(PURIFY) $(CXX) $(ALLFLAGS) -o $@ $^ $(STLLDFLAGS) -lm $(CACHETAMGR) \
+ $(INDEXIF)
+
+test_transmddcoll: test_transmddcoll.o $(RASLIB) $(CACHETAMGR)\
+ $(MDDIF) $(CATALOGIF) $(INDEXIF) $(INDEXMGR) $(BLOBIF) $(ADMINIF)
+ $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(STLLDFLAGS) $(LDFLAGS) -o $@ $^
+
+test_mddobj: test_mddobj.o $(RASLIB) $(CACHETAMGR)\
+ $(MDDIF) $(CATALOGIF) $(INDEXIF) $(INDEXMGR) $(BLOBIF) $(ADMINIF)
+ $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(STLLDFLAGS) $(LDFLAGS) -o $@ $^ -lm \
+ $(CACHETAMGR)
+
+test_transmddobj: test_transmddobj.o $(MAINLIBS)
+ $(PURIFY) $(CXX) $(ALLFLAGS) -o $@ $^ $(INDEXIF)
+
+# can not be used as a target (module library is not remade!)
+test_mddops: test_mddops.o $(RASLIB) $(CACHETAMGR)\
+ $(MDDIF) $(CATALOGIF) $(INDEXIF) $(INDEXMGR) $(BLOBIF) $(ADMINIF)
+ $(PURIFY) $(CXX) $(STLLDFLAGS) $(LDFLAGS) $(BASEDBLDFLAGS) -o $@ $^
+
+# can not be used as a target (module library is not remade!)
+test_mddjoin: test_mddjoin.o $(RASLIB) $(CACHETAMGR)\
+ $(MDDIF) $(CATALOGIF) $(INDEXIF) $(INDEXMGR) $(BLOBIF) $(ADMINIF)
+ $(PURIFY) $(CXX) $(STLLDFLAGS) $(LDFLAGS) $(BASEDBLDFLAGS) -o $@ $^
+
+test_persmddobj: test_persmddobj.o $(RASLIB) $(CACHETAMGR)\
+ $(MDDIF) $(CATALOGIF) $(INDEXMGR) $(BLOBIF) $(ADMINIF) $(QLPARSER) \
+ $(INDEXIF)
+ $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(LDFLAGS) $(STLLDFLAGS) -o $@ $^ \
+ $(STLLDFLAGS) -lm $(CACHETAMGR) -L$(SUPPORT_BASE)/lib -lz
+
+test_extbmarkint: test_extbmarkint.o $(MAINLIBS)
+ $(PURIFY) $(CXX) $(BASEDBLDFLAGS) $(LDFLAGS) $(STLLDFLAGS) -o $@ $^ \
+ $(STLLDFLAGS) -lm $(CACHETAMGR) $(INDEXIF) -L$(SUPPORT_BASE)/lib -lz
+
+# general rules
+include $(RMANBASE)/Makefile.rel
+
+# general dependencies for module libraries
+include $(RMANBASE)/Makefile.dep
+
+# automatically created dependencies
+include Makefile.dep
diff --git a/mddmgr/test/test_extbmarkint.cc b/mddmgr/test/test_extbmarkint.cc
new file mode 100644
index 0000000..3cc0caa
--- /dev/null
+++ b/mddmgr/test/test_extbmarkint.cc
@@ -0,0 +1,374 @@
+/*
+* 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_extbmarkint.cc
+ *
+ * MODULE: mddmgr
+ *
+ * PURPOSE:
+ * Extends the objects created by the test of areas of interest tiling
+ * rasodmg/test/test_int1 (the resulting objects have 5000 frames more
+ * than the original ones ).
+ * Needed because rasodmg doens't support updating of MDDobjects
+ * at the time this was created.
+ *
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+
+#define TEST_PROTECTED
+#define TEST_PRIVATE
+
+#include <stdlib.h>
+#include <iostream>
+
+#include "ulongtype.hh"
+
+#include "mddmgr/persmddcoll.hh"
+#include "mddmgr/persmddobj.hh"
+#include "mddmgr/perstile.hh"
+
+#include "mddmgr/persmddcolliter.hh"
+
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+#include "oidif.hh"
+
+#include "raslib/rminit.hh"
+#include "typefactory.hh"
+
+#include "mddif/dbmddobj.hh"
+#include "mddif/dbmddcoll.hh"
+
+#include "mddbasetype.hh"
+#include "mdddomaintype.hh"
+#include "settype.hh"
+
+
+/*
+ Global Variables
+*/
+extern char* myExecArgv0 = "";
+
+RMINITGLOBALS('C')
+
+static char* O2DBName;
+char *collName;
+char defaultCollName[]= "ObjsContainer";
+
+TransactionIf ta;
+
+/*
+ Functions
+*/
+
+// 2 - Populate collection with MDD objects
+static void testConstructors( OId o,
+ int numberFramesTile,
+ int f, // first frame
+ int n ); // number frames
+
+// 3 - Retrieves an MDD collection with name cn and prints contents:
+static void testAccessing( char* cn );
+
+
+/*************************************************************
+ * Function name.: int main( int argc, char** argv)
+ *
+ * Arguments.....:
+ * argc: number of arguments given to program
+ * argv: array of char* with arguments
+ * Return value..: exit status
+ * Description...: none
+ ************************************************************/
+int
+main( int argc, char** argv)
+{
+ // variables representing O2 database, ta and session
+ DatabaseIf database;
+
+
+
+ if( argc < 2 ) {
+ cout << "Usage: test_extbmarkint <database> [collName] [oid] [frames] " << endl;
+ return -1;
+ }
+ O2DBName = strdup( argv[1] );
+ if ( argc >= 3 ) collName = strdup( argv[2] );
+ else
+ collName = defaultCollName;
+
+ int numberFramesTile = 3; // 9
+ OId o( double( 2)); //
+ if( argc >= 4 )
+ {
+ int oid;
+ o = OId( double( atoi( argv[3] )));
+ cout << "OId " << o << endl;
+ }
+ if( argc >= 5 )
+ {
+ numberFramesTile = atoi( argv[4] );
+ cout << "Number of frames per tile "<< numberFramesTile << endl;
+ }
+
+ // don't forget to initialize before using AdminIf!
+ myExecArgv0 = argv[0];
+ AdminIf* myAdmin = AdminIf::instance();
+
+
+ // connect to the database
+ cout << "Connecting to database " << O2DBName
+ << "..." << endl;
+ int errorDBOpen;
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch( ...)
+ {
+ cout << "Caught Exception " << endl;
+ errorDBOpen = -6;
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Database doesn't exist. Create it new ... " << endl;
+ cout << "Creating new database " << O2DBName
+ << "..." << endl;
+ database.create( O2DBName, "TestSMSchema" );
+ cout << "Connecting to database " << O2DBName
+ << "..." << endl;
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch(...)
+ {
+ errorDBOpen = -6;
+ }
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Failed at opening newly created database " << errorDBOpen << endl;
+ cout << "Exiting " << endl;
+ return errorDBOpen;
+ }
+
+ char c;
+
+ unsigned totalNumberFrames = 200; /* 2000 */
+
+ // The first 2000 frames
+ for( int i = 0; i < totalNumberFrames ; i+= numberFramesTile*30 )
+ {
+ ta.begin( &database );
+ cout << endl << "Populate collection " << i << " ..." << endl;
+ int numberFrames = numberFramesTile*30;
+ if ( i+numberFrames > totalNumberFrames ) numberFrames = totalNumberFrames-i;
+ testConstructors( o, numberFramesTile, i, numberFrames );
+
+/*
+ cout <<"Transaction abort (A/a) or commit (default)? ";
+ cin >> c;
+ if ( c == 'A' || c == 'a' )
+ {
+ ta.abort( );
+ cout <<"End of Transaction Abort..."<<endl;
+ }
+ else
+ {
+*/
+ ta.commit( );
+
+ cout <<"End of transaction commit... "<<endl;
+// }
+ }
+
+
+ const int lastFrame = 2400; // 5120
+
+ // The last frames up to lastFrame
+ for( i = 2121 ; i < lastFrame ; i+= numberFramesTile*30 ) // 2121
+ {
+ ta.begin( &database );
+ cout << endl << "Populate collection " << i << " ..." << endl;
+ int numberFrames = numberFramesTile*30;
+ if ( i+numberFrames > lastFrame ) numberFrames = lastFrame-i;
+ testConstructors( o, numberFramesTile, i, numberFrames );
+
+/*
+ cout <<"Transaction abort (A/a) or commit (default)? ";
+ cin >> c;
+ if ( c == 'A' || c == 'a' )
+ {
+ ta.abort( );
+ cout <<"End of Transaction Abort..."<<endl;
+ }
+ else
+ {
+*/
+ ta.commit( );
+/*
+ cout <<"End of transaction commit... "<<endl;
+ }
+*/
+ }
+
+
+ ta.begin(&database );
+ // read coll and print contents
+ cout << endl << "Read collection " << collName << " and print contents..." << endl;
+ testAccessing( collName );
+ ta.commit( );
+ cout <<"End of transaction commit... "<<endl;
+
+ cout << endl << "Ending O2 session..." << endl;
+ database.close( );
+ delete myAdmin;
+
+ free( O2DBName );
+ if ( collName != defaultCollName ) free( collName );
+ return 0;
+
+}
+
+/*************************************************************
+ * Functions......:
+ *
+ * static void
+ * testConstructors( char* collName )
+ *
+ ************************************************************/
+static void testConstructors( OId o,
+ int numberFramesTile,
+ int f, // first frame
+ int n ) // number frames
+{
+
+ const BaseType* mddType;
+
+ cout << "....testConstructors"<< endl;
+
+ try{
+
+ PersMDDObj* accessedObj = new PersMDDObj( O2DBName, o );
+ int typeSize= accessedObj->getCellType( )->getSize( );
+ cout << "currDom " << accessedObj->getCurrentDomain( ) << endl;
+ accessedObj->printStatus();
+
+ EOId eoid;
+ if ( accessedObj->getEOId( &eoid ) ==0 )
+ cout <<"EOId: " << eoid;
+ cout << endl << endl;
+ mddType = accessedObj->getCellType( );
+
+ r_Minterval firstTile( 3 );
+ firstTile << r_Sinterval( long ( 0 ), long ( numberFramesTile-1 ) )
+ << r_Sinterval( long ( 0 ), long ( 79 ) )
+ << r_Sinterval( long ( 0 ), long ( 119 ) );
+
+ r_Minterval secondTile( 3 );
+ secondTile << r_Sinterval( long ( 0 ) , long ( numberFramesTile-1 ) )
+ << r_Sinterval( long ( 80 ), long ( 159 ) )
+ << r_Sinterval( long ( 0 ) , long ( 119 ) );
+
+ for ( int j = f; j < f+n ; j+=numberFramesTile )
+ {
+ r_Minterval dom1 = firstTile;
+ r_Minterval dom2 = secondTile;
+ r_Point desl( (r_Range) j, 0, 0 );
+ dom1.translate( desl );
+ dom2.translate( desl );
+ if ( dom1[0].high( ) >= f+n )
+ {
+ dom1[0].set_high( long( f+n-1) );
+ dom2[0].set_high( long( f+n-1) );
+ }
+ cout << "dom1" << dom1 << " dom2 " << dom2
+ << " type " << mddType->getTypeName( ) << endl;
+
+ int sz1 = dom1.cell_count( ) * typeSize;
+ char* cells1 = new char[sz1];
+ PersTile* tile1 = new PersTile( dom1, mddType, cells1);
+ accessedObj->insertTile(tile1);
+
+ int sz2 = dom2.cell_count( ) * typeSize;
+ char* cells2 = new char[sz2];
+ PersTile* tile2 = new PersTile( dom2, mddType, cells2 );
+
+ accessedObj->insertTile(tile2);
+ // accessedObj->printStatus( );
+ }
+
+ delete accessedObj;
+
+ }
+ catch ( r_Error& errObj)
+ {
+ cout << "Error caught when opening object" << endl;
+ }
+
+}
+
+
+/*************************************************************
+ * Function......: testAccessing( char* cn )
+ ************************************************************/
+
+static void testAccessing( char* cn )
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testAccessing collection "<< cn << endl;
+
+ try{
+ PersMDDColl objsSet( cn );
+
+ // To test PersMDDColl::printStatus( )
+ // objsSet.printStatus( );
+
+ // To test PersMDDObj::printStatus( ), MDDCollIter::createIterator( ) and
+ // MDDCollIter methods :
+
+ cout << "Iterating through the collection with PersMDDCollIter " << endl;
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ cout << i<<". MDD object in set:" << endl;
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+ accessedObj->printStatus();
+ EOId eoid;
+ if ( accessedObj->getEOId( &eoid ) ==0 )
+ cout <<"EOId: " << eoid;
+ }
+ delete objsIt;
+ objsSet.releaseAll( );
+ }
+ catch ( r_Error& errObj)
+ {
+ cout <<"Error caught ................."<< endl;
+ }
+}
+
diff --git a/mddmgr/test/test_extendobjs.cc b/mddmgr/test/test_extendobjs.cc
new file mode 100644
index 0000000..73f82b3
--- /dev/null
+++ b/mddmgr/test/test_extendobjs.cc
@@ -0,0 +1,324 @@
+/*
+* 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_extendobjs.cc
+ *
+ * MODULE: cachetamgr
+ *
+ * PURPOSE:
+ * Extends the objects created by the test of directional tiling
+ * rasodmg/test/test_dir1 (the resulting objects have 4 times more
+ * products and 2 times more stores than the original ones ).
+ * Needed because rasodmg doens't support updating of MDDobjects
+ * at the time this was created.
+ *
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+
+#define TEST_PROTECTED
+#define TEST_PRIVATE
+
+#include <stdlib.h>
+#include <iostream>
+
+#include "ulongtype.hh"
+
+#include "mddmgr/persmddcoll.hh"
+#include "mddmgr/persmddobj.hh"
+#include "mddmgr/perstile.hh"
+
+#include "mddmgr/persmddcolliter.hh"
+
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+#include "oidif.hh"
+
+#include "raslib/rminit.hh"
+#include "typefactory.hh"
+
+#include "mddif/dbmddobj.hh"
+#include "mddif/dbmddcoll.hh"
+
+#include "mddbasetype.hh"
+#include "mdddomaintype.hh"
+#include "settype.hh"
+
+
+/*
+ Global Variables
+*/
+extern char* myExecArgv0 = "";
+
+RMINITGLOBALS('C')
+
+static char* O2DBName;
+char *collName;
+char defaultCollName[]= "ObjsContainer";
+
+TransactionIf ta;
+
+/*
+ Functions
+*/
+
+// 2 - Populate collection with MDD objects
+static void testConstructors( char* cn , int s, int p);
+
+// 3 - Retrieves an MDD collection with name cn and prints contents:
+static void testAccessing( char* cn );
+
+
+/*************************************************************
+ * Function name.: int main( int argc, char** argv)
+ *
+ * Arguments.....:
+ * argc: number of arguments given to program
+ * argv: array of char* with arguments
+ * Return value..: exit status
+ * Description...: none
+ ************************************************************/
+int
+main( int argc, char** argv)
+{
+ // variables representing O2 database, ta and session
+ DatabaseIf database;
+
+ if( argc < 2 ) {
+ cout << "Usage: test_persmddcoll <database> [collName]" << endl;
+ return -1;
+ }
+ O2DBName = strdup( argv[1] );
+ if ( argc == 3 ) collName = strdup( argv[2] );
+ else
+ collName = defaultCollName;
+
+ // don't forget to initialize before using AdminIf!
+ myExecArgv0 = argv[0];
+ AdminIf* myAdmin = AdminIf::instance();
+
+
+ // connect to the database
+ cout << "Connecting to database " << O2DBName
+ << "..." << endl;
+ int errorDBOpen;
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch( ...)
+ {
+ cout << "Caught Exception " << endl;
+ errorDBOpen = -6;
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Database doesn't exist. Create it new ... " << endl;
+ cout << "Creating new database " << O2DBName
+ << "..." << endl;
+ database.create( O2DBName, "TestSMSchema" );
+ cout << "Connecting to database " << O2DBName
+ << "..." << endl;
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch(...)
+ {
+ errorDBOpen = -6;
+ }
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Failed at opening newly created database " << errorDBOpen << endl;
+ cout << "Exiting " << endl;
+ return errorDBOpen;
+ }
+
+ char c;
+
+ for( int p = 0; p < 4; p++ )
+ {
+ for ( int s = 0; s < 2 ; s++)
+ {
+ ta.begin( &database );
+ cout << endl << "Populate collection " << s <<" " << p << " ..." << endl;
+ testConstructors( collName, s, p );
+ cout <<"Transaction abort (A/a) or commit (default)? ";
+ cin >> c;
+ if ( c == 'A' || c == 'a' )
+ {
+ ta.abort( );
+ cout <<"End of Transaction Abort..."<<endl;
+ }
+ else
+ {
+ ta.commit( );
+ cout <<"End of transaction commit... "<<endl;
+ }
+ }
+ }
+
+
+ ta.begin(&database );
+ // read coll and print contents
+ cout << endl << "Read collection " << collName << " and print contents..." << endl;
+ testAccessing( collName );
+ ta.commit( );
+ cout <<"End of transaction commit... "<<endl;
+
+ cout << endl << "Ending O2 session..." << endl;
+ database.close( );
+ delete myAdmin;
+
+ free( O2DBName );
+ if ( collName != defaultCollName ) free( collName );
+ return 0;
+
+}
+
+/*************************************************************
+ * Functions......:
+ *
+ * static void
+ * testConstructors( char* collName )
+ *
+ ************************************************************/
+static void testConstructors( char* collName, int s, int p )
+{
+
+ const BaseType* mddType;
+ char* uLongCells;
+
+ cout << "....testConstructors"<< endl;
+
+
+ PersMDDObj* accessedObj;
+
+ try{
+ PersMDDColl objsSet(collName);
+
+ cout << "Iterating through the collection with PersMDDCollIter " << endl;
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ cout << endl << i<<". MDD object in set:" << endl;
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+ // accessedObj->printStatus();
+ EOId eoid;
+ if ( accessedObj->getEOId( &eoid ) ==0 )
+ cout <<"EOId: " << eoid;
+ cout << endl << endl;
+
+ mddType = accessedObj->getCellType( );
+
+ r_Minterval firstYear("[1:365,1:60,1:100]");
+
+ vector< Tile* >* firstYearTiles = accessedObj->intersect( firstYear );
+
+ for ( int j = 0; j < firstYearTiles->size( ); j++ )
+ {
+ r_Minterval dom = (*firstYearTiles)[j]->getDomain( );
+
+/*
+ for( int p = 0; p < 4; p++ )
+ {
+ for ( int s = 0; s < 2 ; s++)
+ {
+*/
+ r_Point desl( (r_Range) 730, (p+1)*60, (s+1)* 100 );
+
+ r_Minterval newDom( dom.dimension( ) );
+ newDom.intersection_of( dom, "[1:365,1:60,1:100]");
+ newDom.translate( desl );
+ cout << "dom" << dom << "newDom " << newDom << endl;
+
+ int sz = mddType->getSize( ) * newDom.cell_count( );
+ uLongCells = new char[sz];
+ PersTile* tile1Obj1 = new PersTile( newDom, mddType, uLongCells );
+ accessedObj->insertTile(tile1Obj1);
+
+/*
+ }
+ }
+
+*/
+ }
+ delete firstYearTiles;
+ }
+
+ delete objsIt;
+
+ cout << "Release all " << endl;
+ objsSet.releaseAll( );
+ }
+ catch ( r_Error& errObj)
+ {
+ cout << "Error caught when opening collection" << endl;
+ }
+
+}
+
+
+/*************************************************************
+ * Function......: testAccessing( char* cn )
+ ************************************************************/
+
+static void testAccessing( char* cn )
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testAccessing collection "<< cn << endl;
+
+ try{
+ PersMDDColl objsSet( cn );
+
+ // To test PersMDDColl::printStatus( )
+ // objsSet.printStatus( );
+
+ // To test PersMDDObj::printStatus( ), MDDCollIter::createIterator( ) and
+ // MDDCollIter methods :
+
+ cout << "Iterating through the collection with PersMDDCollIter " << endl;
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ cout << i<<". MDD object in set:" << endl;
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+ accessedObj->printStatus();
+ EOId eoid;
+ if ( accessedObj->getEOId( &eoid ) ==0 )
+ cout <<"EOId: " << eoid;
+ }
+ delete objsIt;
+ objsSet.releaseAll( );
+ }
+ catch ( r_Error& errObj)
+ {
+ cout <<"Error caught ................."<< endl;
+ }
+}
+
diff --git a/mddmgr/test/test_mddjoin.cc b/mddmgr/test/test_mddjoin.cc
new file mode 100644
index 0000000..c7ae617
--- /dev/null
+++ b/mddmgr/test/test_mddjoin.cc
@@ -0,0 +1,228 @@
+/*
+* 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_mddjoin.cc
+ *
+ * MODULE: example for making one tile out of a vector of
+ * Tiles
+ *
+ * COMMENTS:
+ * later has to be moved to the executor
+ *
+*/
+
+static const char rcsid[] = "@(#)blobif,test_mddops: $Id: test_mddjoin.cc,v 1.9 2002/09/03 14:46:50 coman Exp $";
+
+#include <stdlib.h>
+#include <iostream>
+#include "ulongtype.hh"
+#include "booltype.hh"
+#include "mddmgr/persmddobj.hh"
+#include "mddmgr/perstile.hh"
+#include "mddmgr/transtile.hh"
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+#include "raslib/rminit.hh"
+#include "typefactory.hh"
+
+// global variable for AdminIf because of O2 d_Session::begin()
+extern char* myExecArgv0 = "";
+
+RMINITGLOBALS('C')
+
+static char O2BenchDBName[] = "NorbertBase";
+static char O2BenchSchemaName[] = "NorbertSchema";
+
+static void testOperations( DatabaseIf myDB );
+
+static BaseType* myType;
+static BaseType* boolType;
+
+/*************************************************************
+ * Function name.: int main( int argc, char** argv)
+ *
+ * Arguments.....:
+ * argc: number of arguments given to program
+ * argv: array of char* with arguments
+ * Return value..: exit status
+ * Description...: none
+ ************************************************************/
+
+int
+main( int /* argc */, char** argv)
+{
+ // variables representing O2 database, ta and session
+ DatabaseIf database;
+ TransactionIf ta;
+
+ // don't forget to initialize before using AdminIf!
+ myExecArgv0 = argv[0];
+ AdminIf* myAdmin = AdminIf::instance();
+
+ // connect to the database
+ cout << "Connecting to database " << O2BenchDBName
+ << "..." << endl;
+ database.open( O2BenchDBName );
+ ta.begin(&database);
+
+ // only possible after AdminIf::instance on Sun!
+ myType = TypeFactory::mapType("ULong");
+ boolType = TypeFactory::mapType("Bool");
+
+ testOperations( database );
+
+ ta.commit();
+ cout << "Ending O2 session..." << endl;
+ database.close();
+ delete myAdmin;
+}
+
+void
+printAllTiles(const MDDObj* mdd)
+{
+ // contains all tiles of MDD
+ vector<Tile*>* allTiles;
+ // iterator
+ vector<Tile*>::iterator tileIt;
+ // domains of a tile
+ r_Minterval tileDom;
+
+ // domain of MDD object
+ r_Minterval dom;
+ dom = mdd->getCurrentDomain();
+
+ // get all tiles of result MDD
+ allTiles = mdd->intersect(dom);
+
+ // and iterate over them
+ tileIt = allTiles->begin();
+ while (tileIt != allTiles->end())
+ {
+ tileDom = (*tileIt)->getDomain();
+ cout << "Domain of Tile: ";
+ tileDom.print_status();
+ cout << endl;
+
+ cout << "Tile: " << endl;
+ (*tileIt)->printStatus();
+ cout << endl;
+
+ tileIt++;
+ }
+}
+
+/*************************************************************
+ * Function......: testConstructors( DatabaseIf myDB )
+ *
+ * Arguments.....:
+ * myDB: database to use (should be opened)
+ * Return value..: none
+ * Description...: constructs BLOBTiles and inserts them
+ * in root collection.
+ ************************************************************/
+
+static void testOperations( DatabaseIf /* myDB */)
+{
+ unsigned long cell = 1000;
+
+ ULongType ulongtype;
+ BaseType* type = &ulongtype;
+ Tile* res;
+ Tile* boolTile;
+
+ vector<Tile*>* result = new vector<Tile*>;
+ vector<Tile*>::iterator tileIt;
+ Tile* bigTile;
+
+ cout << "Creating Tile: ";
+ r_Minterval bigDom =
+ r_Minterval(3) << r_Sinterval(1l,10l) << r_Sinterval(1l,10l)
+ << r_Sinterval(1l,10l);
+ bigDom.print_status();
+ cout << endl;
+
+ bigTile = new PersTile(bigDom, type, (char*)&cell);
+
+ r_Minterval smallDom
+ = r_Minterval(3) << r_Sinterval(1l,6l) << r_Sinterval(1l,6l)
+ << r_Sinterval(1l,6l);
+
+ cout << "Splitting it into ";
+ smallDom.print_status();
+ cout << " tiles." << endl;
+
+ result = bigTile->splitTile(smallDom);
+
+ cout << "Result tiles: " << endl;
+ // and iterate over them
+ tileIt = result->begin();
+ while (tileIt != result->end())
+ {
+ cout << " Domain of Tile " << (tileIt - result->begin()) << ": ";
+ ((*tileIt)->getDomain()).print_status();
+ cout << endl;
+
+ tileIt++;
+ }
+
+ cout << "Joining the Tiles again:" << endl;
+
+ r_Minterval proj =
+ r_Minterval(3) << r_Sinterval(2l,9l) << r_Sinterval(2l,9l)
+ << r_Sinterval(2l,9l);
+
+ res = new TransTile(result, proj );
+
+ cout << " Result MDD equals original MDD: ";
+ boolTile = new TransTile(res->getDomain(), boolType);
+ cout << "Domain of result Tile: ";
+ (res->getDomain()).print_status();
+ cout << endl;
+ res->printStatus();
+ boolTile->execBinaryOp(Ops::OP_EQUAL, proj,
+ res, proj,
+ bigTile, proj);
+
+ char init = 1;
+
+ cout << "Checking if Tile are equal: ";
+ cout << (int)(*(boolTile->execCondenseOp(Ops::OP_ALL,
+ res->getDomain(),
+ &init ))) << endl;
+
+ cout << "Creating a trimmed, projected 2-D Tile out of the Tile:" << endl;
+ set<r_Dimension, less<r_Dimension> >* projSet =
+ new set<r_Dimension, less<r_Dimension> >;
+ projSet->insert(1);
+
+ r_Minterval projDom =
+ r_Minterval(3) << r_Sinterval(2l, 9l) << r_Sinterval(5l, 5l)
+ << r_Sinterval(2l, 9l);
+
+ Tile* projectedTile = new TransTile(res, projDom, projSet);
+
+ projectedTile->printStatus();
+
+ cout << endl;
+}
diff --git a/mddmgr/test/test_mddobj.cc b/mddmgr/test/test_mddobj.cc
new file mode 100644
index 0000000..5bb70c0
--- /dev/null
+++ b/mddmgr/test/test_mddobj.cc
@@ -0,0 +1,473 @@
+/*
+* 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_mddobj.cc
+ *
+ * MODULE: test for mddobj of mddmgr
+ *
+ * COMMENTS:
+ * in order to compile this test program, getDBMDDObjId from
+ * PersMDDObj has to be made public, which is not the normal
+ * and expected case.
+ *
+*/
+
+#include <stdlib.h>
+#include <iostream>
+#include "mddmgr/perstile.hh"
+#include "ulongtype.hh"
+#include "mddmgr/persmddobj.hh"
+#include "mddmgr/persmddcoll.hh"
+#include "mddmgr/mddcoll.hh"
+#include "mddmgr/mddcolliter.hh"
+
+
+#include "raslib/rminit.hh"
+RMINITGLOBALS('C')
+
+#include "mddif/dbmddobj.hh"
+#include "raslib/minterval.hh"
+#include "raslib/sinterval.hh"
+
+// perhaps used later
+static char O2BenchDBName[] = "PaulaRasDaBase";
+static char O2BenchSchemaName[] = "SMRasDaSchema";
+
+static void ClearDB( d_Database &DB );
+static void testAccessing();
+static void testConstructors();
+static void testSearch();
+static void testGetFunctions();
+static void printInterval(r_Minterval* inter);
+void printMemInfo( );
+
+
+/*************************************************************
+ * 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 TestMDDObjContainer of database..." << endl;
+ database.open( O2BenchDBName);
+ ta.begin( );
+ Handle collHandle = 0;
+ collHandle = o2_get_root( "TestMDDObjContainer" );
+ if ( collHandle )
+ {
+ // I don't know if this is needed.
+ o2_unref_handle ( collHandle );
+ database.destroy_persistent_root( "TestMDDObjContainer" );
+ }
+ ta.commit( );
+
+ // connect to the database
+ cout << "Connecting to database " << O2BenchDBName
+ << "..." << endl;
+ database.open( O2BenchDBName );
+
+ // create root collection
+ cout << "Creating root collection..." << endl;
+ ta.begin();
+ database.create_persistent_root( "TestMDDObjContainer",
+ "d_List< d_Ref<DBMDDObj> >",
+ OL_CONSTANT);
+ ta.commit();
+
+ // create indexes and put them in TestMDDObjContainer
+ cout << "Create objects and put in TestMDDObjContainer..." << endl;
+ ta.begin();
+ testConstructors();
+ ta.commit();
+
+ // read index and print contents
+ cout << "Read objects 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();
+
+ /*
+ // test get member functions
+ cout << "Get * from object and print result..." << endl;
+ ta.begin();
+ testGetFunctions();
+ ta.commit();
+ */
+
+ cout << "Ending O2 session..." << endl;
+ session.end();
+ database.close();
+}
+
+/*************************************************************
+ * Function......: testConstructors()
+ *
+ * Arguments.....: none
+ * Return value..: none
+ * Description...: constructs Indices and inserts them
+ * in root collection.
+ ************************************************************/
+
+static void testConstructors()
+{
+ ULongType anyType;
+ char anyCell[] = {0,0,0,0};
+ unsigned long MDDObj1sz = 0;
+
+ cout << "....testConstructors"<< endl;
+
+ // read root object
+ d_List< d_Ref<DBMDDObj> > objsList("TestMDDObjContainer");
+
+ // create MDD Object
+ cout << " mddObj1" << 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);
+ MDDObj1sz += tile1Obj1->getSize( );
+ PersMDDObj* MDDObj1=new PersMDDObj( dom, "ULong");
+ MDDObj1->insertTile(tile1Obj1);
+
+ 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);
+
+ MDDObj1sz += tile1Obj1->getSize( );
+ // MDDObj1->insertTile(tile2Obj1);
+
+ 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);
+ MDDObj1sz += tile3Obj1->getSize( );
+ // MDDObj1->insertTile(tile3Obj1);
+
+ vector<Tile*>* newTiles = new vector< Tile* >;
+ newTiles->push_back(tile2Obj1);
+ newTiles->push_back(tile3Obj1);
+ MDDObj1->insertTiles(*newTiles);
+ delete newTiles;
+
+ objsList.insert_element_last(MDDObj1->getDBMDDObjId());
+
+ cout << "Size of MDDObj1 : " << MDDObj1sz << " - " << MDDObj1sz/1024 << endl;
+ printMemInfo( );
+ cout << "Delete MDDObj1 ..........." << endl;
+ delete MDDObj1;
+ printMemInfo( );
+ cout << endl << endl;
+
+
+ unsigned long MDDObj2sz = 0;
+ cout << " mddObj2 "<< 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);
+ MDDObj2sz += tile1Obj2->getSize( );
+ PersMDDObj* MDDObj2 = new PersMDDObj( dom2, "ULong");
+ MDDObj2->insertTile(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);
+ MDDObj2sz += tile2Obj2->getSize( );
+
+ MDDObj2->insertTile(tile2Obj2);
+
+ objsList.insert_element_last(MDDObj2->getDBMDDObjId());
+
+ cout << "Size of MDDObj2 : " << MDDObj2sz << " - " << MDDObj2sz/1024 << endl;
+ printMemInfo( );
+ cout << "Delete MDDObj2 ..........." << endl;
+ delete MDDObj2;
+ printMemInfo( );
+ cout << endl << endl;
+}
+
+/*************************************************************
+ * Function......: testAccessing()
+ *
+ * Arguments.....: none
+ * Return value..: none
+ * Description...: reads DirTilesIx's and shows contents
+ ************************************************************/
+
+static void testAccessing()
+{
+ DBMDDObjId accessedObj;
+
+ cout << "....testAccessing"<<endl;
+
+ // read root object
+ d_List< DBMDDObjId > objsList("TestMDDObjContainer");
+ // used for iterating
+ d_Iterator< DBMDDObjId > objsIt = objsList.create_iterator();
+
+ for( int i = 1 ; objsIt.not_done(); i++, objsIt.advance())
+ {
+ accessedObj = objsIt.get_element();
+ cout << " --"<<i<<". MDD object in list:" << endl;
+ accessedObj->printStatus();
+ cout << " -- CellTypeName: " << accessedObj->getCellTypeName( ) << endl;
+ }
+
+}
+
+/*************************************************************
+ * Function......: testSearch()
+ *
+ * Arguments.....: none
+ * Return value..: none
+ * Description...: reads Index's and shows contents
+ ************************************************************/
+
+static void testSearch()
+{
+
+ PersMDDColl mddObjsColl ( "TestMDDObjContainer" );
+ MDDObj* accessedObj;
+ MDDCollIter* objsIt = mddObjsColl.createIterator( );
+
+
+/*
+ DBMDDObjId accessedObj;
+
+ cout << "....testSearch"<<endl;
+
+ // read root object
+ d_List< DBMDDObjId > objsList("TestMDDObjContainer");
+ // used for iterating
+ d_Iterator< DBMDDObjId > objsIt = objsList.create_iterator();
+
+*/
+
+ for( int i = 0 ; objsIt->notDone(); i++, objsIt->advance())
+ {
+
+ accessedObj = objsIt->getElement();
+
+ if (i == 0 || i == 1)
+ {
+ vector< Tile* >* entriesList = 0;
+
+ r_Minterval searchInt1(2);
+ r_Minterval searchInt2(3);
+
+ printMemInfo( );
+
+ cout << " -- " << i+1 << ". MDD 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 = accessedObj->intersect(searchInt1);
+ 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 = accessedObj->intersect(searchInt2);
+ break;
+ default: break;
+ }
+
+ printMemInfo( );
+
+ cout << " -- Search result: " << endl;
+ vector<Tile*>::iterator entryIt = entriesList->begin();
+
+ 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 << " Access contents " ;
+ char* tileContents = ( *entryIt )->getContents( );
+
+ cout << endl;
+
+ entryIt++;
+ }
+
+ printMemInfo( );
+ cout << " Release entriesList " << endl;
+
+ delete entriesList;
+ }
+ }
+ delete objsIt;
+}
+
+/*************************************************************
+ * Function......: testGetFunctions()
+ *
+ * Arguments.....: none
+ * Return value..: none
+ * Description...: reads Index's and shows contents
+ ************************************************************/
+
+static void testGetFunctions()
+{
+
+ MDDObj* accessedObj;
+ PersMDDColl persMDDObjsColl ( "TestMDDObjContainer" );
+ MDDColl* mddObjsColl = &persMDDObjsColl;
+
+ MDDCollIter* objsIt = mddObjsColl->createIterator( );
+
+ vector< Tile* >* entriesList;
+
+ cout << "....testGetTiles"<<endl;
+
+ for( int i = 0 ; objsIt->notDone(); i++, objsIt->advance())
+ {
+ r_Minterval currDom;
+ r_Minterval defDom;
+
+ cout << " " << i << ". Object" << endl;
+ accessedObj = objsIt->getElement( );
+
+ defDom = accessedObj->getDefinitionDomain( );
+ cout << " GetDefinitionDomain result: ";
+ printInterval( &defDom );
+ cout << endl;
+
+ currDom = accessedObj->getCurrentDomain( );
+ cout << " GetCurrentDomain result: ";
+ printInterval( &currDom );
+ cout << endl;
+
+ entriesList = accessedObj->getTiles( );
+ cout << " -- GetTiles result: " << endl;
+ vector<Tile*>::iterator entryIt = entriesList->begin();
+
+ 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++;
+ }
+ delete entriesList;
+ }
+ delete objsIt;
+ mddObjsColl->releaseAll( );
+}
+
+/*************************************************************
+ * Function......:
+ *
+ * Arguments.....:
+ * Return value..:
+ * Description...:
+ ************************************************************/
+
+static void printInterval(r_Minterval* inter)
+{
+ for (int i = 0; i <inter->dimension( ); i++)
+ {
+ (*inter)[i].is_low_fixed( )? cout << (*inter)[i].low( ): cout << "*";
+ cout << " - ";
+ (*inter)[i].is_high_fixed( )? cout << (*inter)[i].high( ): cout << "*";
+ cout << ",";
+ }
+}
+
+/*************************************************************
+ * Function......:
+ *
+ * Arguments.....:
+ * Return value..:
+ * Description...:
+ ************************************************************/
+
+void printMemInfo( )
+{
+
+
+ // allows to store values in the program
+ struct mallinfo meminfo = mallinfo();
+
+ cout << " Memory Usage Information : bytes - Kbytes" ;
+ cout << endl;
+
+ cout << " space in arena : " << meminfo.arena << " - " << meminfo.arena/1024 << endl;
+ cout << " number of small blocks : " << meminfo.smblks << " - " << meminfo.smblks/1024 << endl;
+ cout << " number of ordinary blocks : " << meminfo.ordblks << " - " << meminfo.ordblks/1024 << endl;
+ cout << " space in free ordinary blocks : " << meminfo.fordblks << " - " << meminfo.fordblks/1024 << endl;
+ cout << " space in used ordinary blocks : " << meminfo.uordblks << " - " << meminfo.uordblks/1024 << endl;
+
+ // cout << "additional space from last call: " << meminfo.uordblks - memUsed < < endl;
+
+}
+
+
diff --git a/mddmgr/test/test_mddops.cc b/mddmgr/test/test_mddops.cc
new file mode 100644
index 0000000..5a81bc8
--- /dev/null
+++ b/mddmgr/test/test_mddops.cc
@@ -0,0 +1,335 @@
+/*
+* 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_mddops.cc
+ *
+ * MODULE: example for executing operations on MDDs
+ *
+ * PURPOSE:
+ * makes operations on MDDs or parts of them
+ *
+ * COMMENTS:
+ * later has to be moved to the executor
+ *
+*/
+
+static const char rcsid[] = "@(#)blobif,test_mddops: $Id: test_mddops.cc,v 1.10 2002/09/03 14:46:50 coman Exp $";
+
+#include <stdlib.h>
+#include <iostream>
+#include "o2lib_CC.hxx"
+#include "o2template_CC.hxx"
+#include "ulongtype.hh"
+#include "mddmgr/persmddobj.hh"
+#include "mddmgr/perstile.hh"
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+#include "raslib/rminit.hh"
+#include "typefactory.hh"
+
+
+// global variable for AdminIf because of O2 d_Session::begin()
+extern char* myExecArgv0 = "";
+
+RMINITGLOBALS('C')
+
+static char O2BenchDBName[] = "DemoBase";
+static char O2BenchSchemaName[] = "RasDaSchema";
+
+static void testOperations( DatabaseIf myDB );
+
+BaseType* myType;
+static long myCell = 0;
+
+/*************************************************************
+ * Function name.: int main( int argc, char** argv)
+ *
+ * Arguments.....:
+ * argc: number of arguments given to program
+ * argv: array of char* with arguments
+ * Return value..: exit status
+ * Description...: none
+ ************************************************************/
+
+int
+main( int argc, char** argv)
+{
+ // variables representing O2 database, ta and session
+ DatabaseIf database;
+ TransactionIf ta;
+
+ // don't forget to initialize before using AdminIf!
+ myExecArgv0 = argv[0];
+
+ AdminIf* myAdmin = AdminIf::instance();
+
+ // only possible after AdminIf::instance on Sun!
+ myType = TypeFactory::mapType("ULong");
+
+ // connect to the database
+ cout << "Connecting to database " << O2BenchDBName
+ << "..." << endl;
+ database.open( O2BenchDBName );
+
+ testOperations( database );
+
+ cout << "Ending O2 session..." << endl;
+ database.close();
+ delete myAdmin;
+}
+
+void
+printAllTiles(const MDDObj* mdd)
+{
+ // contains all tiles of MDD
+ vector<Tile*>* allTiles;
+ // iterator
+ vector<Tile*>::iterator tileIt;
+ // domains of a tile
+ r_Minterval tileDom;
+
+ // domain of MDD object
+ r_Minterval dom;
+ dom = mdd->getCurrentDomain();
+
+ // get all tiles of result MDD
+ allTiles = mdd->intersect(dom);
+
+ // and iterate over them
+ tileIt = allTiles->begin();
+ while (tileIt != allTiles->end())
+ {
+ tileDom = (*tileIt)->getDomain();
+ cout << "Domain of Tile: ";
+ tileDom.print_status();
+ cout << endl;
+
+ cout << "Tile: " << endl;
+ (*tileIt)->printStatus();
+ cout << endl;
+
+ tileIt++;
+ }
+}
+
+/*************************************************************
+ * Function......: testOperations( DatabaseIf myDB )
+ *
+ * Arguments.....:
+ * myDB: database to use (should be opened)
+ * Return value..: none
+ * Description...: constructs BLOBTiles and inserts them
+ * in root collection.
+ ************************************************************/
+
+MDDObj*
+execBinaryOp( Ops::OpType op,
+ const MDDObj* op1, const r_Minterval& areaOp1,
+ const MDDObj* op2, const r_Minterval& areaOp2 )
+{
+ // contains all tiles of op1
+ vector<Tile*>* allTilesOp1;
+ // contains all tiles of op2 which intersect a given op1 Tile
+ // in the relevant area.
+ vector<Tile*>* intersectTilesOp2;
+ // iterators for tiles of the MDDs
+ vector<Tile*>::iterator tileOp1It;
+ vector<Tile*>::iterator intersectTileOp2It;
+ // domain of tile of Op1
+ r_Minterval tileOp1Dom;
+ // domain of tile of Op2
+ r_Minterval tileOp2Dom;
+ // intersection of domains in relevant area.
+ r_Minterval intersectDom;
+ // pointer to generated result tile
+ PersTile* resTile;
+ // MDDObj for result
+ PersMDDObj* mddres;
+ // translations between the two areas
+ r_Point offset12(areaOp1.dimension());
+ r_Point offset21(areaOp1.dimension());
+ // dummy
+ r_Minterval dummy;
+
+ // calculate translations
+ r_Point originOp1 = areaOp1.get_origin();
+ r_Point originOp2 = areaOp2.get_origin();
+ for(r_Dimension i = 0; i<areaOp1.dimension(); i++)
+ {
+ offset12[i] = originOp2[i] - originOp1[i];
+ offset21[i] = originOp1[i] - originOp2[i];
+ }
+
+ // create MDDObj for result (type has later to be
+ // retrieved from one of the operands)
+ mddres = new PersMDDObj( areaOp1, "ULong" );
+
+ // get all tiles in relevant area of MDD op1
+ allTilesOp1 = op1->intersect(areaOp1);
+
+ // and iterate over them
+ tileOp1It = allTilesOp1->begin();
+ while (tileOp1It != allTilesOp1->end())
+ {
+ // domain of the op1 tile
+ tileOp1Dom = (*tileOp1It)->getDomain();
+
+ // intersect the tile with MDD op2 (including translation)
+ intersectTilesOp2 =
+ op2->intersect(tileOp1Dom.create_translation(offset12));
+
+ // iterate over intersecting tiles
+ intersectTileOp2It = intersectTilesOp2->begin();
+ while (intersectTileOp2It != intersectTilesOp2->end())
+ {
+ tileOp2Dom = (*intersectTileOp2It)->getDomain();
+
+ // the relevant domain is the intersection of the
+ // domains of the two tiles with the relevant area.
+ intersectDom = tileOp1Dom.create_intersection(
+ tileOp2Dom.create_translation(offset21));
+ intersectDom.intersection_with(areaOp1);
+
+ // Creating tile for result. Type should later come from
+ // operand.
+ resTile = new PersTile(intersectDom, myType);
+
+ // carry out operation on the relevant area of the tiles
+ resTile->execBinaryOp(op, intersectDom,
+ (*tileOp1It), intersectDom,
+ (*intersectTileOp2It),
+ intersectDom.create_translation(offset12));
+
+ // insert Tile in result tile
+ mddres->insertTile(resTile);
+
+ intersectTileOp2It++;
+ }
+ tileOp1It++;
+ }
+
+ return mddres;
+}
+
+/*************************************************************
+ * Function......: testConstructors( DatabaseIf myDB )
+ *
+ * Arguments.....:
+ * myDB: database to use (should be opened)
+ * Return value..: none
+ * Description...: constructs BLOBTiles and inserts them
+ * in root collection.
+ ************************************************************/
+
+// function for creating demo tiles
+
+Tile*
+create2DTile( long xmin, long xmax, long ymin, long ymax,
+ BaseType* type )
+{
+ // is copied anyway in constructor
+ unsigned long cell = 0x10000L;
+
+ r_Sinterval s1(xmin, xmax);
+ r_Sinterval s2(ymin, ymax);
+ r_Minterval dom(2);
+ dom << s1 << s2;
+ cout << " Domain of Tile ";
+ dom.print_status();
+ cout << endl;
+ return new PersTile( dom, type, (char*)&cell);
+}
+
+static void testOperations( DatabaseIf myDB )
+{
+ Tile* aTile;
+ ULongType ulongtype;
+ BaseType* type = &ulongtype;
+ MDDObj* res;
+
+ r_Sinterval limits1(1l,10l);
+ r_Sinterval limits2(1l,10l);
+ r_Minterval dom(2);
+ dom << limits1 << limits2;
+
+ r_Sinterval oplimits1(2l,9l);
+ r_Sinterval oplimits2(2l,9l);
+ r_Minterval opdom(2);
+ opdom << oplimits1 << oplimits2;
+
+ r_Sinterval limits21(11l,20l);
+ r_Sinterval limits22(11l,20l);
+ r_Minterval dom2(2);
+ dom2 << limits21 << limits22;
+
+ r_Sinterval oplimits21(12l,19l);
+ r_Sinterval oplimits22(12l,19l);
+ r_Minterval opdom2(2);
+ opdom2 << oplimits21 << oplimits22;
+
+ // create MDD Object for 1st operand
+ cout << "MDD Op1" << endl;
+
+ PersMDDObj* mddop1 = new PersMDDObj( dom, "ULong" );
+
+ cout << " Tile 1 [ 1:5, 1:10 ] " << endl;
+ aTile = create2DTile(1, 5, 1, 10, type);
+ mddop1->insertTile(aTile);
+
+ cout << " Tile 2 [ 6:10, 1:5 ] " << endl;
+ aTile = create2DTile(6, 10, 1, 5, type);
+ mddop1->insertTile(aTile);
+
+ cout << " Tile 3 [ 6:10, 6:10 ] " << endl;
+ aTile = create2DTile(6, 10, 6, 10, type);
+ mddop1->insertTile(aTile);
+
+ mddop1->printStatus();
+
+ // create MDD Object for 2nd operand
+ cout << "MDD Op2" << endl;
+
+ PersMDDObj* mddop2 = new PersMDDObj( dom2, "ULong" );
+
+ cout << " Tile 1 [ 11:17, 11:15 ] " << endl;
+ aTile = create2DTile(11, 17, 11, 15, type);
+ mddop2->insertTile(aTile);
+
+ cout << " Tile 2 [ 11:17, 16:20 ] " << endl;
+ aTile = create2DTile(11, 17, 16, 20, type);
+ mddop2->insertTile(aTile);
+
+ cout << " Tile 3 [ 18:20, 11:20 ] " << endl;
+ aTile = create2DTile(18, 20, 11, 20, type);
+ mddop2->insertTile(aTile);
+
+ mddop2->printStatus();
+
+ res = execBinaryOp(Ops::OP_PLUS, mddop1, opdom, mddop2, opdom2);
+
+ // output result (cast should not be necessary!)
+ ((PersMDDObj*)res)->printStatus();
+ printAllTiles(res);
+
+}
diff --git a/mddmgr/test/test_persmddcoll.cc b/mddmgr/test/test_persmddcoll.cc
new file mode 100644
index 0000000..1a08546
--- /dev/null
+++ b/mddmgr/test/test_persmddcoll.cc
@@ -0,0 +1,768 @@
+/*
+* 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_persmddcoll.cc
+ *
+ * MODULE: test for mddobj of cachetamgr
+ *
+ * PURPOSE:
+ * creates a persistent collection of objects and iterators.
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+
+#include "mymalloc/mymalloc.h"
+
+#include <stdlib.h>
+#include <iostream>
+
+#define TEST_PROTECTED
+#define TEST_PRIVATE
+
+
+#include "ulongtype.hh"
+
+#include "tilemgr/persmddcoll.hh"
+#include "tilemgr/persmddobj.hh"
+#include "tilemgr/perstile.hh"
+
+#include "tilemgr/persmddcolliter.hh"
+
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+
+#include "raslib/rminit.hh"
+#include "typefactory.hh"
+
+#include "mddbasetype.hh"
+#include "mdddomaintype.hh"
+#include "settype.hh"
+
+extern char* myExecArgv0 = "";
+
+RMINITGLOBALS('C')
+
+static char* O2DBName;
+char *collName;
+char defaultCollName[]= "ObjsContainer";
+static int createMDDColl( const char* collName, DatabaseIf* db );
+static void ClearDB( d_Database &DB );
+static void testAccessing( );
+static void testConstructors( );
+static void testRemove( );
+static void testSearch( );
+static void testGetFunctions( );
+static void testLaterInsert( );
+PersTile* createPersTile( const r_Minterval& dom, const BaseType* type );
+static int openCreateDB( const char* O2DBName, DatabaseIf& database );
+
+TransactionIf ta;
+
+/*************************************************************
+ * Function name.: int main( int argc, char** argv)
+ *
+ * Arguments.....:
+ * argc: number of arguments given to program
+ * argv: array of char* with arguments
+ * Return value..: exit status
+ * Description...: none
+ ************************************************************/
+
+int
+main( int argc, char** argv)
+{
+ // variables representing O2 database, ta and session
+ DatabaseIf database;
+ DatabaseIf database1;
+
+ if( argc < 2 ) {
+ cout << "Usage: test_persmddcoll <database> [collName]" << endl;
+ return -1;
+ }
+ O2DBName = argv[1];
+ if ( argc == 3 ) collName = argv[2];
+ else
+ collName = defaultCollName;
+
+ // don't forget to initialize before using AdminIf!
+ myExecArgv0 = argv[0];
+ AdminIf* myAdmin = AdminIf::instance();
+
+ // connect to the database
+ cout << "Connecting to database " << O2DBName
+ << "..." << endl;
+
+ int errorDBOpen = openCreateDB( O2DBName, database );
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Failed at opening newly created database " << errorDBOpen << endl;
+ cout << "Exiting " << endl;
+ return errorDBOpen;
+ }
+
+
+
+ cout << endl << "Deleting root object from the database ..." <<endl;
+ ta.begin( &database );
+ int i = PersMDDColl::destroyRoot( collName, &database );
+ cout << " i == " << i << endl;
+ cout << " &database = " << long( &database) << endl;
+ // database.destroyRootObj( collName );
+ ta.commit( );
+
+
+ ta.begin( &database);
+ createMDDColl( collName, &database );
+ ta.commit( );
+
+ // create collection and objects and put them in the collection
+ cout << endl << "Populate collection ..." << endl;
+ ta.begin( &database );
+ testConstructors( );
+ ta.commit( );
+
+ // read coll and print contents
+ cout << endl << "Read collection and print contents..." << endl;
+ ta.begin( &database );
+ testAccessing( );
+ ta.commit( );
+
+ // connect to the database
+ cout << "Closing database " << O2DBName
+ << "..." << endl;
+ database.close( );
+
+ // connect to the database
+ cout << endl << "Connecting to database SecondBase "
+ << "..." << endl;
+ // database1.open( "SecondBase" );
+
+ errorDBOpen = openCreateDB( "SecondBase", database1 );
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Failed at opening database SecondBase " << errorDBOpen << endl;
+ cout << "Exiting " << endl;
+ return errorDBOpen;
+ }
+
+ // read coll and print contents
+ cout << endl << "Read collection and print contents..." << endl;
+ cout << "Read only? "<< endl;
+ int ro;
+ cin >> ro;
+ ta.begin( &database1, ro );
+ cout << endl << " testAccessing before "<<endl;
+ testAccessing( );
+ ta.commit( );
+
+/*
+ // add some new tiles
+ cout << endl << "Insert more tiles to the existing objects" << endl;
+ ta.begin( &database );
+ testLaterInsert( );
+ ta.commit( );
+
+ // read coll and print contents
+ cout << endl << "Read collection and print contents..." << endl;
+ ta.begin( &database );
+ testAccessing( );
+ ta.commit( );
+
+
+ // search for an interval
+ cout << endl << "Test region search ..." << endl;
+ ta.begin( &database );
+ testSearch( );
+ ta.commit( );
+
+ // search for an interval
+ cout << endl << "Test get functions of MDDObj ..." << endl;
+ ta.begin( &database );
+ testGetFunctions( );
+ ta.commit( );
+
+ // test remove operation and print contents
+ cout << endl << "Test remove ..." << endl;
+ ta.begin( &database );
+ testRemove( );
+ ta.commit( );
+
+ // read coll and print contents
+ cout << endl << "Read collection and print contents..." << endl;
+ ta.begin( &database );
+ testAccessing( );
+ ta.commit( );
+*/
+ cout << endl << "Ending O2 session..." << endl;
+ database.close( );
+ delete myAdmin;
+}
+/*************************************************************
+ * Function......: testConstructors()
+ *
+ ************************************************************/
+PersTile*
+createPersTile( const r_Minterval& dom, const BaseType* type )
+{
+ char* cells = (char*)mymalloc(dom.cell_count() * type->getSize());
+ PersTile* t = new PersTile( dom, type, cells );
+ return t;
+}
+
+/*************************************************************
+ * Function......: testConstructors()
+ *
+ * Arguments.....: none
+ * Return value..: none
+ * Description...: constructs Indices and inserts them
+ * in root collection.
+ ************************************************************/
+
+static void testConstructors()
+{
+ const BaseType* ulongTypeObj = TypeFactory::mapType("ULong");
+ const BaseType* boolTypeObj = TypeFactory::mapType("Bool");
+ char* uLongCells;
+ char* boolCells;
+
+ const MDDBaseType* mType1 =
+ (const MDDBaseType* ) TypeFactory::mapMDDType("TestSMDomainType2D");
+ const MDDBaseType* mType2 =
+ (const MDDBaseType* ) TypeFactory::mapMDDType("TestSMDomainType3D");
+
+ cout << "....testConstructors"<< endl;
+
+
+ // read root object
+
+ try {
+ PersMDDColl objsSet1("WrongName");
+ }
+ catch (...)
+ {
+ cout <<"Error caught ................."<< endl;
+ }
+
+ PersMDDColl objsSet(collName);
+
+/*
+ // test for crash of O2 iterator reset in case the collection is empty
+ cout << "createIterator " << endl;
+ MDDCollIter* it = objsSet.createIterator( );
+ // cout << " Iterator not Done returns " << it->notDone( );
+ // if ( it->notDone( ) ) it->reset( );
+ cout << " Iterator reset " << endl;
+ it->reset( );
+ // cout << " Testing advance on an empty collection" << endl;
+ // it->advance( ); // OK
+ // cout <<" Testing get_element on an empty collection" << endl;
+ // MDDObj* testIterMDDObj = it->getElement( ); // FATAL ERROR
+ // cout <<" get_element returned " << testIterMDDObj << endl;
+*/
+
+ // create MDD Object 1
+
+ cout << " mddObj1" << 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;
+
+
+ r_Minterval tmpInt = *( ( MDDDomainType* ) mType1 )->getDomain( );
+ PersMDDObj* MDDObj1 = new PersMDDObj( mType1, tmpInt );
+
+ PersTile* tile1Obj1 = createPersTile( dom, ulongTypeObj);
+ MDDObj1->insertTile(tile1Obj1);
+
+ cout << " tile 2 = nil, 0-400, 22-24 "<< endl;
+ dom[0].set_interval(0l,400l);
+ dom[1].set_interval(22l,24l);
+ PersTile* tile2Obj1 = createPersTile( dom, ulongTypeObj);
+ MDDObj1->insertTile(tile2Obj1);
+
+ cout << " tile 3 = nil, 0-600, 10-1000 "<< endl;
+ dom[0].set_interval(0l,600l);
+ dom[1].set_interval(10l,1000l);
+ PersTile* tile3Obj1 = createPersTile( dom, ulongTypeObj);
+ MDDObj1->insertTile(tile3Obj1);
+
+ cout << " MDDObj1 == isPersistent:" << MDDObj1->isPersistent( )<< ";" ;
+ MDDObj1->printStatus( );
+ cout << endl;
+
+ objsSet.insert(MDDObj1);
+
+
+ // create MDD Object
+
+ cout << " mddObj2 "<< 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;
+ // PersMDDObj* MDDObj2 = new PersMDDObj( dom2, "Bool");
+
+ tmpInt = *( ( MDDDomainType* ) mType2 )->getDomain( );
+ PersMDDObj* MDDObj2 = new PersMDDObj( mType2, tmpInt );
+
+ PersTile* tile1Obj2 = createPersTile( dom2, boolTypeObj);
+ MDDObj2->insertTile( 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 = createPersTile( dom2, boolTypeObj);
+
+ MDDObj2->insertTile(tile2Obj2);
+
+ cout << " MDDObj2 == isPersistent:" << MDDObj2->isPersistent( )<< ";" ;
+ MDDObj2->printStatus( );
+ cout << endl;
+
+ objsSet.insert(MDDObj2);
+
+ objsSet.releaseAll( );
+
+}
+
+/*************************************************************
+ * Function......: testAccessing()
+ *
+ * Arguments.....: none
+ * Return value..: none
+ * Description...: reads DirTilesIx's and shows contents
+ ************************************************************/
+
+static void testAccessing()
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testAccessing"<<endl;
+ try{
+ PersMDDColl objsSet(collName);
+
+ // To test PersMDDColl::printStatus( )
+ // objsSet.printStatus( );
+
+ // To test PersMDDObj::printStatus( ), MDDCollIter::createIterator( ) and
+ // MDDCollIter methods :
+
+
+ cout << "Iterating through the collection with PersMDDCollIter " << endl;
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+ cout << i<<". MDD object in set:" << endl;
+ accessedObj->printStatus();
+ cout << endl << endl;
+ }
+ delete objsIt;
+ objsSet.releaseAll( );
+ }
+ catch(...)
+ {
+ cout << "Error opening collection !!!! "<<endl;
+ exit(-1);
+ }
+}
+
+/*************************************************************
+ * Function......: testLaterInsert()
+ *
+ * Description...:
+ ************************************************************/
+
+static void testLaterInsert()
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testAccessing"<<endl;
+
+ PersMDDColl objsSet(collName);
+
+ // To test PersMDDColl::printStatus( )
+ // objsSet.printStatus( );
+
+ // To test PersMDDObj::printStatus( ), MDDCollIter::createIterator( ) and
+ // MDDCollIter methods :
+
+
+ cout << "Iterating through the collection with PersMDDCollIter " << endl;
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+
+ PersTile *t, *t2, *t3;
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+ switch( accessedObj->getDimension( ) )
+ {
+ case 2 :
+ t2 = new PersTile( r_Minterval("[40:60,80:100]"),
+ accessedObj->getCellType( ) );
+ t = t2;
+ break;
+ case 3 :
+ t3 = new PersTile(r_Minterval("[40:60,80:100,0:20]"),
+ accessedObj->getCellType( ) );
+ t = t3;
+ break;
+ default:
+ cout << "Error Dimensionality not expected" << endl;
+ break;
+ }
+ accessedObj->insertTile(t);
+ cout << i<<". MDD object in set:" << endl;
+ accessedObj->printStatus();
+ cout << endl << endl;
+ }
+ delete objsIt;
+ objsSet.releaseAll( );
+}
+
+
+/*************************************************************
+ * Function......: testSearch()
+ *
+ * Arguments.....: none
+ * Return value..: none
+ * Description...: reads Index's and shows contents
+ ************************************************************/
+
+static void testSearch()
+{
+
+ MDDObj* accessedObj;
+
+ cout << "....testSearch"<<endl;
+
+ PersMDDColl objsSet(collName);
+
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ accessedObj = objsIt->getElement();
+
+ cout << "Accessed Object " << endl;
+ accessedObj->printStatus( );
+ cout << endl;
+
+ if (i == 1 || i == 2)
+ {
+ r_Minterval searchInt1(2);
+ r_Minterval searchInt2(3);
+ vector< Tile* >* entriesList;
+
+ cout << " -- " << i << ". MDD object in list. Search for:";
+ switch (i) {
+ case 1: searchInt1[0].set_interval(10l,20l);
+ searchInt1[1].set_interval(10l,30l);
+ cout << " 10-20, 10-30" << endl;
+ entriesList = accessedObj->intersect(searchInt1);
+ break;
+ case 2: 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 = accessedObj->intersect(searchInt2);
+ break;
+ default: break;
+ }
+ cout << " -- Search result: " << endl;
+ vector<Tile*>::iterator entryIt = entriesList->begin();
+
+ 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++;
+ }
+ delete entriesList;
+ }
+ }
+ delete objsIt;
+ objsSet.releaseAll( );
+}
+
+/*************************************************************
+ * Function......: testGetFunctions()
+ *
+ * Arguments.....: none
+ * Return value..: none
+ * Description...: reads Index's and shows contents
+ ************************************************************/
+
+static void testGetFunctions()
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testGetFunctions"<<endl;
+
+ PersMDDColl objsSet(collName);
+
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ vector< Tile* >* entriesList;
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ r_Minterval currDom;
+ r_Minterval defDom;
+
+ cout << " " << i << ". Object" << endl;
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+
+
+ defDom = accessedObj->getDefinitionDomain( );
+ cout << " GetDefinitionDomain result: ";
+ defDom.print_status( );
+ cout << endl;
+
+ currDom = accessedObj->getCurrentDomain( );
+ cout << " GetCurrentDomain result: ";
+ currDom.print_status( );
+ cout << endl;
+
+ entriesList = accessedObj->getTiles( );
+ cout << " -- GetTiles result: " << endl;
+ vector<Tile*>::iterator entryIt = entriesList->begin();
+
+ while (entryIt != entriesList->end())
+ {
+ // (*entryIt)->printStatus();
+ r_Minterval tileInterval = (*entryIt)->getDomain();
+ int dimensionality = tileInterval.dimension();
+
+ cout << " PersTile ";
+ cout << " domain == " << dimensionality << ": ";
+ for (int i = 0; i <dimensionality; i++)
+ cout << tileInterval[i].low() << "-" << tileInterval[i].high() <<", ";
+ cout << endl;
+ entryIt++;
+ }
+ delete entriesList;
+ }
+ delete objsIt;
+ objsSet.releaseAll( );
+}
+
+/*************************************************************
+ * Function......: testRemove()
+ *
+ * Arguments.....: none
+ * Return value..: none
+ * Description...: reads DirTilesIx's and shows contents
+ ************************************************************/
+
+static void testRemove()
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testRemove"<<endl;
+
+ PersMDDColl objsSet(collName);
+ // PersMDDColl objsSet("Qualquercoisa");
+ // To test PersMDDColl::printStatus and PersMDDColl::remove
+
+
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ cout << "-- Remove second element from collection " << endl;
+
+ for( int i = 1 ; objsIt->notDone( ) && i < 2; i++, objsIt->advance( ))
+ {
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+ }
+ cout << "Delete of objsIt:" << endl;
+ delete objsIt;
+ cout << "Finished Delete of objsIt." << endl;
+ cout << "Remove accessedObj:" << endl;
+ objsSet.remove( accessedObj );
+ cout << "Finished Remove accessedObj." << endl;
+}
+
+/*************************************************************
+ * Function......: openCreateDB()
+ *
+ ************************************************************/
+
+static int openCreateDB( const char* O2DBName, DatabaseIf& database )
+{
+ cout << "openCreateDB " << O2DBName << endl;
+
+ int errorDBOpen;
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch( ...)
+ {
+ cout << "Caught Exception " << endl;
+ errorDBOpen = -6;
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Database doesn't exist. Create it new ... " << endl;
+ cout << "Creating new database " << O2DBName
+ << "..." << endl;
+ database.create( O2DBName, "TestSMSchema" );
+ cout << endl << "Connecting to database " << O2DBName
+ << "..." << endl;
+
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch(...)
+ {
+ errorDBOpen = -6;
+ }
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Failed at opening newly created database " << errorDBOpen << endl;
+ cout << "Exiting " << endl;
+ return errorDBOpen;
+ }
+ return errorDBOpen;
+}
+
+/*************************************************************
+ * Function......: createMDDColl( )
+ ************************************************************/
+static int
+createMDDColl( const char* collName, DatabaseIf* db )
+{
+ MDDDomainType* mType1 = 0;
+ MDDDomainType* mType2 = 0;
+ MDDType* mt = 0;
+ CollectionType* collType1 = 0;
+
+ const BaseType* ulongTypeObj = TypeFactory::mapType("ULong");
+
+ const MDDDomainType* cmType1 =
+ ( MDDDomainType* ) TypeFactory::mapMDDType( "TestSMDomainType2D" );
+ const MDDDomainType* cmType2 =
+ ( MDDDomainType* ) TypeFactory::mapMDDType( "TestSMDomainType3D" );
+
+ const CollectionType* collType =
+ (CollectionType*)TypeFactory::mapSetType( "ObjsContainerType" );
+
+
+ if( !cmType1 || !cmType2 || !collType )
+ {
+ char name1[] = "TestSMDomainType2D";
+ char name2[] = "TestSMDomainType3D";
+
+ r_Sinterval limits1Obj1(0l,1000l);
+ r_Sinterval limits2Obj1(0l,800l);
+ r_Minterval dom1(2);
+ dom1 << limits1Obj1 << limits2Obj1;
+ cout << "MDD Type 1 , domain "<< dom1 << 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;
+ cout << "MDD Type 2 , domain "<< dom2 << endl;
+
+ // MDDDomainType* mType1 =
+ mType1 =
+ new MDDDomainType((char*) name1, ( BaseType* ) ulongTypeObj, dom1 );
+ // MDDDomainType* mType2 =
+ mType2 =
+ new MDDDomainType((char*) name2, ( BaseType* ) ulongTypeObj, dom2 );
+
+ cout << "MDD Type1 == ";
+ mType1->print_status( cout );
+ cout << endl;
+ cout << "MDD Type2 == ";
+ mType2->print_status( cout );
+ cout << endl;
+
+ TypeFactory::addMDDType( mType1 );
+ TypeFactory::addMDDType( mType2 );
+
+ if ( !collType )
+ {
+ cout << "Collection type newly created " << endl;
+ // MDDType* mt = new MDDType( );
+ mt = new MDDType( );
+ cout << "MDDtype created "<< endl;
+ collType1 = new SetType( "ObjsContainerType", mType1 );
+ cout << "Set Type created ... ";
+ collType = collType1;
+ TypeFactory::addSetType( (SetType*) collType );
+ cout <<" and added "<< endl;
+
+ }
+
+ }
+ cout << "Creating root collection" << endl;
+
+ OId oColl;
+ if( OId::allocateMDDCollOId( &oColl ) == 0 )
+ cout <<"Successfully allocated OId for collection " << oColl << endl;
+ else
+ cout <<"Error allocating OId for collection " << endl;
+
+ PersMDDColl* col;
+ try {
+ // CollectionType* ct = TypeFactory::mapSetType( "ObjsContainerType" );
+ col = PersMDDColl::createRoot( collName, oColl, collType, db );
+ }
+ catch (...)
+ {
+ cout <<"Error caught ................."<< endl;
+ return -1;
+ }
+
+ cout << "Committing TA ..."<< endl;
+ ta.commit( );
+
+ if ( col ) delete col;
+ cout << "Col freed . "<< endl;
+
+ ta.begin( db );
+ return 0;
+}
diff --git a/mddmgr/test/test_persmddobj.cc b/mddmgr/test/test_persmddobj.cc
new file mode 100644
index 0000000..b54a851
--- /dev/null
+++ b/mddmgr/test/test_persmddobj.cc
@@ -0,0 +1,1125 @@
+/*
+* 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_persmddobj.cc
+ *
+ * MODULE: test for PersMDDObj of mddmgr
+ *
+ * PURPOSE:
+ * creates a persistent collection of objects and iterators and tests
+ * usage of O2 OIds.
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+
+#include "mymalloc/mymalloc.h"
+
+#define TEST_PROTECTED
+#define TEST_PRIVATE
+
+#include <stdlib.h>
+#include <iostream>
+
+#include "ulongtype.hh"
+
+#include "mddmgr/persmddcoll.hh"
+#include "mddmgr/persmddobj.hh"
+#include "mddmgr/perstile.hh"
+
+#include "mddmgr/persmddcolliter.hh"
+
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+#include "oidif.hh"
+
+#include "raslib/rminit.hh"
+#include "typefactory.hh"
+
+#include "mddif/dbmddobj.hh"
+#include "mddif/dbmddcoll.hh"
+
+#include "mddbasetype.hh"
+#include "mdddomaintype.hh"
+#include "settype.hh"
+
+
+/*
+ Global Variables
+*/
+extern char* myExecArgv0 = "";
+
+RMINITGLOBALS('C')
+
+static char* O2DBName;
+char *collName;
+char defaultCollName[]= "ObjsContainer";
+OId globalOId1, globalOId2;
+OId globalCollOId;
+EOId globalEOId[4];
+int numObjsCreated;
+TransactionIf ta;
+int ExitNo;
+
+/*
+ Functions
+*/
+
+int
+getOption( )
+{
+ unsigned int result;
+ cout << endl;
+ cout << "Choose Option : " << endl;
+ cout << "-----------------------------------------------------------------"<<endl;
+ cout << " 1 - Create MDD collection with name .. " << collName << endl;
+ cout << " 2 - Populate collection with MDD objects (testConstructors) " << endl;
+ cout << " 3 - Access MDD collection given name (testAccessing) " << endl;
+ cout << " 4 - Access MDD collection given OId (testAccessing)" << endl;
+ cout << " 5 - Access MDD object given OId (testAccessingMDDObj) " << endl;
+ cout << " 6 - Remove MDD object from the collection given OId (testRemove) "<<endl;
+ cout << " 7 - Test PersMDDObj::intersect( ) (testSearch) " <<endl;
+ cout << " 8 - Test PersMDDColl::getCardinality( ) "<<endl;
+ cout << " 9 - Test PersMDDObj get functions "<< endl;
+ cout << " 10 - Remove MDD Collection given OId " << endl;
+ cout << " 11 - Insert MDD given OId in a second collection "<< endl;
+ cout << " 12 - Insert tile in MDD given OId "<< globalOId1 <<endl;
+ cout << " 13 - Test removeTile from MDD "<< globalOId1 << endl;
+ ExitNo = 14;
+ cout << " " << ExitNo << " - Exit " << endl;
+ cout << "------------------------------------------------------------------"<<endl;
+ cout << "Enter option: ";
+ cin >> result;
+ return result;
+}
+
+// 1 - Create MDD collection
+static int createMDDColl( const char* collName, DatabaseIf* db );
+
+// 2 - Populate collection with MDD objects
+static void testConstructors( char* cn );
+
+// 3 - Retrieves an MDD collection with name cn and prints contents:
+static void testAccessing( char* cn );
+
+// 4 - Retrieves an MDD collection with OId o and prints contents:
+static void testAccessing( OId o );
+
+// 5 - Retrieves an MDD object with OId o and prints contents:
+static void testAccessingMDDObj( OId o );
+
+// Removes one of the MDD objects in the collection
+static void testRemove( );
+
+// 6 - Removes MDD object with OId o in the collection
+static void testRemove( OId o );
+
+// 7 - Test PersMDDObj::intersect( ) objects of the collection
+static void testSearch( );
+
+// 8 - Test PersMDDColl::getCardinality( )
+static void testGetCardinality( char* cn);
+
+// 9 - Scans collection and tests PersMDDObj get functions
+static void testGetFunctions( );
+
+//10 - Remove MDD collection given OId
+
+//11 - Insert MDD given OId in a second collection
+static void testInsertMDDObjColl( OId o, char* cn );
+
+//12 - Test later insertion of tile in PersMDDObj
+static void testLaterInsert( OId o );
+
+//13 - Test removeTile from an MDD obj
+static void testRemoveTile( OId o );
+
+// Tries accessing several OIds, including ilegal ones, to test
+// several error conditions.
+static void testAccessingOId( );
+
+
+/*************************************************************
+ * Function name.: int main( int argc, char** argv)
+ *
+ * Arguments.....:
+ * argc: number of arguments given to program
+ * argv: array of char* with arguments
+ * Return value..: exit status
+ * Description...: none
+ ************************************************************/
+int
+main( int argc, char** argv)
+{
+ // variables representing O2 database, ta and session
+ DatabaseIf database;
+
+ if( argc < 2 ) {
+ cout << "Usage: test_persmddcoll <database> [collName]" << endl;
+ return -1;
+ }
+ O2DBName = strdup( argv[1] );
+ if ( argc == 3 ) collName = strdup( argv[2] );
+ else
+ collName = defaultCollName;
+
+ // don't forget to initialize before using AdminIf!
+ myExecArgv0 = argv[0];
+ AdminIf* myAdmin = AdminIf::instance();
+
+
+ // connect to the database
+ cout << "Connecting to database " << O2DBName
+ << "..." << endl;
+ int errorDBOpen;
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch( ...)
+ {
+ cout << "Caught Exception " << endl;
+ errorDBOpen = -6;
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Database doesn't exist. Create it new ... " << endl;
+ cout << "Creating new database " << O2DBName
+ << "..." << endl;
+ database.create( O2DBName, "TestSMSchema" );
+ cout << "Connecting to database " << O2DBName
+ << "..." << endl;
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch(...)
+ {
+ errorDBOpen = -6;
+ }
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Failed at opening newly created database " << errorDBOpen << endl;
+ cout << "Exiting " << endl;
+ return errorDBOpen;
+ }
+
+ ta.begin( &database );
+ cout << endl << "Deleting root object from the database ..." <<endl;
+ int i = PersMDDColl::destroyRoot( collName, &database );
+ cout << " i == " << i << endl;
+ // cout << " &database = " << long( &database) << endl;
+ ta.commit( );
+
+ char c;
+ int error;
+
+ for( unsigned opt = getOption( ); opt != ExitNo ; opt = getOption( ) )
+ {
+ cout <<"Transaction begin ... " << endl;
+ ta.begin( &database );
+ switch ( opt )
+ {
+ case 1: // 1 - Create MDD collection with name
+ // create root collection
+ cout << endl << "Creating mdd types and root collection..." << endl;
+ if ( createMDDColl( collName, &database ) != 0 )
+ {
+ cout <<"Error caught ................."<< endl;
+ cout << endl << "Ending O2 session..." << endl;
+ ta.commit( );
+ database.close( );
+ delete myAdmin;
+ exit( 1 );
+ }
+ break;
+
+ case 2: // 2 - Populate collection with MDD objects (testConstructors)
+ // create objects and put them in the collection
+ cout << endl << "Populate collection ..." << endl;
+ testConstructors( collName );
+ break;
+
+ case 3: // 3 - Access MDD collection given name (testAccessing)
+ // read coll and print contents
+ cout << endl << "Read collection " << collName << " and print contents..." << endl;
+ testAccessing( collName );
+ break;
+
+ case 4: // 4 - Access MDD collection given OId (testAccessing)
+ cout << endl << "Read collection " << globalCollOId << " and print contents..." << endl;
+ testAccessing( globalCollOId );
+ break;
+
+ case 5: // 5 - Access MDD object given OId (testAccessingMDDObj)
+ cout << endl << "Test Accessing MDD with OId " << globalOId1 << " ... " << endl;
+ testAccessingMDDObj( globalOId1 );
+ break;
+
+ case 6: // 6 - Remove MDD object from the collection given OId (testRemove)
+ cout<< endl << "Remove MDD with OId " << globalOId1 << " ..." << endl;
+ testRemove( globalOId1 );
+ break;
+
+ case 7: // 7 - Test PersMDDObj::intersect( ) (testSearch)
+ cout << endl << "Test region search ..." << endl;
+ testSearch( );
+ break;
+
+ case 8: // 8 - Test PersMDDColl::getCardinality( )
+ cout << endl << "Get cardinality of collection" << collName <<" ..." << endl;
+ testGetCardinality( collName );
+ break;
+
+ case 9: // 9 - Test PersMDDObj get functions
+ cout << endl <<"Test PersMDDObj get functions " << endl;
+ testGetFunctions( );
+ break;
+
+ case 10: // 10 - Remove MDD Collection given OId
+ cout << endl << "Remove MDD collection with OId ";
+ cout << globalCollOId << " ..." << endl;
+ error = PersMDDColl::destroyRoot( globalCollOId, &database );
+ if (error )
+ cout << " Error destroying root " << endl;
+ break;
+
+ case 11: // 11 - Insert MDD given OId in a second collection
+ cout << endl << "Insert Object with OId " << globalOId1;
+ cout << " in collection Coleccao1 " << endl;
+ cout << "First, create collection" << endl;
+ if ( createMDDColl( "Coleccao1", &database ) != 0 )
+ {
+ cout <<"Error caught ................."<< endl;
+ cout << endl << "Ending O2 session..." << endl;
+ ta.commit( );
+ database.close( );
+ delete myAdmin;
+ exit( 1 );
+ }
+ cout << "Then insert object with OId "<< globalOId1 << endl;
+ testInsertMDDObjColl( globalOId1 , "Coleccao1");
+ cout << endl;
+ break;
+
+ case 12: // 12 - Insert new tiles in the MDD object
+ cout << endl << "Insert Tile in object with OId " << globalOId1;
+ testLaterInsert( globalOId1 );
+ cout << endl;
+ break;
+
+ case 13: // 13 - Remove a tile from the MDD object
+ cout << endl << "Remove Tile from object with OId " << globalOId1;
+ testRemoveTile( globalOId1 );
+ cout << endl;
+ break;
+
+ default:
+ break;
+ }
+ cout <<"Transaction abort (A/a) or commit (default)? ";
+ cin >> c;
+ if ( c == 'A' || c == 'a' )
+ {
+ ta.abort( );
+ cout <<"End of Transaction Abort..."<<endl;
+ }
+ else ta.commit( );
+ if ( opt == 6 )
+ {
+ cout<<"Garbage ? ( y /n ) ";
+ cin >> c;
+ if (c =='y' || c == 'Y' )
+ {
+ cout <<"Garbaging ..."<< endl;
+ ta.begin( &database );
+ database.garbage( );
+ ta.commit( );
+ }
+ }
+ cout <<"End of transaction commit... "<<endl;
+ } // for opt
+
+
+ cout << endl << "Ending O2 session..." << endl;
+ database.close( );
+ delete myAdmin;
+
+ free( O2DBName );
+ if ( collName != defaultCollName ) free( collName );
+ return 0;
+
+}
+
+/*************************************************************
+ * Functions......:
+ *
+ * static void
+ * testInsertMDDObjColl( OId o, char* cn )
+ *
+ * static void
+ * testConstructors( char* collName )
+ *
+ ************************************************************/
+static void
+testInsertMDDObjColl( OId o, char* cn )
+{
+ cout << "....testInsertMDDObjColl "<< o <<","<< cn << endl;
+ PersMDDObj* obj = new PersMDDObj( O2DBName,o );
+ PersMDDColl objsSet( cn );
+ objsSet.insert( obj );
+ delete obj;
+
+}
+
+static void testConstructors( char* collName )
+{
+
+ const BaseType* ulongTypeObj = TypeFactory::mapType("ULong");
+ const BaseType* boolTypeObj = TypeFactory::mapType("Bool");
+ // char uLongCell[] = {0,0,0,0};
+ char* uLongCells;
+ // char boolCell = 0;
+ char* boolCells;
+
+
+ const MDDBaseType* mType1 =
+ (const MDDBaseType* ) TypeFactory::mapMDDType("TestSMDomainType2D");
+ const MDDBaseType* mType2 =
+ (const MDDBaseType* ) TypeFactory::mapMDDType("TestSMDomainType3D");
+
+ cout << "....testConstructors"<< endl;
+
+ OId oid1;
+ if ( OId::allocateMDDOId( &oid1 ) == 0)
+ cout << "Successfull allocation of OId " << oid1 <<endl;
+ else
+ {
+ cout << "Error by allocation of OId" <<endl;
+ exit(1);
+ }
+ OId oid2;
+ if ( OId::allocateMDDOId( &oid2 ) == 0)
+ cout << "Successfull allocation of OId " << oid2 <<endl;
+ else
+ {
+ cout << "Error by allocation of OId" <<endl;
+ exit(1);
+ }
+
+ globalOId1 = oid1;
+ globalOId2 = oid2;
+
+ // read root object
+
+ PersMDDColl objsSet(collName);
+
+
+ // create MDD Object 1
+
+ cout << "Creating mddObj1" << 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;
+
+ r_Minterval tmpInt = *( ( MDDDomainType* ) mType1 )->getDomain( );
+ PersMDDObj* MDDObj1 = new PersMDDObj( mType1, tmpInt, O2DBName, oid1 );
+
+
+ uLongCells = (char*) mymalloc( dom.cell_count() * ulongTypeObj->getSize() );
+ PersTile* tile1Obj1 = new PersTile( dom, ulongTypeObj, uLongCells );
+
+ MDDObj1->insertTile(tile1Obj1);
+
+ cout << "tile 2 = nil, 0-400, 22-24 "<< endl;
+ dom[0].set_interval(0l,400l);
+ dom[1].set_interval(22l,24l);
+
+ uLongCells = (char*) mymalloc( dom.cell_count() * ulongTypeObj->getSize() );
+ PersTile* tile2Obj1 = new PersTile( dom, ulongTypeObj, uLongCells );
+ MDDObj1->insertTile(tile2Obj1);
+
+ cout << "tile 3 = nil, 0-600, 10-1000 "<< endl;
+ dom[0].set_interval(0l,600l);
+ dom[1].set_interval(10l,1000l);
+ uLongCells = (char*) mymalloc( dom.cell_count() * ulongTypeObj->getSize() );
+ PersTile* tile3Obj1 = new PersTile( dom, ulongTypeObj, uLongCells );
+ MDDObj1->insertTile(tile3Obj1);
+
+ cout << "MDDObj1 == isPersistent:" << MDDObj1->isPersistent( )<< ";" <<endl;
+ MDDObj1->printStatus( );
+ cout << endl;
+
+ objsSet.insert(MDDObj1);
+
+ // create MDD Object
+ cout << "Creating mddObj2 "<< 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;
+
+ tmpInt = *( ( MDDDomainType* ) mType2 )->getDomain( );
+ PersMDDObj* MDDObj2 = new PersMDDObj( mType2, tmpInt, O2DBName, oid2 );
+
+ boolCells = (char*) mymalloc( dom2.cell_count() * boolTypeObj->getSize() );
+ PersTile* tile1Obj2 = new PersTile( dom2, boolTypeObj, boolCells);
+ MDDObj2->insertTile( 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);
+ boolCells = (char*) mymalloc( dom2.cell_count() * boolTypeObj->getSize() );
+ PersTile* tile2Obj2 = new PersTile( dom2, boolTypeObj, boolCells );
+
+ MDDObj2->insertTile(tile2Obj2);
+
+
+ cout << "MDDObj2 == isPersistent:" << MDDObj2->isPersistent( )<< ";" <<endl;
+ MDDObj2->printStatus( );
+ cout << endl;
+
+/*
+ // This program doesn't work if the TA is aborted when OIds are
+ // allocated, even if all allocated OIds are binded. Question: is it
+ // because of dangling handles? This little test was done to
+ // check that.
+ // This without oids works with ta.abort
+ // conclusion: the problem with abort is not due to the handles
+ Handle hd;
+ d_Ref<DBMDDObj> refObj = MDDObj2->getDBMDDObjId();
+ hd = refObj.o2_get_handle();
+*/
+
+
+ objsSet.insert(MDDObj2);
+ numObjsCreated = 2;
+
+ cout << "Release all " << endl;
+
+ ( ( PersMDDColl ) objsSet ).releaseAll( );
+
+}
+
+
+/*************************************************************
+ * Function......: testAccessing( char* cn )
+ * testAccessing( OId o )
+ ************************************************************/
+
+static void testAccessing( char* cn )
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testAccessing collection "<< cn << endl;
+
+ try{
+ PersMDDColl objsSet( cn );
+
+ // To test PersMDDColl::printStatus( )
+ // objsSet.printStatus( );
+
+ // To test PersMDDObj::printStatus( ), MDDCollIter::createIterator( ) and
+ // MDDCollIter methods :
+
+ cout << "Iterating through the collection with PersMDDCollIter " << endl;
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ cout << i<<". MDD object in set:" << endl;
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+ accessedObj->printStatus();
+ EOId eoid;
+ if ( accessedObj->getEOId( &eoid ) ==0 )
+ cout <<"EOId: " << eoid;
+ // old version cout <<"EOId: " << eoid.getSystemName( ) << eoid.getBaseName( ) << eoid.getOId( );
+ cout << endl << endl;
+ accessedObj->getEOId( &globalEOId[i-1] );
+ }
+ delete objsIt;
+ objsSet.releaseAll( );
+ }
+ catch ( r_Error& errObj)
+ {
+ cout <<"Error caught ................."<< endl;
+ }
+}
+
+static void testAccessing( OId o )
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testAccessing collection "<< o << endl;
+
+ try {
+ PersMDDColl objsSet( o, O2DBName );
+
+ OId o;
+ if ( objsSet.getOId( &o ) == 0 )
+ cout <<"getOId " << o << endl;
+ else
+ cout <<"Error getOId " << endl;
+
+ EOId eo;
+ if ( objsSet.getEOId( &eo ) == 0 )
+ cout << "getEOId " << eo <<endl;
+ // cout << "getEOId " << eo.getSystemName( ) <<":"<<eo.getBaseName( )<<":"<<eo.getOId( ) << endl;
+ else
+ cout <<"Error getEOId " << endl;
+
+ // To test PersMDDColl::printStatus( )
+ objsSet.printStatus( );
+
+ // To test PersMDDObj::printStatus( ), MDDCollIter::createIterator( ) and
+ // MDDCollIter methods :
+
+ cout << "Iterating through the collection with PersMDDCollIter " << endl;
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ cout << i<<". MDD object in set:" << endl;
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+ accessedObj->printStatus();
+ EOId eoid;
+ if ( accessedObj->getEOId( &eoid ) ==0 )
+ cout <<"EOId: " << eoid ;
+ // cout <<"EOId: " << eoid.getSystemName( ) << eoid.getBaseName() << eoid.getOId( );
+ cout << endl << endl;
+ accessedObj->getEOId( &globalEOId[i-1] );
+ }
+ delete objsIt;
+ objsSet.releaseAll( );
+ }
+ catch ( r_Error& errObj)
+ {
+ cout <<"Error caught ................."<< endl;
+ }
+
+}
+
+/*************************************************************
+ * Function......: testAccessingMDDObj(OId o )
+ * testAccessingOId( )
+ *
+ ************************************************************/
+static void testAccessingMDDObj(OId o)
+{
+ PersMDDObj *mObj;
+
+ cout << "....testAccessingMDDObj"<<endl;
+
+ try{
+ mObj = new PersMDDObj( O2DBName, o);
+ mObj->printStatus( );
+ delete mObj;
+ }
+ catch (...)
+ {
+ cout <<" Object not found..." << endl;
+
+ }
+}
+
+static void testAccessingOId()
+{
+ PersMDDObj *mObj1, *mObj2, *mObj;
+ Handle hdObj;
+ int result;
+ OId o(70000);
+ OId o1(5010);
+ OId o2(0);
+ OId o3(5);
+
+ cout << "....testAccessingOId"<<endl;
+
+
+ cout << "Test OIdIf::getType( )..."<<endl;
+ cout << "1.st MDDObj " << endl;
+ cout << "getType " << globalOId1.getType( O2DBName ) << endl;
+
+ cout << "2.nd MDDObj " << endl;
+ cout << "getType " << globalOId2.getType( O2DBName ) << endl;
+
+ // This crashes
+ // cout << "OId == 0 " << endl;
+ // cout << "getType " << o2.getType( O2DBName ) << endl;
+
+ cout << "OId == 5 " << endl;
+ cout << "getType " << o3.getType( O2DBName ) << endl;
+
+ cout << "MDDCollection " << endl;
+ cout << "getType " << globalCollOId.getType( O2DBName ) << endl;
+ // mObj2 = new PersMDDObj( O2DBName, globalOId2);
+ // mObj2->printStatus( );
+
+ cout << "Not used OId " << endl;
+ cout << "getType " << o1.getType( O2DBName ) << endl;
+
+ cout << "Nonexistent OId " << endl;
+ cout << "getType " << o.getType( O2DBName ) << endl;
+ // mObj2 = new PersMDDObj( O2DBName, globalOId2);
+ // mObj2->printStatus( );
+
+ cout <<"Loading PersMDDObjs from OIds " << endl;
+ mObj1 = new PersMDDObj( O2DBName, globalOId1);
+ mObj1->printStatus( );
+ mObj2 = new PersMDDObj( O2DBName, globalOId2);
+ mObj2->printStatus( );
+
+ delete mObj1;
+ delete mObj2;
+
+
+ for ( int i = 0; i < numObjsCreated; i++ )
+ {
+ cout << "Reading with " << i+1<< ".th EOId " ;
+ cout << globalEOId[i];
+ // cout << globalEOId[i].getSystemName( );
+ // cout << " ; "<< globalEOId[i].getBaseName( ) << ";" << globalEOId[i].getOId( );
+ cout << endl;
+
+
+ // result = o2_externalNameGetObject( &globalEOId[i], &hdObj );
+ result = globalEOId[i].getObject( &hdObj );
+ if ( result == 0 )
+ {
+ DBMDDObjId obj1(hdObj);
+ mObj = new PersMDDObj(obj1);
+ mObj->printStatus( );
+ }
+ else
+ cout << "No such object!!" << endl;
+ // o2_unref_handle( );
+ delete mObj;
+ }
+
+}
+
+/*************************************************************
+ * Function......: testLaterInsert()
+ *
+ ************************************************************/
+
+static void testLaterInsert( OId o )
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testLaterInsert"<<endl;
+
+ try{
+ accessedObj = new PersMDDObj( O2DBName, o);
+ }
+ catch (...)
+ {
+ cout <<" Object not found..." << endl;
+ return;
+ }
+
+ cout << "Current status of MDD object : " << endl;
+ accessedObj->printStatus( );
+ cout << endl << "Inserting new Tile ..."<< endl;
+
+ PersTile *t, *t2, *t3;
+ switch( accessedObj->getDimension( ) )
+ {
+ case 2 :
+ t2 = new PersTile( r_Minterval("[40:60,80:1200]"),
+ accessedObj->getCellType( ) );
+ t = t2;
+ break;
+ case 3 :
+ t3 = new PersTile(r_Minterval("[40:60,80:100,0:20]"),
+ accessedObj->getCellType( ) );
+ t = t3;
+ break;
+ default:
+ cout << "Error Dimensionality not expected" << endl;
+ break;
+ }
+ accessedObj->insertTile(t);
+ cout << " New status after insertion:" << endl;
+ accessedObj->printStatus();
+ cout << endl << endl;
+
+ delete accessedObj;
+}
+
+
+/*************************************************************
+ * Function......: testSearch()
+ *
+ ************************************************************/
+static void testSearch()
+{
+
+ MDDObj* accessedObj;
+
+ cout << "....testSearch"<<endl;
+
+ PersMDDColl objsSet(collName);
+
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ accessedObj = objsIt->getElement();
+
+ cout << "Accessed Object " << endl;
+ accessedObj->printStatus( );
+ cout << endl;
+
+ if (i == 1 || i == 2)
+ {
+ r_Minterval searchInt1(2);
+ r_Minterval searchInt2(3);
+ vector< Tile* >* entriesList;
+
+ cout << " -- " << i << ". MDD object in list. Search for:";
+ switch (i) {
+ case 1: searchInt1[0].set_interval(10l,20l);
+ searchInt1[1].set_interval(10l,30l);
+ cout << " 10-20, 10-30" << endl;
+ entriesList = accessedObj->intersect(searchInt1);
+ break;
+ case 2: 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 = accessedObj->intersect(searchInt2);
+ break;
+ default: break;
+ }
+ cout << " -- Search result: " << endl;
+ vector<Tile*>::iterator entryIt = entriesList->begin();
+
+ 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++;
+ }
+ delete entriesList;
+ }
+ }
+ delete objsIt;
+ // objsSet.releaseAll( );
+}
+
+/*************************************************************
+ * Function......: testRemoveTile(OId o )
+ *
+ ************************************************************/
+static void testRemoveTile(OId o)
+{
+ PersMDDObj *mObj;
+
+ cout << "....testRemoveTile from MDD Obj "<< o << endl;
+
+ try{
+ mObj = new PersMDDObj( O2DBName, o);
+ mObj->printStatus( );
+ }
+ catch (...)
+ {
+ cout <<" Object not found..." << endl;
+ return;
+ }
+
+ vector<Tile*>* tiles = mObj->getTiles( );
+
+ if ( tiles->size( ) == 0 )
+ {
+ cout <<"MDD object has no tiles !! "<< endl;
+ return;
+ }
+ else
+ {
+ int ix = tiles->size( )/2;
+
+ cout << "Removing "<< ix <<". tile from MDD Obj "<< endl;
+ cout << "Tile Description: " << (*tiles)[ix]->getDomain( ) << endl;
+
+ PersTile* t = (PersTile*) (*tiles)[ix];
+
+ mObj->removeTile( (*tiles)[ix] );
+
+ delete tiles;
+ delete mObj;
+ }
+}
+
+/*************************************************************
+ * Function......: testGetCardinality( const char* cn )
+ * testGetFunctions()
+ *
+ ************************************************************/
+static void testGetCardinality( char* cn )
+{
+ cout << "....testGetCardinality( "<< cn << " )" << endl;
+
+ try{
+ PersMDDColl objsSet( cn );
+ cout<< "Cardinality of collection " << objsSet.getCardinality( ) <<endl;
+ }
+ catch( r_Error& errObj)
+ {
+ cout <<"Error caught ................."<< endl;
+ }
+}
+
+static void testGetFunctions()
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testGetFunctions"<<endl;
+
+ PersMDDColl objsSet(collName);
+
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ vector< Tile* >* entriesList;
+
+ for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
+ {
+ r_Minterval currDom;
+ r_Minterval defDom;
+
+ cout << " " << i << ". Object" << endl;
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+
+
+ defDom = accessedObj->getDefinitionDomain( );
+ cout << " GetDefinitionDomain result: ";
+ defDom.print_status( );
+ cout << endl;
+
+ currDom = accessedObj->getCurrentDomain( );
+ cout << " GetCurrentDomain result: ";
+ currDom.print_status( );
+ cout << endl;
+
+ entriesList = accessedObj->getTiles( );
+ cout << " -- GetTiles result: " << endl;
+ vector<Tile*>::iterator entryIt = entriesList->begin();
+
+ while (entryIt != entriesList->end())
+ {
+ // (*entryIt)->printStatus();
+ r_Minterval tileInterval = (*entryIt)->getDomain();
+ int dimensionality = tileInterval.dimension();
+
+ cout << " PersTile ";
+ cout << " domain == " << dimensionality << ": ";
+ for (int i = 0; i <dimensionality; i++)
+ cout << tileInterval[i].low() << "-" << tileInterval[i].high() <<", ";
+ cout << endl;
+ entryIt++;
+ }
+ delete entriesList;
+ }
+ delete objsIt;
+ objsSet.releaseAll( );
+}
+
+/*************************************************************
+ * Function......: testRemove()
+ * testRemove( OId o )
+ *
+ ************************************************************/
+
+static void testRemove()
+{
+ PersMDDObj* accessedObj;
+
+ cout << "....testRemove"<<endl;
+
+ PersMDDColl objsSet(collName);
+ // PersMDDColl objsSet("Qualquercoisa");
+ // To test PersMDDColl::printStatus and PersMDDColl::remove
+
+
+ MDDCollIter* objsIt = objsSet.createIterator( );
+
+ cout << "-- Remove second element from collection " << endl;
+
+ for( int i = 1 ; objsIt->notDone( ) && i < 2; i++, objsIt->advance( ))
+ {
+ accessedObj = (PersMDDObj*) objsIt->getElement();
+ }
+ cout << "Delete of objsIt:" << endl;
+ delete objsIt;
+ cout << "Finished Delete of objsIt." << endl;
+ cout << "Remove accessedObj:" << endl;
+ objsSet.remove( accessedObj );
+ cout << "Finished Remove accessedObj." << endl;
+}
+
+static void testRemove( OId o )
+{
+
+ cout << "....testRemove( OId == " << o <<" ) "<< endl;
+
+ PersMDDColl objsSet(collName);
+ objsSet.remove( o, O2DBName );
+}
+
+
+/*************************************************************
+ * Function......: createMDDColl( )
+ ************************************************************/
+static int
+createMDDColl( const char* collName, DatabaseIf* db )
+{
+ MDDDomainType* mType1 = 0;
+ MDDDomainType* mType2 = 0;
+ MDDType* mt = 0;
+ CollectionType* collType1 = 0;
+
+ const BaseType* ulongTypeObj = TypeFactory::mapType("ULong");
+
+ const MDDDomainType* cmType1 =
+ ( MDDDomainType* ) TypeFactory::mapMDDType( "TestSMDomainType2D" );
+ const MDDDomainType* cmType2 =
+ ( MDDDomainType* ) TypeFactory::mapMDDType( "TestSMDomainType3D" );
+
+ const CollectionType* collType =
+ (CollectionType*)TypeFactory::mapSetType( "ObjsContainerType" );
+
+
+ if( !cmType1 || !cmType2 || !collType )
+ {
+ char name1[] = "TestSMDomainType2D";
+ char name2[] = "TestSMDomainType3D";
+
+ r_Sinterval limits1Obj1(0l,1000l);
+ r_Sinterval limits2Obj1(0l,800l);
+ r_Minterval dom1(2);
+ dom1 << limits1Obj1 << limits2Obj1;
+ cout << "MDD Type 1 , domain "<< dom1 << 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;
+ cout << "MDD Type 2 , domain "<< dom2 << endl;
+
+ // MDDDomainType* mType1 =
+ mType1 =
+ new MDDDomainType((char*) name1, ( BaseType* ) ulongTypeObj, dom1 );
+ // MDDDomainType* mType2 =
+ mType2 =
+ new MDDDomainType((char*) name2, ( BaseType* ) ulongTypeObj, dom2 );
+
+ cout << "MDD Type1 == ";
+ mType1->print_status( cout );
+ cout << endl;
+ cout << "MDD Type2 == ";
+ mType2->print_status( cout );
+ cout << endl;
+
+ TypeFactory::addMDDType( mType1 );
+ TypeFactory::addMDDType( mType2 );
+
+ if ( !collType )
+ {
+ cout << "Collection type newly created " << endl;
+ // MDDType* mt = new MDDType( );
+ mt = new MDDType( );
+ cout << "MDDtype created "<< endl;
+ collType1 = new SetType( "ObjsContainerType", mType1 );
+ cout << "Set Type created ... ";
+ collType = collType1;
+ TypeFactory::addSetType( (SetType*) collType );
+ cout <<" and added "<< endl;
+
+ }
+
+ }
+ //ta.commit( );
+
+ //ta.begin( );
+
+ cout << "Creating root collection" << endl;
+
+ // cout << " &database = " << long( db ) << endl;
+
+ OId oColl;
+ if( OId::allocateMDDCollOId( &oColl ) == 0 )
+ cout <<"Successfully allocated OId for collection " << oColl << endl;
+ else
+ cout <<"Error allocating OId for collection " << endl;
+ globalCollOId = oColl;
+
+ PersMDDColl* col;
+ try {
+ // CollectionType* ct = TypeFactory::mapSetType( "ObjsContainerType" );
+ col = PersMDDColl::createRoot( collName, oColl, collType, db );
+ }
+ catch (...)
+ {
+ cout <<"Error caught ................."<< endl;
+ return -1;
+ }
+
+ cout << "Committing TA ..."<< endl;
+ ta.commit( );
+
+ /*
+
+ cout <<"Freeing types ... "<< endl;
+
+ // if ( mType1 ) delete mType1;
+ cout << "Type 1 freed . "<< endl;
+ // if ( mType2 ) delete mType2;
+ cout << "Type 2 freed . "<< endl;
+ // if ( mt ) delete mt;
+ cout << "Type mt freed . "<< endl;
+ // if ( collType1 ) delete collType1;
+ cout << "Types collType1 freed . "<< endl;
+ */
+ if ( col ) delete col;
+ cout << "Col freed . "<< endl;
+
+
+ ta.begin( db );
+ return 0;
+}
diff --git a/mddmgr/test/test_transmddcoll.cc b/mddmgr/test/test_transmddcoll.cc
new file mode 100644
index 0000000..b3045c3
--- /dev/null
+++ b/mddmgr/test/test_transmddcoll.cc
@@ -0,0 +1,180 @@
+/*
+* 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_transmddcoll.cc
+ *
+ * MODULE: test for transmddobj of cachetamgr
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+
+#include <stdlib.h>
+#include <iostream>
+#include <vector.h> // STL
+#include "tilemgr/transtile.hh"
+#include "tilemgr/transmddobj.hh"
+#include "ulongtype.hh" // from catalogif
+#include "raslib/minterval.hh"
+#include "tilemgr/transmddcoll.hh"
+#include "tilemgr/mddcolliter.hh"
+#include "adminif.hh"
+
+// Needed by Adminif. Adminif has to be instantiated because
+// of cell base types.
+extern char* myExecArgv0 = "";
+#include "raslib/rminit.hh"
+RMINITGLOBALS('C')
+
+
+/*************************************************************
+ * 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...:
+ * The cellType of the MDD objects in this program is
+ * not set correctly because no database is open and no
+ * transaction is started.
+ ************************************************************/
+
+int
+main( int argc, char** argv)
+{
+ myExecArgv0 = argv[0];
+
+ const int numObjs = 10;
+ const int numTilesObj = 10;
+ r_Sinterval domSinterval;
+
+ // In order to work with cell base types, AdminIf has to be
+ // instantiated.
+ // cout << " Adminif::instance " << endl;
+ AdminIf* myAdmin = AdminIf::instance();
+
+ ULongType anyType;
+
+ char anyCell[4];
+ int i;
+ MDDColl* tCollMDDObjs = new TransMDDColl( );
+
+ cout << " Allocating new TransMDDColl ..."<<endl;
+ tCollMDDObjs = new TransMDDColl( );
+ cout << " new TransMDDColl allocated..."<<endl;
+
+ cout << "Creating transient tiles for the MDD objects ... " << endl;
+ vector<TransTile*>* tilesVectsArr[numObjs];
+
+ // initialize array of vectors of tiles
+ for (i=0; i<numObjs; i++)
+ {
+ tilesVectsArr[i] = new vector<TransTile*>(numTilesObj);
+ for (int j=0; j<numTilesObj ; j++)
+ {
+ r_Minterval dom(2);
+ domSinterval.set_interval( r_Range(j* 10), r_Range((j+1)*10-1) );
+ dom << domSinterval << domSinterval;
+ (*tilesVectsArr[i])[j] = new TransTile( dom, &anyType, anyCell );
+ }
+ }
+
+
+ cout << "Creating transient MDD objects ... " << endl;
+ TransMDDObj* MDDObjsArr[numObjs];
+
+ for ( i=0; i<numObjs; i++ )
+ {
+ r_Minterval dom(2);
+ domSinterval.set_interval( r_Range( i ), r_Range( 100 + i*10 ) );
+ if( i == 3 || i == 5 || i == 7 )
+ domSinterval.set_low( '*' );
+ if( i == 2 || i == 4 || i == 6 )
+ domSinterval.set_high( '*' );
+ dom << domSinterval << domSinterval;
+ MDDObjsArr[i] = new TransMDDObj( dom, "ULong" );
+ for( int j=0; j < numTilesObj; j++)
+ {
+ vector<TransTile*>* pTilesVec = tilesVectsArr[i];
+ MDDObjsArr[i]->insertTile( (*pTilesVec)[j] );
+ }
+ }
+
+ cout << "Printing contents of created objects ... " << endl;
+ for( i = 0; i< numObjs; i++)
+ {
+ cout << "- " << i << ". Transient MDD Object contents: " <<endl;
+ MDDObjsArr[i]->printStatus( );
+ cout << endl;
+ }
+
+ cout << "Creating a transient collection of objects ... " << endl;
+ for( i = 0; i< numObjs; i++)
+ {
+ // cout << "- " << i << ". Transient MDD Object contents: " <<endl;
+ tCollMDDObjs->insert(MDDObjsArr[i]);
+ // cout << endl;
+ }
+ cout << "Contents of the Transient Collection: ... : " << endl;
+ tCollMDDObjs->printStatus( );
+
+ cout << "Testing TransMDDCollIter ... : " << endl;
+ MDDCollIter* transIter = tCollMDDObjs->createIterator( );
+ MDDObj* currObj;
+
+ for ( i=0; transIter->notDone( ) ; transIter->advance( ), i++)
+ {
+ cout << "- " << i << ". Trans. MDD Object returned by Iterator contents: " <<endl;
+ currObj = transIter->getElement( );
+ currObj->printStatus( );
+ }
+
+ // delete iterator from TransMDDColl
+ delete transIter;
+
+ // releases all contents from the collection. It should free all the MDD
+ // objects and tiles created in this program.
+ tCollMDDObjs->releaseAll( );
+
+ // delete transient MDD Collection
+ delete tCollMDDObjs;
+
+ /*
+ This shouldn't be needed if realeaseAll from the TransMDDColl works fine
+ for ( i = 0 ; i < numObjs; i++ )
+ {
+ delete MDDObjsArr[i];
+ }
+ */
+
+
+ // delete dynamically allocated vectors of tiles (not the tiles themselves,
+ // which should have been freed by releaseAll of TransMDDColl)
+ for (i = 0; i < numObjs; i++)
+ delete tilesVectsArr[i];
+
+ delete myAdmin;
+
+}
diff --git a/mddmgr/test/test_transmddobj.cc b/mddmgr/test/test_transmddobj.cc
new file mode 100644
index 0000000..28c50d2
--- /dev/null
+++ b/mddmgr/test/test_transmddobj.cc
@@ -0,0 +1,443 @@
+/*
+* 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_transmddcoll.cc
+ *
+ * MODULE: test for transmddobj of cachetamgr
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+
+#include "rt_odb_Database.hxx"
+
+#define TEST_PRIVATE
+
+#include <stdlib.h>
+#include <iostream>
+#include <vector.h> // STL
+#include "mddmgr/transtile.hh"
+#include "mddmgr/transmddobj.hh"
+
+#include "typefactory.hh"
+#include "ulongtype.hh" // from catalogif
+#include "mddbasetype.hh" // from catalogif
+
+#include "raslib/minterval.hh"
+#include "mddmgr/transmddcoll.hh"
+#include "mddmgr/mddcolliter.hh"
+#include "adminif.hh"
+#include "databaseif.hh"
+#include "transactionif.hh"
+
+#include "raslib/rminit.hh"
+RMINITGLOBALS('C')
+
+#include <malloc.h>
+
+// Needed by Adminif. Adminif has to be instantiated because
+// of cell base types.
+extern char* myExecArgv0 = "";
+
+void testConstruction( );
+void testRemovetile( );
+void testIntersection( );
+void printMemInfo( );
+
+
+/*************************************************************
+ * 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)
+{
+ myExecArgv0 = argv[0];
+ AdminIf* myAdmin = AdminIf::instance();
+ TransactionIf ta;
+ char O2DBName[] = "BaseTestTransMDDObj";
+
+ // variables representing O2 database, ta and session
+ DatabaseIf database;
+ // connect to the database
+ cout << "Connecting to database " << O2DBName
+ << "..." << endl;
+ int errorDBOpen;
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch( ...)
+ {
+ cout << "Caught Exception " << endl;
+ errorDBOpen = -6;
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Database doesn't exist. Create it new ... " << endl;
+ cout << "Creating new database " << O2DBName
+ << "..." << endl;
+ database.create( O2DBName, "TestSMSchema" );
+ cout << "Connecting to database " << O2DBName
+ << "..." << endl;
+ try{
+ errorDBOpen = database.open( O2DBName );
+ }
+ catch(...)
+ {
+ errorDBOpen = -6;
+ }
+ }
+ if ( errorDBOpen < 0 )
+ {
+ cout << "Failed at opening newly created database " << errorDBOpen << endl;
+ cout << "Exiting " << endl;
+ return errorDBOpen;
+ }
+
+ ta.begin( &database, 1 );
+
+ cout << " Main - begin " << endl;
+ printMemInfo( );
+
+ /*
+ cout << "---------- ";
+ cout << "Testing constructor and insertTile for TransMDDObj: " << endl;
+ testConstruction( );
+ cout << "Testing constructor - end " << endl;
+ printMemInfo( );
+ */
+
+ cout << "Testing intersection for TransMDDObj: " << endl;
+ testIntersection( );
+ cout << "Testing intersection - end " << endl;
+ printMemInfo( );
+
+
+ /*
+ cout << "---------- ";
+ cout << "Testing removeTile from TransMDDObj: " << endl;
+ testRemovetile( );
+ cout << "Main - end " << endl;
+ printMemInfo( );
+ */
+
+ ta.abort( );
+ database.close( );
+
+ delete myAdmin;
+
+}
+
+void testConstruction( )
+{
+ const int numTilesObj = 20;
+ r_Sinterval domSinterval;
+ cout <<"here 1" << endl;
+ ULongType ult;
+ BaseType* anyType = new( (d_Database*)(d_Database::transient_memory) ) ULongType; // anyType;
+
+ cout << "here 2"<< endl;
+ const MDDBaseType* anyBaseType =
+ new( (d_Database*)(d_Database::transient_memory) ) MDDBaseType( "AnyType", &ult/* anyType */ );
+
+ // const MDDBaseType anyBaseType( "AnyType", &ult );
+
+ char anyCell[4];
+ int j;
+ MDDObj* testMDDObj;
+
+
+ cout << "Creating transient tiles for the MDD object ... " << endl;
+ vector<TransTile*> tilesVect(numTilesObj);
+
+
+ // initialize array of tiles
+ for (j=0; j<numTilesObj ; j++)
+ {
+ r_Minterval dom(2);
+ TransTile* tt;
+
+ domSinterval.set_interval( r_Range(j* 10), r_Range((j+1)*10-1) );
+ dom << domSinterval << domSinterval;
+ cout << "Newly created tile domain : " << dom << " " << endl;
+ // printMemInfo();
+ tt = new TransTile( dom, anyType, anyCell );
+ cout << "Tile created " << endl;
+ // printMemInfo();
+ tilesVect[j] = tt ;
+ }
+
+ // Test trans tiles part - BEGIN
+ // works fine
+ /*
+ for ( int h=0; h < tilesVect.size(); h++)
+ delete tilesVect[h];
+ */
+ // release (tilesVect.begin( ), tilesVect.end( ) );
+
+ // Test trans tiles part - END
+
+
+ cout << "Creating the transient MDD object ... " << endl;
+
+ r_Minterval dom(2);
+ domSinterval.set_interval( r_Range( 0 ), r_Range( 100 ) );
+ domSinterval.set_low( '*' );
+ dom << domSinterval << domSinterval;
+ // testMDDObj = new TransMDDObj( dom, "ULong" );
+ testMDDObj = new TransMDDObj( anyBaseType, dom );
+ for(j=0; j < numTilesObj; j++)
+ {
+ testMDDObj->insertTile( tilesVect[j] );
+ }
+ // printMemInfo();
+
+ cout << "Printing contents of the created object ... " << endl;
+ testMDDObj->printStatus( );
+
+ cout << "Deleting the created object ... " << endl;
+ delete testMDDObj;
+ // printMemInfo();
+
+
+}
+
+
+void testIntersection( )
+{
+ const int numTilesObj = 20;
+ r_Sinterval domSinterval;
+
+ const BaseType* ulongTypeObj = TypeFactory::mapType("ULong");
+
+ char uLongCell[] = {0,1,2,3};
+
+ const MDDBaseType* anyBaseType =
+ new MDDBaseType( "AnyType1", (BaseType*) ulongTypeObj );
+
+ TypeFactory::addTempType( (Type*) anyBaseType );
+
+ BaseType* bt = ( (MDDBaseType* ) anyBaseType )->getBaseType( );
+ cout << "Base type size " << bt->getSize( )<< endl;
+
+
+ int j;
+ MDDObj* testMDDObj;
+
+
+ cout << "Creating transient tiles for the MDD object ... " << endl;
+ vector<TransTile*> tilesVect(numTilesObj);
+
+
+ // initialize array of tiles
+ for (j=0; j<numTilesObj ; j++)
+ {
+ r_Minterval dom(2);
+ TransTile* tt;
+
+ domSinterval.set_interval( r_Range(j* 10), r_Range((j+1)*10-1) );
+ dom << domSinterval << domSinterval;
+ cout << "Newly created tile domain : " << dom << " " << endl;
+ // printMemInfo();
+ tt = new TransTile( dom, (BaseType*) ulongTypeObj, uLongCell );
+ cout << "Tile created " << endl;
+ if (!j)
+ tt->printStatus( );
+ // printMemInfo();
+ tilesVect[j] = tt ;
+ }
+
+ // Test trans tiles part - BEGIN
+ // works fine
+ /*
+ for ( int h=0; h < tilesVect.size(); h++)
+ delete tilesVect[h];
+ */
+ // release (tilesVect.begin( ), tilesVect.end( ) );
+
+ // Test trans tiles part - END
+
+
+ cout << "Creating the transient MDD object ... " << endl;
+
+ r_Minterval dom(2);
+ domSinterval.set_interval( r_Range( 0 ), r_Range( 100 ) );
+ domSinterval.set_low( '*' );
+ dom << domSinterval << domSinterval;
+ testMDDObj = new TransMDDObj( anyBaseType, dom );
+ for(j=0; j < numTilesObj; j++)
+ {
+ testMDDObj->insertTile( tilesVect[j] );
+ }
+ // printMemInfo();
+
+ cout << "Printing contents of the created object ... " << endl;
+ testMDDObj->printStatus( );
+
+ r_Minterval searchInterval(2);
+ domSinterval.set_interval( r_Range( 4 ), r_Range( 96 ) );
+ searchInterval<< domSinterval ;
+ domSinterval.set_interval( r_Range( 22 ), r_Range( 84 ) );
+ searchInterval<< domSinterval ;
+ cout << "Intersection with "<< searchInterval << " :" << endl ;
+
+ vector<Tile*>* intersectResult =
+ ( testMDDObj )->intersect( searchInterval );
+ cout << "Result of intersection:" << endl;
+ cout << "Intersect result size " << intersectResult->size( ) << endl;
+ for (int tilesIter = 0; tilesIter < intersectResult->size( ) ; tilesIter++)
+ {
+ Tile* currTile;
+ currTile = (*intersectResult)[tilesIter];
+ cout << "Tile " << tilesIter << " domain : " ;
+ cout << currTile->getDomain( ) << endl;
+ }
+
+ // printMemInfo();
+ cout << "Deleting intersection result " << endl;
+ // Individual tiles in the intersectResult shouldn't be deleted, since
+ // they are part of the TransMDDObj. They are deleted whenever the object
+ // is deleted.
+ delete intersectResult;
+ // printMemInfo();
+
+ cout << "Testing point query " << endl;
+ r_Point pnt1( r_Range(2) , r_Range(3) );
+ unsigned long* c1 = (unsigned long*) testMDDObj->pointQuery( pnt1 );
+ // char* c1 = testMDDObj->pointQuery( pnt1 );
+ cout << "1. Result "<< pnt1 << ": "<< *c1 << endl;
+
+ r_Point pnt2( r_Range(20) , r_Range(30) );
+ unsigned long* c2 = (unsigned long*) testMDDObj->pointQuery( pnt2 );
+ // char* c2 = testMDDObj->pointQuery( pnt2 );
+ cout << "2. Result "<< pnt2 << ": "<< c2 << endl;
+
+ cout << "Deleting the created object ... " << endl;
+ delete testMDDObj;
+ printMemInfo();
+}
+
+
+void testRemovetile( )
+{
+ const int numTilesObj = 20;
+ r_Sinterval domSinterval;
+ BaseType* anyType = new( (d_Database*)(d_Database::transient_memory) ) ULongType; // ULongType anyType;
+ char anyCell[4]= {'a','b','c','\0'};
+ int j,i;
+ TransMDDObj* testMDDObj;
+ vector<Tile*>* allTilesObj;
+ vector<Tile*> tilesToDelete;
+ const MDDBaseType* anyBaseType =
+ new( (d_Database*)(d_Database::transient_memory) ) MDDBaseType( "AnyType", anyType );
+
+ cout << "Creating transient tiles for the MDD object ... " << endl;
+ vector<TransTile*> tilesVect;
+
+ // initialize array of tiles
+ for ( j=0; j<numTilesObj ; j++)
+ {
+ r_Minterval dom(2);
+ domSinterval.set_interval( r_Range(j* 10), r_Range((j+1)*10-1) );
+ dom << domSinterval << domSinterval;
+ cout << "New TransTile " << endl;
+ tilesVect.push_back( new TransTile( dom, anyType, anyCell ) );
+ // printMemInfo( );
+ }
+
+ cout << "Creating the transient MDD object ... " << endl;
+
+ r_Minterval dom(2);
+ domSinterval.set_interval( r_Range( 0 ), r_Range( 100 ) );
+ domSinterval.set_low( '*' );
+ dom << domSinterval << domSinterval;
+ testMDDObj = new TransMDDObj( anyBaseType, dom );
+ for( j=0; j < numTilesObj; j++)
+ {
+ cout << "InsertTile " << endl ;
+ testMDDObj->insertTile( ( Tile*) tilesVect[j] );
+ // printMemInfo( );
+ }
+
+ cout << "Printing contents of the created object ... " << endl;
+ testMDDObj->printStatus( );
+
+ cout << "Getting all tiles from the object... " << endl;
+ allTilesObj = testMDDObj->getTiles( );
+ // printMemInfo( );
+
+ cout << "Removing tile 2, 4, 6, and 12 from the object... " << endl;
+ for ( i = 0; i < allTilesObj->size( ); i++)
+ {
+ if ( i==2 || i == 4 || i == 6 || i == 12 )
+ {
+ tilesToDelete.push_back( (*allTilesObj)[i]);
+ }
+ }
+ for ( i = 0; i < tilesToDelete.size( ); i++)
+ {
+ cout << " Tile is going to be removed " << endl;
+ testMDDObj->removeTile(tilesToDelete[i] );
+ cout << endl << " Value of pointer to tile : " << tilesToDelete[i] << endl<< endl;
+ // printMemInfo();
+ }
+ testMDDObj->printStatus( );
+
+ cout << "Deleting the created object ... " << endl;
+ // printMemInfo( );
+ delete testMDDObj;
+ cout << "Already deleted " << endl;
+ // printMemInfo( );
+
+ delete allTilesObj;
+}
+
+
+void printMemInfo( )
+{
+
+
+ // allows to store values in the program
+ struct mallinfo meminfo = mallinfo();
+
+ cout << " Memory Usage Information : " ;
+ cout << endl;
+
+ cout << " space in arena : " << meminfo.arena << endl;
+ cout << " number of small blocks : " << meminfo.smblks << endl;
+ cout << " number of ordinary blocks : " << meminfo.ordblks << endl;
+ cout << " space in free ordinary blocks : " << meminfo.fordblks << endl;
+ cout << " space in used ordinary blocks : " << meminfo.uordblks << endl;
+
+ // cout << "additional space from last call: " << meminfo.uordblks - memUsed << endl;
+
+}
+
+