/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community. If not, see .
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see
* or contact Peter Baumann via .
*/
#include "mymalloc/mymalloc.h"
#include
#include
#include
#include
#include "adminif.hh"
#include "transactionif.hh"
#include "databaseif.hh"
#include "raslib/rmdebug.hh"
#include "indexmgr/mddstorage.hh"
#include "raslib/mddtypes.hh"
#include "oidif.hh"
#include "inlineminterval.hh"
#include "externs.h"
RMINITGLOBALS('C')
unsigned int size = 0;
r_Dimension dimension = 0;
MDDStorage::IndexType myType = 0;
int _isNode = 0;
OId myOId = (double)0;
OId parent = (double)0;
void
readFromDb()
{
RMDBGOUT(8, "(relindexif)" << "\tDBHierIndex::readFromDb() " << myOId);
EXEC SQL BEGIN DECLARE SECTION;
double id1;
double parentid1;
short indextype1;
long dimension1;
long size1;
short indexsubtype1;
short lowerfind;
struct {
short length;
char data[3990];
} dyndata1;
short dyndataind1;
EXEC SQL END DECLARE SECTION;
id1 = myOId;
EXEC SQL SELECT
IndexType,
NumEntries,
Dimension,
ParentOId,
IndexSubType
INTO
:indextype1,
:size1,
:dimension1,
:parentid1,
:indexsubtype1
FROM
RAS_HIERIX
WHERE
MDDObjIxOId = :id1;
if (SQLCODE != 0)
{
check("DBHierIndex::readFromDb() RAS_HIERIX\0");
if (SQLCODE == 100)
throw r_Error(r_Error::r_Error_ObjectUnknown);
else
throw r_Error(r_Error::r_Error_BaseDBMSFailed);
}
switch (indextype1)
{
case 0:
myType = MDDStorage::AutoIx;
break;
case 1:
myType = MDDStorage::DirTilesIx;
break;
case 2:
myType = MDDStorage::RegDirIx;
break;
case 3:
myType = MDDStorage::RPlusTreeNode;
break;
case 4:
myType = MDDStorage::RegRPlusTreeNode;
break;
default:
RMDBGOUT(0, "DBHierIndex::readFromDb() UNKNOWN INDEXTYPE " << indextype1 << "\t " << myOId << " " << myOId.getType());
break;
}
cout << "myType\t\t" << myType << endl;
size = size1;
cout << "size\t\t" << size << endl;
_isNode = indexsubtype1;
cout << "node\t\t" << _isNode << endl;
dimension = dimension1;
cout << "dimension\t\t" << dimension << endl;
if (parentid1)
parent = OId(parentid1);
else
parent = OId(0, OId::INVALID);
cout << "parent\t\t" << parent << " " << parent.getIdAsLong() << " " << parent.getType() << endl;
//number of bytes for bounds for "size" entries and mydomain
unsigned long boundssize = sizeof(r_Range) * (size + 1) * dimension;
//number of bytes for fixes for "size" entries and mydomain
unsigned long fixessize = sizeof(char) * (size + 1) * dimension;
//number of bytes for ids of entries
unsigned long idssize = sizeof(OId::Id) * size;
//number of bytes for types of entries
unsigned long typessize = sizeof(char) * size;
//number of bytes for the dynamic data
unsigned long completesize = boundssize * 2 + fixessize * 2 + idssize + typessize;
char* completebuffer = (char*)mymalloc(completesize);
r_Range* upperboundsbuf = (r_Range*)mymalloc(boundssize);
r_Range* lowerboundsbuf = (r_Range*)mymalloc(boundssize);
char* upperfixedbuf = (char*)mymalloc(fixessize);
char* lowerfixedbuf = (char*)mymalloc(fixessize);
OId::Id* entryidsbuf = (OId::Id*)mymalloc(idssize);
char* entrytypesbuf = (char*)mymalloc(typessize);
RMDBGOUT(8, "(relindexif)" << "\t\tcomplete " << completesize << " bounds " << boundssize << " fixes " << fixessize << " ids " << idssize << " types " << typessize);
//counter which keeps track of the bytes that have been read from the db
unsigned long bytesdone = 0;
//counter which keeps track of the bytes that have to be read from the db
unsigned long bytestogo = 0;
int i = 0;
currentDbRows = 0;
EXEC SQL DECLARE C CURSOR FOR
SELECT
DynData
FROM
RAS_HIERIXDYN
WHERE
MDDObjIxOId = :id1
ORDER BY
Count;
EXEC SQL OPEN C;
do {
EXEC SQL FETCH C INTO :dyndata1 :dyndataind1;
if (SQLCODE != 0)
{
if (SQLCODE != 100)
{
check("DBHierIndex::readFromDb() FETCH\0");
RMDBGOUT(7, "(relindexif)" << "\t\tSQLCODE " << SQLCODE);
free(upperboundsbuf);
free(lowerboundsbuf);
free(upperfixedbuf);
free(lowerfixedbuf);
free(entryidsbuf);
free(entrytypesbuf);
free(completebuffer);
throw r_Error(r_Error::r_Error_BaseDBMSFailed);
}
break;
}
RMDBGOUT(7, "(relindexif)" << "\t\tbytes allready read " << bytesdone << " bytes read now " << dyndata1.length);
memcpy(&completebuffer[bytesdone], dyndata1.data, dyndata1.length);
bytesdone = dyndata1.length + bytesdone;
currentDbRows = currentDbRows + 1;
}
while (1);
//all dynamic data is in completebuffer
//put that stuff in the correct buffers
memcpy(lowerboundsbuf, completebuffer, boundssize);
memcpy(upperboundsbuf, &completebuffer[boundssize], boundssize);
memcpy(lowerfixedbuf, &completebuffer[boundssize * 2], fixessize);
memcpy(upperfixedbuf, &completebuffer[boundssize * 2 + fixessize], fixessize);
memcpy(entryidsbuf, &completebuffer[boundssize * 2 + fixessize * 2], idssize);
memcpy(entrytypesbuf, &completebuffer[boundssize * 2 + fixessize * 2 + idssize], typessize);
//all dynamic data is in its buffer
free (completebuffer);
//rebuild the attributes from the buffers
myDomain = InlineMinterval(dimension, &(lowerboundsbuf[0]), &(upperboundsbuf[0]), &(lowerfixedbuf[0]), &(upperfixedbuf[i*dimension]));
cout << "myDomain\t\t" << myDomain << endl;
for (i = 0; i < size; i++)
{
domainList.push_back(InlineMinterval(dimension, &(lowerboundsbuf[(i+1)*dimension]), &(upperboundsbuf[(i+1)*dimension]), &(lowerfixedbuf[(i+1)*dimension]), &(upperfixedbuf[(i+1)*dimension])));
entryOIdList.push_back(OId(entryidsbuf[i], (OId::OIdType)entrytypesbuf[i]));
RMDBGOUT(8, "(relindexif)" << "\t\tentry " << entryidsbuf[i] << " " << (OId::OIdType)entrytypesbuf[i] << " at " << InlineMinterval(dimension, &(lowerboundsbuf[(i+1)*dimension]), &(upperboundsbuf[(i+1)*dimension]), &(lowerfixedbuf[(i+1)*dimension]), &(upperfixedbuf[(i+1)*dimension])));
}
free(upperboundsbuf);
free(lowerboundsbuf);
free(upperfixedbuf);
free(lowerfixedbuf);
free(entryidsbuf);
free(entrytypesbuf);
EXEC SQL CLOSE C;
RMDBGOUT(8, "(relindexif)" << "\t\tDBHierIndex::readFromDb() END " << myOId);
}
int
main(int argc, char** argv)
{
AdminIf* myAdmin = AdminIf::instance();
DatabaseIf database;
TransactionIf ta;
if (!myAdmin)
{
cout << "Error at connecting " << endl;
cout << "Goodbye "<< endl;
exit (-1);
}
if (!database.open("RASBASE"))
{
cout << "could not open database" << endl;
}
if (argc == 2)
{
myOId = (double)a2l(argv[1]);
cout << "myOId " << myOId << endl;
readFromDb();
}
}