///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoObjectManager.cc
// --------------------
// Cego database object manager implementation
//     
// Design and Implementation by Bjoern Lemke               
//     
// (C)opyright 2000-2010 Bjoern Lemke
//
// This program 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 2, or (at your option)
// any later version.
// 
// This program 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 this program; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// IMPLEMENTATION MODULE
//
// Class: CegoObjectManager
// 
// Description: Cego database object manager
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

// base includes
#include <lfc/Exception.h>

// cego includes
#include "CegoObjectManager.h"
#include "CegoBTreeManager.h"
#include "CegoXMLdef.h"
#include "CegoBTreeNode.h"

#include <string.h>
#include <stdlib.h>

CegoObjectManager::CegoObjectManager(CegoDatabaseManager* pDBMng)
{
    _pDBMng = pDBMng;
    _pLockHandle = new CegoLockHandler(pDBMng);    
    _modId = _pDBMng->getModId("CegoObjectManager");
}

CegoObjectManager::~CegoObjectManager()
{
    delete _pLockHandle;
}

CegoDatabaseManager* CegoObjectManager::getDBMng()
{
    return _pDBMng;
}

CegoLockHandler* CegoObjectManager::getLockHandler()
{
    return _pLockHandle;
}

void CegoObjectManager::createTableObject(CegoTableObject& tableObject)
{

    unsigned long lockId = 0;
    CegoBufferPage bp;
    
    try
    {
    
	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	if ( tableObject.getType() == CegoObject::SYSTEM )
	{
	    lockMode = CegoBufferPool::PERSISTENT;
	}
	
	if ( objectExists(tableObject.getTabSetId(), tableObject.getName(), tableObject.getType()) )
	{
	    Chain msg = Chain("Object ") +  tableObject.getName() + Chain(" exists");
	    throw Exception(EXLOC, msg);
	}
	
	int fileId;
	int pageId;
	
	if ( tableObject.getType() == CegoObject::RBSEG )
	{
	    Chain tableSet = _pDBMng->getTabSetName(tableObject.getTabSetId());
	    fileId = _pDBMng->getTmpFid(tableSet);
	}
	else
	{
	    fileId = tableObject.getTabSetId();
	}
	
	pageId = tableObject.getTabName().getHashPos(TABMNG_HASHSIZE);
	
	bool created = false;
		
	_pDBMng->bufferFix(bp, tableObject.getTabSetId(), fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
	
	while ( ! created )
	{
	    char *buf;
	    
	    lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
	    
	    buf = (char*)bp.newEntry(tableObject.getEntrySize());
	    
	    if ( buf )
	    {
		_pLockHandle->unlockSysPage(lockId); 
		lockId = 0;
		
		CegoBufferPage tupPage;
		getNewFilePage(tupPage, tableObject.getTabSetId(), tableObject.getType());   
		
		tupPage.setType(CegoBufferPage::TUPLE);
		
		int dataFileId = tupPage.getFileId();
		int dataPageId = tupPage.getPageId();
		
		_pDBMng->bufferUnfix(tupPage, true, _pLockHandle);
		
		tableObject.setDataFileId(dataFileId);
		tableObject.setDataPageId(dataPageId);
		tableObject.setLastDataFileId(dataFileId);
		tableObject.setLastDataPageId(dataPageId);
		
		tableObject.encode(buf);
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		created = true;
		
	    }
	    else
	    {
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		CegoBufferPage nbp;
		
		if (fileId == 0 && pageId == 0)
		{	 	 
		    getNewFilePage(nbp, tableObject.getTabSetId(), CegoObject::SYSTEM);
		}
		else
		{			
		    _pDBMng->bufferFix(nbp, tableObject.getTabSetId(), fileId, pageId, lockMode, _pLockHandle);
		}

		bp.setNextFileId(nbp.getFileId());
		bp.setNextPageId(nbp.getPageId());
		
		_pLockHandle->unlockSysPage(lockId);	    
		lockId = 0;
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		bp = nbp;
	    }
	}
    }
    catch ( Exception e)
    {
	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }
}

void CegoObjectManager::createBTreeObject(CegoBTreeObject& btreeObject)
{

    unsigned long lockId = 0;
    CegoBufferPage bp;
    
    try
    {
    
	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
		
	if ( objectExists(btreeObject.getTabSetId(), btreeObject.getName(), btreeObject.getType()) )
	{
	    Chain msg = Chain("BTree ") +  btreeObject.getName() + Chain(" exists");
	    throw Exception(EXLOC, msg);
	}
	
	int fileId;
	int pageId;
	
	
	fileId = btreeObject.getTabSetId();	
	pageId = btreeObject.getTabName().getHashPos(TABMNG_HASHSIZE);
	
	bool created = false;
		
	_pDBMng->bufferFix(bp, btreeObject.getTabSetId(), fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
	
	while ( ! created )
	{
	    char *buf;
	    
	    lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
	    
	    buf = (char*)bp.newEntry(btreeObject.getEntrySize());
	    
	    if ( buf )
	    {
		_pLockHandle->unlockSysPage(lockId); 
		lockId = 0;
		
		CegoBufferPage rootPage;
		getNewFilePage(rootPage, btreeObject.getTabSetId(), btreeObject.getType());   
		
		rootPage.setType(CegoBufferPage::BTREE_LEAF);
		CegoBTreeNode rootNode;
		rootNode.setType(CegoBTreeNode::LEAF);
		rootNode.setPtr(rootPage.getChunkEntry(), rootPage.getChunkLen());
		rootNode.initNode();
		
		int dataFileId = rootPage.getFileId();
		int dataPageId = rootPage.getPageId();
		
		_pDBMng->bufferUnfix(rootPage, true, _pLockHandle);
		
		btreeObject.setDataFileId(dataFileId);
		btreeObject.setDataPageId(dataPageId);
		
		btreeObject.encode(buf);
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		created = true;
		
	    }
	    else
	    {
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		CegoBufferPage nbp;
		
		if (fileId == 0 && pageId == 0)
		{	 	 
		    getNewFilePage(nbp, btreeObject.getTabSetId(), CegoObject::SYSTEM);
		}
		else
		{			
		    _pDBMng->bufferFix(nbp, btreeObject.getTabSetId(), fileId, pageId, lockMode, _pLockHandle);
		}

		bp.setNextFileId(nbp.getFileId());
		bp.setNextPageId(nbp.getPageId());
		
		_pLockHandle->unlockSysPage(lockId);	    
		lockId = 0;
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		bp = nbp;
	    }
	}
    }
    catch ( Exception e)
    {
	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }
}


void CegoObjectManager::createKeyObject(CegoKeyObject& keyObject)
{    
    unsigned long lockId = 0;
    CegoBufferPage bp;

    try
    {    
	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	if ( objectExists(keyObject.getTabSetId(), keyObject.getName(), keyObject.getType()) )
	{
	    Chain msg = Chain("Object ") +  keyObject.getName() + Chain(" exists");
	    throw Exception(EXLOC, msg);
	}
	
	int fileId = keyObject.getTabSetId();
	int pageId = keyObject.getTabName().getHashPos(TABMNG_HASHSIZE);
	
	bool created = false;
	
	_pDBMng->bufferFix(bp, keyObject.getTabSetId(), fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
	
	while ( ! created )
	{
	    char *buf;
	    
	    lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
	    
	    buf = (char*)bp.newEntry(keyObject.getEntrySize());
	    
	    if ( buf )
	    {
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		keyObject.encode(buf);
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		created = true;		
	    }
	    else
	    {
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		CegoBufferPage nbp;
		
		if (fileId == 0 && pageId == 0)
		{	 	 
		    getNewFilePage(nbp, keyObject.getTabSetId(), CegoObject::SYSTEM);
		}
		else
		{			
		    _pDBMng->bufferFix(nbp, keyObject.getTabSetId(), fileId, pageId, lockMode, _pLockHandle);
		}
		
		bp.setNextFileId(nbp.getFileId());
		bp.setNextPageId(nbp.getPageId());
		
		_pLockHandle->unlockSysPage(lockId);	    
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		bp = nbp;
	    }
	}
    }
    catch ( Exception e)
    {

	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }
}

void CegoObjectManager::createCheckObject(CegoCheckObject& checkObject)
{    
    unsigned long lockId = 0;
    CegoBufferPage bp;

    try
    {
	
	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	if ( objectExists(checkObject.getTabSetId(), checkObject.getName(), checkObject.getType()) )
	{
	    Chain msg = Chain("Object ") +  checkObject.getName() + Chain(" exists");
	    throw Exception(EXLOC, msg);
	}
	
	int fileId = checkObject.getTabSetId();
	int pageId = checkObject.getTabName().getHashPos(TABMNG_HASHSIZE);
	
	bool created = false;
	
	_pDBMng->bufferFix(bp, checkObject.getTabSetId(), fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
	
	while ( ! created )
	{
	    char *buf;
	    
	    lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);

	    buf = (char*)bp.newEntry(checkObject.getEntrySize());
	    
	    if ( buf )
	    {
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		checkObject.encode(buf);
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		created = true;		
	    }
	    else
	    {
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		CegoBufferPage nbp;
		
		if (fileId == 0 && pageId == 0)
		{	 	 
		    getNewFilePage(nbp, checkObject.getTabSetId(), CegoObject::SYSTEM);
		}
		else
		{			
		    _pDBMng->bufferFix(nbp, checkObject.getTabSetId(), fileId, pageId, lockMode, _pLockHandle);
		}
		
		bp.setNextFileId(nbp.getFileId());
		bp.setNextPageId(nbp.getPageId());
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		bp = nbp;
	    }
	}
    }
    catch ( Exception e)
    {
	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }
}


void CegoObjectManager::createViewObject(CegoViewObject& viewObject)
{    
    unsigned long lockId = 0;
    CegoBufferPage bp;

    try
    {

	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	if ( objectExists(viewObject.getTabSetId(), viewObject.getName(), viewObject.getType()) )
	{
	    Chain msg = Chain("Object ") +  viewObject.getName() + Chain(" exists");
	    throw Exception(EXLOC, msg);
	}
	
	int fileId = viewObject.getTabSetId();
	int pageId = viewObject.getName().getHashPos(TABMNG_HASHSIZE);
	
	bool created = false;

	_pDBMng->bufferFix(bp, viewObject.getTabSetId(), fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
	
	while ( ! created )
	{
	    char *buf;

	    lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
	    
	    buf = (char*)bp.newEntry(viewObject.getEntrySize());
	    
	    if ( buf )
	    {		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		viewObject.encode(buf);		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);		
		created = true;		
	    }
	    else
	    {
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		CegoBufferPage nbp;
		

		if (fileId == 0 && pageId == 0)
		{	 	 
		    getNewFilePage(nbp, viewObject.getTabSetId(), CegoObject::SYSTEM);
		}
		else
		{
		    _pDBMng->bufferFix(nbp, viewObject.getTabSetId(), fileId, pageId, lockMode, _pLockHandle);
		}
		
		bp.setNextFileId(nbp.getFileId());
		bp.setNextPageId(nbp.getPageId());
	       
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		bp = nbp;
	    }
	}	
    }
    catch ( Exception e)
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }

}

void CegoObjectManager::createProcObject(CegoProcObject& procObject)
{
    unsigned long lockId = 0;
    CegoBufferPage bp;

    try
    {

	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	if ( objectExists(procObject.getTabSetId(), procObject.getName(), procObject.getType()) )
	{
	    Chain msg = Chain("Object ") +  procObject.getName() + Chain(" exists");
	    throw Exception(EXLOC, msg);
	}
	
	int fileId = procObject.getTabSetId();
	int pageId = procObject.getName().getHashPos(TABMNG_HASHSIZE);
	
	bool created = false;
	
	_pDBMng->bufferFix(bp, procObject.getTabSetId(), fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
	
	while ( ! created )
	{
	    char *buf;
	    
	    lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
	
	    buf = (char*)bp.newEntry(procObject.getEntrySize());
	    	    
	    if ( buf )
	    {	       
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		procObject.encode(buf);		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		created = true;		
	    }
	    else
	    {
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		CegoBufferPage nbp;
		
		if (fileId == 0 && pageId == 0)
		{	 	 
		    getNewFilePage(nbp, procObject.getTabSetId(), CegoObject::SYSTEM);
		}
		else
		{
		    _pDBMng->bufferFix(nbp, procObject.getTabSetId(), fileId, pageId, lockMode, _pLockHandle);
		}
	    
		bp.setNextFileId(nbp.getFileId());
		bp.setNextPageId(nbp.getPageId());
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		bp = nbp;
	    }
	}
    }
    catch ( Exception e)
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }
}

void CegoObjectManager::truncateObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type)
{
    unsigned long lockId = 0;
    CegoBufferPage bp;
	    
    try
    {
    
	int lowPage;
	int highPage; 
	
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX 
	     || type == CegoObject::FKEY
	     || type == CegoObject::CHECK )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = objName.getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage++)
	{ 
	    
	    int pageId = hashPage;
	    
	    int fileId;
	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {
		fileId = tabSetId;
	    }
	    	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
	    	    
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    
		    int size;
		    obj.decodeBase(pE, size);   
		    
		    bool typeMatch =  ( type == CegoObject::INDEX
					&& ( obj.getType() == CegoObject::INDEX
					     || obj.getType() == CegoObject::PINDEX
					     || obj.getType() == CegoObject::UINDEX ));
		    if ( ! typeMatch )
			typeMatch = obj.getType() == type;
		    
		    if ( typeMatch && objName == obj.getName() && tabSetId == obj.getTabSetId() )
		    {
			switch ( type ) 
			{
			case CegoObject::FKEY:
			case CegoObject::CHECK:
			case CegoObject::VIEW:
			case CegoObject::PROCEDURE:
			{

			    /* nothing to do */
			    _pLockHandle->unlockSysPage(lockId);	    
			    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
			    return;
			    
			}
			case CegoObject::TABLE:
			case CegoObject::SYSTEM:
			case CegoObject::RBSEG:
			case CegoObject::INDEX:
			case CegoObject::PINDEX:
			case CegoObject::UINDEX:
			{
			    CegoTableObject to;			
			    to.decode(pE);
			  
			    fileId = to.getDataFileId();
			    pageId = to.getDataPageId();
			    
			    CegoBufferPage tupPage;
			    getNewFilePage(tupPage, tabSetId, type);   
			    
			    tupPage.setType(CegoBufferPage::TUPLE);
			    
			    int dataFileId = tupPage.getFileId();
			    int dataPageId = tupPage.getPageId();
			    
			    _pDBMng->bufferUnfix(tupPage, true, _pLockHandle);
			    
			    to.setDataFileId(dataFileId);
			    to.setDataPageId(dataPageId);
			    to.setLastDataFileId(dataFileId);
			    to.setLastDataPageId(dataPageId);
			    to.encode(pE);
					    
			    _pLockHandle->unlockSysPage(lockId);
			    lockId = 0;

			    freeObjectPages(tabSetId, fileId, pageId);
			    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
			    
			    return;		       
			}
			default:
			    break;
			}
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}
	    }	
	}    
	Chain msg = Chain("Object ") +  objName + Chain(" not found");
	throw Exception(EXLOC, msg);
	
    }
    catch ( Exception e)
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }
}

void CegoObjectManager::removeObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type)
{
    unsigned long lockId = 0;
    CegoBufferPage bp;
	    
    try
    {
    
	int lowPage;
	int highPage; 
	
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX 
	     || type == CegoObject::BTREE 
	     || type == CegoObject::PBTREE 
	     || type == CegoObject::UBTREE 
	     || type == CegoObject::FKEY
	     || type == CegoObject::CHECK )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = objName.getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage++)
	{ 
	    
	    int pageId = hashPage;
	    
	    int fileId;
	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {
		fileId = tabSetId;
	    }
	    	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
	    	    
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    
		    int size;
		    obj.decodeBase(pE, size);   

		    bool typeMatch =  
			( type == CegoObject::INDEX && ( obj.getType() == CegoObject::INDEX
							 || obj.getType() == CegoObject::PINDEX
							 || obj.getType() == CegoObject::UINDEX )) ||
			( type == CegoObject::BTREE && ( obj.getType() == CegoObject::BTREE
							 || obj.getType() == CegoObject::PBTREE
							 || obj.getType() == CegoObject::UBTREE ));
		    
		    if ( ! typeMatch )		   
			typeMatch = obj.getType() == type;
		    
		    if ( typeMatch && objName == obj.getName() && tabSetId == obj.getTabSetId() )
		    {
			switch ( type ) 
			{
			case CegoObject::FKEY:
			case CegoObject::CHECK:
			case CegoObject::VIEW:
			case CegoObject::PROCEDURE:
			{
			    bp.freeEntry(pE);
			    _pLockHandle->unlockSysPage(lockId);
			    
			    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
			    return;
			    
			}
			case CegoObject::BTREE:
			case CegoObject::PBTREE:
			case CegoObject::UBTREE:
			{
			    CegoBTreeObject btoe;			
			    btoe.decode(pE);

			    CegoBTreeManager btreeMng(this, &btoe);
			    btreeMng.freeBTree();
			    
			    bp.freeEntry(pE);

			    _pLockHandle->unlockSysPage(lockId);
			    lockId = 0;

			    _pDBMng->bufferUnfix(bp, true, _pLockHandle);			    			   
			    
			    return;
			}
			case CegoObject::TABLE:
			case CegoObject::SYSTEM:
			case CegoObject::RBSEG:
			case CegoObject::INDEX:
			case CegoObject::PINDEX:
			case CegoObject::UINDEX:
			{
			    CegoTableObject to;			
			    to.decode(pE);
			    
			    bp.freeEntry(pE);	       			
			    
			    fileId = to.getDataFileId();
			    pageId = to.getDataPageId();	       			
			    
			    _pLockHandle->unlockSysPage(lockId);
			    lockId = 0;

			    freeObjectPages(tabSetId, fileId, pageId);
			    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
			    
			    return;		       
			}
			default:
			    break;
			}
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}
	    }	
	}    
	Chain msg = Chain("Object ") +  objName + Chain(" not found");
	throw Exception(EXLOC, msg);
	
    }
    catch ( Exception e)
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }
}

void CegoObjectManager::reorgObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type)
{
    unsigned long lockId = 0;
    CegoBufferPage bp;
		
    try
    {

	int lowPage;
	int highPage; 
	
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = objName.getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
       	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage++)
	{ 
	    
	    int pageId = hashPage;
	    
	    int fileId;
	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {
		fileId = tabSetId;
	    }
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
		
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    
		    int size;
		    obj.decodeBase(pE, size);   
		    
		    bool typeMatch = ( type == CegoObject::INDEX
				       && ( obj.getType() == CegoObject::INDEX
					    || obj.getType() == CegoObject::PINDEX
					    || obj.getType() == CegoObject::UINDEX ));
		    if ( ! typeMatch )
			typeMatch = obj.getType() == type;
		    
		    if ( typeMatch && objName == obj.getName() && tabSetId == obj.getTabSetId() )
		    {
			switch ( type ) 
			{
			case CegoObject::TABLE:
			case CegoObject::SYSTEM:
			case CegoObject::RBSEG:
			case CegoObject::INDEX:
			case CegoObject::PINDEX:
			case CegoObject::UINDEX:
			{
			    CegoTableObject to;			
			    to.decode(pE);
			    
			    fileId = to.getDataFileId();
			    pageId = to.getDataPageId();	       			
			    
			    int newFileId;
			    int newPageId;
			    
			    int newLastFileId;
			    int newLastPageId;
			    
			    removeEmptyPages(tabSetId, fileId, pageId, newFileId, newPageId, newLastFileId, newLastPageId);
			    
			    to.setDataFileId(newFileId);
			    to.setDataPageId(newPageId);
			    
			    to.setLastDataFileId(newLastFileId);
			    to.setLastDataPageId(newLastPageId);
			    
			    to.encode(pE);
			    
			    _pLockHandle->unlockSysPage(lockId);
			    lockId = 0;

			    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
			    
			    return;
			    
			}
			default:
			    break;			    
			}
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}    
	    }	
	}
	Chain msg = Chain("Object ") +  objName + Chain(" not found");
	throw Exception(EXLOC, msg);

    }
    catch ( Exception e)
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }
}


void CegoObjectManager::invalidateObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type)
{
    unsigned long lockId = 0;
    CegoBufferPage bp;
		
    try
    {

	int lowPage;
	int highPage; 
	
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = objName.getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
       	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage++)
	{ 
	    
	    int pageId = hashPage;
	    
	    int fileId;
	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {
		fileId = tabSetId;
	    }
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
		
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    
		    int size;
		    obj.decodeBase(pE, size);   
		    
		    bool typeMatch =  ( type == CegoObject::INDEX 
					&& ( obj.getType() == CegoObject::INDEX
					     || obj.getType() == CegoObject::PINDEX
					     || obj.getType() == CegoObject::UINDEX ));
		    if ( ! typeMatch )
			typeMatch = obj.getType() == type;
		    
		    if ( typeMatch && objName == obj.getName() && tabSetId == obj.getTabSetId() )
		    {
			switch ( type ) 
			{
			case CegoObject::TABLE:
			case CegoObject::SYSTEM:
			case CegoObject::RBSEG:
			case CegoObject::INDEX:
			case CegoObject::PINDEX:
			case CegoObject::UINDEX:		       
			{
			    CegoTableObject to;			
			    to.decode(pE);
			    
			    fileId = to.getDataFileId();
			    pageId = to.getDataPageId();	       			

			    
			    freeObjectPages(tabSetId, fileId, pageId);			    
			    
			    // remove pages here
			    
			    to.setDataFileId(0);
			    to.setDataPageId(0);
			    
			    to.setLastDataFileId(0);
			    to.setLastDataPageId(0);
			    
			    to.encode(pE);
			    
			    _pLockHandle->unlockSysPage(lockId);
			    lockId = 0;

			    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
			    
			    return;
			    
			}
			default:
			    break;
			}
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}    
	    }	
	}
	Chain msg = Chain("Object ") +  objName + Chain(" not found");
	throw Exception(EXLOC, msg);

    }
    catch ( Exception e)
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;	
	
    }
}

void CegoObjectManager::alterTableObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type, CegoTableObject& objEntry)
{

    unsigned long lockId = 0;
    unsigned long altLockId = 0;
    CegoBufferPage bp;
    CegoBufferPage altPage;	    
    
    try
    {

	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	if ( type == CegoObject::SYSTEM )
	{
	    lockMode = CegoBufferPool::PERSISTENT; 
	}
		
	int lowPage;
	int highPage;
        
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX 
	     || type == CegoObject::FKEY )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = objName.getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage++)
	{ 

	    int fileId;

	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {
		fileId = tabSetId;
	    }

	    int pageId = hashPage; 
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
			    
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    int entrySize;
		    
		    obj.decodeBase(pE, entrySize);   
		    
		    bool typeMatch =  ( type == CegoObject::INDEX
					&& ( obj.getType() == CegoObject::INDEX
					     || obj.getType() == CegoObject::PINDEX
					     || obj.getType() == CegoObject::UINDEX ));
		    if ( ! typeMatch )
			typeMatch = obj.getType() == type;
		    		    
		    if ((Chain)obj.getName() == objName && typeMatch && tabSetId == obj.getTabSetId())
		    {		       
			
			CegoTableObject to;
			
			to.decode(pE);   
			
			bp.freeEntry(pE);	       
			
			_pLockHandle->unlockSysPage(lockId);
			lockId = 0;

			_pDBMng->bufferUnfix(bp, true, _pLockHandle);
			
			
			int dataFileId = to.getDataFileId();
			int dataPageId = to.getDataPageId();		    
			int lastFileId = to.getLastDataFileId();
			int lastPageId = to.getLastDataPageId();	       			
			
			// make new entry here
			
			int altFileId;
			if ( type == CegoObject::RBSEG )
			{
			    Chain tableSet = _pDBMng->getTabSetName(tabSetId);
			    altFileId = _pDBMng->getTmpFid(tableSet);
			}
			else
			{
			    altFileId = tabSetId;
			}
			
			int altPageId = objEntry.getName().getHashPos(TABMNG_HASHSIZE);
			
			bool created = false;
						
			_pDBMng->bufferFix(altPage, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
			
			while ( ! created )
			{
			    char *buf;
			   
			    altLockId = _pLockHandle->lockSysPage(altFileId, altPageId, CegoLockHandler::WRITE);
			
			    buf = (char*)altPage.newEntry(objEntry.getEntrySize());
			    
			    if ( buf )
			    {
				objEntry.setDataFileId(dataFileId);
				objEntry.setDataPageId(dataPageId);
				objEntry.setLastDataFileId(lastFileId);
				objEntry.setLastDataPageId(lastPageId);
				
				objEntry.encode(buf);
				
				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;
				
				return;			    
			    }
			    else
			    {
				altFileId = altPage.getNextFileId();
				altPageId = altPage.getNextPageId();
				
				CegoBufferPage nbp;
				
				if (altFileId == 0 && altPageId == 0)
				{
				    getNewFilePage(nbp, tabSetId, type);				    
				}
				else
				{
				    _pDBMng->bufferFix(nbp, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
				}
				
				altPage.setNextFileId(nbp.getFileId());
				altPage.setNextPageId(nbp.getPageId());
				
				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;
				
				altPage = nbp;
			    }
			}		    
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;
	    
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}	    
	    }
	}
	Chain msg = Chain("Table ") +  objName + Chain(" not found");
	throw Exception(EXLOC, msg);
    }
    catch ( Exception e)
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);

	if ( altPage.isFixed() )
	    _pDBMng->bufferUnfix(altPage, false, _pLockHandle);
	
	if ( altLockId )
	    _pLockHandle->unlockSysPage(altLockId);
       
	throw e;	
	
    }    
}


void CegoObjectManager::alterBTreeObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type, CegoBTreeObject& objEntry)
{

    unsigned long lockId = 0;
    unsigned long altLockId = 0;
    CegoBufferPage bp;
    CegoBufferPage altPage;	    
    
    try
    {

	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	if ( type == CegoObject::SYSTEM )
	{
	    lockMode = CegoBufferPool::PERSISTENT; 
	}
		
	int lowPage;
	int highPage;
        
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX 
	     || type == CegoObject::FKEY )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = objName.getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage++)
	{ 

	    int fileId;

	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {
		fileId = tabSetId;
	    }

	    int pageId = hashPage; 
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
			    
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    int entrySize;
		    
		    obj.decodeBase(pE, entrySize);   

		    bool typeMatch =  
			( type == CegoObject::BTREE && ( obj.getType() == CegoObject::BTREE
							 || obj.getType() == CegoObject::PBTREE
							 || obj.getType() == CegoObject::UBTREE ));
		    
		    if ( ! typeMatch )
			typeMatch = obj.getType() == type;
		    
		    
		    if ((Chain)obj.getName() == objName && typeMatch && tabSetId == obj.getTabSetId())
		    {		       
			
			CegoBTreeObject bto;
			
			bto.decode(pE);   
			
			bp.freeEntry(pE);	       
			
			_pLockHandle->unlockSysPage(lockId);
			lockId = 0;

			_pDBMng->bufferUnfix(bp, true, _pLockHandle);
			
			
			int dataFileId = bto.getDataFileId();
			int dataPageId = bto.getDataPageId();		    
			
			// make new entry here
			
			int altFileId = tabSetId;			
			int altPageId = objEntry.getName().getHashPos(TABMNG_HASHSIZE);
			
			bool created = false;
						
			_pDBMng->bufferFix(altPage, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
			
			while ( ! created )
			{
			    char *buf;
			   
			    altLockId = _pLockHandle->lockSysPage(altFileId, altPageId, CegoLockHandler::WRITE);
			
			    buf = (char*)altPage.newEntry(objEntry.getEntrySize());
			    
			    if ( buf )
			    {
				objEntry.setDataFileId(dataFileId);
				objEntry.setDataPageId(dataPageId);
				
				objEntry.encode(buf);
				
				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;
				
				return;			    
			    }
			    else
			    {
				altFileId = altPage.getNextFileId();
				altPageId = altPage.getNextPageId();
				
				CegoBufferPage nbp;
				
				if (altFileId == 0 && altPageId == 0)
				{
				    getNewFilePage(nbp, tabSetId, type);				    
				}
				else
				{
				    _pDBMng->bufferFix(nbp, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
				}
				
				altPage.setNextFileId(nbp.getFileId());
				altPage.setNextPageId(nbp.getPageId());
				
				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;
				
				altPage = nbp;
			    }
			}		    
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;
	    
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}	    
	    }
	}
	Chain msg = Chain("BTree ") +  objName + Chain(" not found");
	throw Exception(EXLOC, msg);
    }
    catch ( Exception e)
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);

	if ( altPage.isFixed() )
	    _pDBMng->bufferUnfix(altPage, false, _pLockHandle);
	
	if ( altLockId )
	    _pLockHandle->unlockSysPage(altLockId);
       
	throw e;	
	
    }    
}



void CegoObjectManager::alterKeyObject(int tabSetId, const Chain& keyName, CegoObject::ObjectType type, CegoKeyObject& objEntry)
{

    unsigned long lockId = 0;
    unsigned long altLockId = 0;
    CegoBufferPage bp;
    CegoBufferPage altPage;

    try
    {
	
	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	if ( type == CegoObject::SYSTEM )
	{
	    lockMode = CegoBufferPool::PERSISTENT; 
	}
    	
	for ( int hashPage = 0; hashPage < TABMNG_HASHSIZE ; hashPage++)
	{ 
	    
	    int fileId = tabSetId;
	    int pageId = hashPage;
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
	    
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    int entrySize;
		    
		    obj.decodeBase(pE, entrySize);   
		    
		    if ((Chain)obj.getName() == keyName && obj.getType() == type && tabSetId == obj.getTabSetId())
		    {		       
			
			CegoKeyObject ko;
			
			ko.decode(pE);   
			
			bp.freeEntry(pE);	       
			
			_pDBMng->bufferUnfix(bp, true, _pLockHandle);		    
			_pLockHandle->unlockSysPage(lockId);
			lockId = 0;
			
			int altFileId = tabSetId;
			int altPageId = objEntry.getName().getHashPos(TABMNG_HASHSIZE);
			
			bool created = false;
						
			_pDBMng->bufferFix(altPage, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
			
			while ( ! created )
			{
			    char *buf;
			    
			    altLockId = _pLockHandle->lockSysPage(altFileId, altPageId, CegoLockHandler::WRITE);
			    
			    buf = (char*)altPage.newEntry(objEntry.getEntrySize());
			    
			    if ( buf )
			    {			
				objEntry.encode(buf);
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;

				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);			    
				return;			    
			    }
			    else
			    {
				altFileId = altPage.getNextFileId();
				altPageId = altPage.getNextPageId();
				
				CegoBufferPage nbp;
				
				if (altFileId == 0 && altPageId == 0)
				{
				    getNewFilePage(nbp, tabSetId, type);				    
				}
				else
				{
				    _pDBMng->bufferFix(nbp, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
				}
				
				altPage.setNextFileId(nbp.getFileId());
				altPage.setNextPageId(nbp.getPageId());
				
				_pLockHandle->unlockSysPage(altLockId);			    
				altLockId = 0;

				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				
				altPage = nbp;
			    }
			}		    
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);		
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}	    
	    }	
	}
	Chain msg = Chain("Key ") +  keyName + Chain(" not found");
	throw Exception(EXLOC, msg);
    }
    catch ( Exception e )
    {
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( altPage.isFixed() )
	    _pDBMng->bufferUnfix(altPage, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	if ( altLockId )
	    _pLockHandle->unlockSysPage(altLockId);	    
	
	throw e;
	
    }

}

void CegoObjectManager::alterCheckObject(int tabSetId, const Chain& checkName, CegoObject::ObjectType type, CegoCheckObject& objEntry)
{


    unsigned long lockId = 0;
    unsigned long altLockId = 0;
    CegoBufferPage bp;
    CegoBufferPage altPage;

    try
    {
    
	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	if ( type == CegoObject::SYSTEM )
	{
	    lockMode = CegoBufferPool::PERSISTENT; 
	}
	
   	
	for ( int hashPage = 0; hashPage < TABMNG_HASHSIZE ; hashPage++)
	{ 
	    
	    int fileId = tabSetId;
	    int pageId = hashPage;
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage  )
	    {
	    
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    int entrySize;
		    
		    obj.decodeBase(pE, entrySize);   
		    
		    if ((Chain)obj.getName() == checkName && obj.getType() == type && tabSetId == obj.getTabSetId())
		    {		       
			
			CegoCheckObject co;
			
			co.decode(pE);   
			
			bp.freeEntry(pE);	       
			
			_pLockHandle->unlockSysPage(lockId);
			_pDBMng->bufferUnfix(bp, true, _pLockHandle);
			
			
			int altFileId = tabSetId;
			int altPageId = objEntry.getName().getHashPos(TABMNG_HASHSIZE);
			
			bool created = false;
					    
			_pDBMng->bufferFix(altPage, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
			
			while ( ! created )
			{
			    char *buf;
			    
			    altLockId = _pLockHandle->lockSysPage(altFileId, altPageId, CegoLockHandler::WRITE);
			    
			    buf = (char*)altPage.newEntry(objEntry.getEntrySize());
			    
			    if ( buf )
			    {
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;

				objEntry.encode(buf);			    
				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				return;
			    }
			    else
			    {
				altFileId = altPage.getNextFileId();
				altPageId = altPage.getNextPageId();
				
				CegoBufferPage nbp;
				
				if (altFileId == 0 && altPageId == 0)
				{
				    getNewFilePage(nbp, tabSetId, type);				    
				}
				else
				{
				    _pDBMng->bufferFix(nbp, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
				}
				
				altPage.setNextFileId(nbp.getFileId());
				altPage.setNextPageId(nbp.getPageId());
				
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;
				
				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				
				altPage = nbp;
			    }
			}
			
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);	    	    
		lockId = 0;

		_pDBMng->bufferUnfix(bp, true, _pLockHandle);		
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}	    
	    }	
	}
	Chain msg = Chain("Check ") +  checkName + Chain(" not found");
	throw Exception(EXLOC, msg);
    }
    catch ( Exception e )
    {
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( altPage.isFixed() )
	    _pDBMng->bufferUnfix(altPage, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	if ( altLockId )
	    _pLockHandle->unlockSysPage(altLockId);	    
	
	throw e;
	
    }
}

void CegoObjectManager::alterProcObject(int tabSetId, const Chain& procName, CegoProcObject& procEntry)
{

    unsigned long lockId = 0;
    unsigned long altLockId = 0;
    CegoBufferPage bp;
    CegoBufferPage altPage;

    try
    {
	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	for ( int hashPage = 0; hashPage < TABMNG_HASHSIZE ; hashPage++)
	{ 
	    
	    int fileId = tabSetId;
	    int pageId = hashPage;
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
		
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
				
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    int entrySize;
		    
		    obj.decodeBase(pE, entrySize);   
		    
		    if ((Chain)obj.getName() == procName && obj.getType() == CegoObject::PROCEDURE && tabSetId == obj.getTabSetId())
		    {		       
			
			CegoKeyObject ko;
			
			ko.decode(pE);   
			
			bp.freeEntry(pE);	       
			
			_pLockHandle->unlockSysPage(lockId);
			lockId = 0;

			_pDBMng->bufferUnfix(bp, false, _pLockHandle);
			
			int altFileId = tabSetId;
			int altPageId = procEntry.getName().getHashPos(TABMNG_HASHSIZE);
			
			bool created = false;
					    
			_pDBMng->bufferFix(altPage, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
			
			while ( ! created )
			{
			    char *buf;
			    
			    altLockId = _pLockHandle->lockSysPage(altFileId, altPageId, CegoLockHandler::WRITE);
			    			    
			    buf = (char*)altPage.newEntry(procEntry.getEntrySize());
			    
			    
			    if ( buf )
			    {
				procEntry.encode(buf);			
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;

				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				return;
			    }
			    else
			    {
				altFileId = altPage.getNextFileId();
				altPageId = altPage.getNextPageId();
				
				CegoBufferPage nbp;
				
				if (altFileId == 0 && altPageId == 0)
				{
				    getNewFilePage(nbp, tabSetId, CegoObject::PROCEDURE);				    
				}
				else
				{
				    _pDBMng->bufferFix(nbp, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
				}
				
				altPage.setNextFileId(nbp.getFileId());
				altPage.setNextPageId(nbp.getPageId());
				
				_pLockHandle->unlockSysPage(altLockId);			    
				altLockId = 0;
				
				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				
				altPage = nbp;
			    }
			}
			
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);	    	    
		lockId = 0;

		_pDBMng->bufferUnfix(bp, true, _pLockHandle);		
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}	    
	    }	
	}    
	Chain msg = Chain("Procedure ") +  procName + Chain(" not found");
	throw Exception(EXLOC, msg);
	
    }
    catch ( Exception e )
    {
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( altPage.isFixed() )
	    _pDBMng->bufferUnfix(altPage, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	if ( altLockId )
	    _pLockHandle->unlockSysPage(altLockId);	    
	
	throw e;
	
    }
}


void CegoObjectManager::alterViewObject(int tabSetId, const Chain& viewName, CegoViewObject& viewEntry)
{
    unsigned long lockId = 0;
    unsigned long altLockId = 0;
    CegoBufferPage bp;
    CegoBufferPage altPage;

    try
    {
	
	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	for ( int hashPage = 0; hashPage < TABMNG_HASHSIZE ; hashPage++)
	{ 
	    
	    int fileId = tabSetId;
	    int pageId = hashPage;
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage  )
	    {
		
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    int entrySize;
		    
		    obj.decodeBase(pE, entrySize);   
		    
		    if ((Chain)obj.getName() == viewName && obj.getType() == CegoObject::VIEW && tabSetId == obj.getTabSetId())
		    {		       
			
			CegoViewObject vo;
			
			vo.decode(pE);   
			
			bp.freeEntry(pE);	       
			
			_pDBMng->bufferUnfix(bp, false, _pLockHandle);
			_pLockHandle->unlockSysPage(lockId);
			lockId = 0;

			// make new entry here
			
			int altFileId = tabSetId;
			int altPageId = viewEntry.getName().getHashPos(TABMNG_HASHSIZE);
			
			bool created = false;
			
			_pDBMng->bufferFix(altPage, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
			
			while ( ! created )
			{
			    char *buf;
			    			 
			    altLockId = _pLockHandle->lockSysPage(altFileId, altPageId, CegoLockHandler::WRITE);
			    
			    buf = (char*)altPage.newEntry(viewEntry.getEntrySize());
			    
			    if ( buf )
			    {
				viewEntry.encode(buf);			    
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;
				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);			 
				return;			    
			    }
			    else
			    {
				altFileId = altPage.getNextFileId();
				altPageId = altPage.getNextPageId();
				
				CegoBufferPage nbp;
				
				if (altFileId == 0 && altPageId == 0)
				{
				    getNewFilePage(nbp, tabSetId, CegoObject::VIEW);				    
				}
				else
				{
				    _pDBMng->bufferFix(nbp, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
				}

				
				altPage.setNextFileId(nbp.getFileId());
				altPage.setNextPageId(nbp.getPageId());
				
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;

				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				
				altPage = nbp;
			    }
			}
			
		    }
		    pE = (char*)bp.getNextEntry();
		}
				
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);	    	    
		lockId = 0;

		_pDBMng->bufferUnfix(bp, true, _pLockHandle);		
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}	    
	    }	
	}
	Chain msg = Chain("View ") +  viewName + Chain(" not found");
	throw Exception(EXLOC, msg);
    }
    catch ( Exception e )
    {
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( altPage.isFixed() )
	    _pDBMng->bufferUnfix(altPage, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);

	if ( altLockId )
	    _pLockHandle->unlockSysPage(altLockId);	    
	
	throw e;
	
    }
}


void CegoObjectManager::alterCheckObject(int tabSetId, const Chain& checkName, CegoCheckObject& checkEntry)
{

    unsigned long lockId = 0;
    unsigned long altLockId = 0;
    CegoBufferPage bp;    
    CegoBufferPage altPage;
    
    try
    {
	
	CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	
	for ( int hashPage = 0; hashPage < TABMNG_HASHSIZE ; hashPage++)
	{ 
	    
	    int fileId = tabSetId;
	    int pageId = hashPage;
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
		
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
				
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::WRITE);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    
		    CegoObject obj;
		    int entrySize;
		    
		    obj.decodeBase(pE, entrySize);   
		    
		    if ((Chain)obj.getName() == checkName && obj.getType() == CegoObject::CHECK && tabSetId == obj.getTabSetId())
		    {		       
			
			CegoCheckObject co;
			
			co.decode(pE);   
			
			bp.freeEntry(pE);	       
		    
			_pLockHandle->unlockSysPage(lockId);
			lockId = 0;

			_pDBMng->bufferUnfix(bp, false, _pLockHandle);
						    
			// make new entry here
			
			int altFileId = tabSetId;
			int altPageId = checkEntry.getName().getHashPos(TABMNG_HASHSIZE);
			
			bool created = false;
						
			_pDBMng->bufferFix(altPage, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
			
			while ( ! created )
			{
			    char *buf;
			    
			    altLockId = _pLockHandle->lockSysPage(altFileId, altPageId, CegoLockHandler::WRITE);
			    
			    buf = (char*)altPage.newEntry(checkEntry.getEntrySize());
			    
			    if ( buf )
			    {			    
				checkEntry.encode(buf);			    			    
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;

				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				return;			    
			    }
			    else
			    {
				altFileId = altPage.getNextFileId();
				altPageId = altPage.getNextPageId();
				
				CegoBufferPage nbp;
				
				
				if (altFileId == 0 && altPageId == 0)
				{
				    getNewFilePage(nbp, tabSetId, CegoObject::VIEW);				    
				}
				else
				{
				    _pDBMng->bufferFix(nbp, tabSetId, altFileId, altPageId, lockMode, _pLockHandle);
				}
				
				altPage.setNextFileId(nbp.getFileId());
				altPage.setNextPageId(nbp.getPageId());
				
				_pLockHandle->unlockSysPage(altLockId);
				altLockId = 0;

				_pDBMng->bufferUnfix(altPage, true, _pLockHandle);
				
				altPage = nbp;
			    }
			}
			
		    }
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);	    
		lockId = 0;

		_pDBMng->bufferUnfix(bp, true, _pLockHandle);		
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}	    
	    }	
	}
	
	Chain msg = Chain("Check ") +  checkName + Chain(" not found");
	throw Exception(EXLOC, msg);
    }
    catch ( Exception e )
    {
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);

	if ( altPage.isFixed() )
	    _pDBMng->bufferUnfix(altPage, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);

	if ( altLockId )
	    _pLockHandle->unlockSysPage(altLockId);	    
	
	throw e;
	
    }
}


void CegoObjectManager::getObjectList(int tabSetId, CegoObject::ObjectType type, ListT<Chain>& objList)
{    
       
    unsigned long lockId = 0;
    CegoBufferPage bp;
    
    try
    {
	int maxPos = TABMNG_HASHSIZE;
	
	for ( int hashPos = 0 ; hashPos < maxPos; hashPos++ )
	{
	    
	    int pageId = hashPos;
	    
	    int fileId;
	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {
		fileId = tabSetId;
	    }
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage )
	    {
		
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
	    		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::READ);
		char* pE = (char*)bp.getFirstEntry();
		
		while (pE)
		{
		    
		    CegoObject obj;
		    int entrySize;
		    
		    obj.decodeBase(pE, entrySize);   
		    
		    if ( tabSetId == obj.getTabSetId() )
		    {

			bool typeMatch =  
			    ( type == CegoObject::INDEX && ( obj.getType() == CegoObject::INDEX
							     || obj.getType() == CegoObject::PINDEX
							     || obj.getType() == CegoObject::UINDEX )) ||
			    ( type == CegoObject::BTREE && ( obj.getType() == CegoObject::BTREE
							     || obj.getType() == CegoObject::PBTREE
							     || obj.getType() == CegoObject::UBTREE ));
			if ( ! typeMatch )
			    typeMatch = obj.getType() == type;
			
			if ( typeMatch )
			{		    		   
			    objList.Insert(obj.getName());
			}
		    }
		    
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);		    
		lockId = 0;

		_pDBMng->bufferUnfix(bp, false, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}
	    }
	}
    }
    catch ( Exception e )
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);	    	
	
	throw e;	
    }

}

void CegoObjectManager::getObjectListByTable(int tabSetId, const Chain& tabName, 
					     ListT<CegoTableObject>& idxList, 
					     ListT<CegoBTreeObject>& btreeList, 
					     ListT<CegoKeyObject>& keyList,
					     ListT<CegoCheckObject>& checkList, bool ignoreInvalid)
{

    keyList.Empty();
    checkList.Empty();
    idxList.Empty();

    unsigned long lockId = 0;
    CegoBufferPage bp;

    try
    {
	int maxPos = TABMNG_HASHSIZE;
	
	for ( int hashPos = 0 ; hashPos < maxPos; hashPos++ )
	{
	    
	    int fileId = tabSetId;	
	    int pageId = hashPos;
	    
	    bool lastPage = false;	
	    
	    while ( ! lastPage )
	    {
		
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);	
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::READ);	
		
		char* pE = (char*)bp.getFirstEntry();
		
		while (pE)
		{
		    
		    CegoObject obj;
		    int entrySize;
		    obj.decodeBase(pE, entrySize);   
		    
		    if ( tabSetId == obj.getTabSetId() )
		    {
			if ( obj.getType() == CegoObject::FKEY)
			{
			    CegoKeyObject ko;
			    ko.decode(pE);
			    if ( (Chain)ko.getTabName() == (Chain)tabName || (Chain)ko.getRefTable() == (Chain)tabName )
			    {
				keyList.Insert(ko);
			    }
			}
			else if ( obj.getType() == CegoObject::CHECK )
			{
			    CegoCheckObject co;
			    co.decode(pE);
			    if ( (Chain)co.getTabName() == (Chain)tabName )
			    {
				checkList.Insert(co);
			    }			
			}
			else if ( obj.getType() == CegoObject::INDEX 
				  || obj.getType() == CegoObject::UINDEX 
				  || obj.getType() == CegoObject::PINDEX ) 
			{
			    CegoTableObject io;
			    io.decode(pE);
			    			    
			    if ( (Chain)io.getTabName() == (Chain)tabName)
			    {
				// for invalidation
				if ( ! ( io.getDataFileId() == 0 && io.getDataPageId() == 0 && ignoreInvalid ) ) 
				    idxList.Insert(io);
			    }
			}
			else if ( obj.getType() == CegoObject::BTREE 
				  || obj.getType() == CegoObject::UBTREE 
				  || obj.getType() == CegoObject::PBTREE ) 
			{
			    CegoBTreeObject bto;
			    bto.decode(pE);
			    			    
			    if ( (Chain)bto.getTabName() == (Chain)tabName)
			    {
				// for invalidation
				if ( ! ( bto.getDataFileId() == 0 && bto.getDataPageId() == 0 && ignoreInvalid ) ) 
				    btreeList.Insert(bto);
			    }
			}
		    }
		    
		    pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		_pDBMng->bufferUnfix(bp, false, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}
	    }
	}
    }
    catch ( Exception e)
    {
	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);	    	
	
	throw e;
    }
}

void CegoObjectManager::getObject(int tabSetId, const Chain& objectName, CegoObject::ObjectType type, CegoDecodableObject& oe)
{
    CegoBufferPage bp;
    getObjectWithFix(tabSetId, objectName, type, oe, bp);
    _pDBMng->bufferUnfix(bp, false, _pLockHandle);    
}

void CegoObjectManager::getObjectWithFix(int tabSetId, const Chain& objectName, CegoObject::ObjectType type, CegoDecodableObject& oe, CegoBufferPage &bp)
{

    unsigned long lockId = 0;
    
    try
    {
	
	int lowPage;
	int highPage;
	
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX 
	     || type == CegoObject::BTREE
	     || type == CegoObject::PBTREE 
	     || type == CegoObject::UBTREE 
	     || type == CegoObject::FKEY
	     || type == CegoObject::CHECK )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = objectName.getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
	
	bool notFound = true;
	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage ++)
	{ 
	    
	    int pageId = hashPage;
	    int fileId;
	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {
		fileId = tabSetId;
	    }
	    
	    bool lastPage = false;
	    
	    while ( ! lastPage && notFound )
	    {
		
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::READ);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while (pE && notFound )
		{
		    
		    CegoObject obj;
		    int entrySize;
		    obj.decodeBase(pE, entrySize);
		    
		    if ( tabSetId == obj.getTabSetId() )
		    {

			bool typeMatch =  
			    ( type == CegoObject::INDEX && ( obj.getType() == CegoObject::INDEX
							     || obj.getType() == CegoObject::PINDEX
							     || obj.getType() == CegoObject::UINDEX )) ||
			    ( type == CegoObject::BTREE && ( obj.getType() == CegoObject::BTREE
							     || obj.getType() == CegoObject::PBTREE
							     || obj.getType() == CegoObject::UBTREE ));
			if ( ! typeMatch )
			    typeMatch = obj.getType() == type;
			
			if ((Chain)obj.getName() == (Chain)objectName && typeMatch ) // && type != CegoObject::FKEY)
			{
			    oe.decode(pE);
			    notFound = false;
			}
			else
			{		    
			    pE = (char*)bp.getNextEntry();
			}
		    }
		    else
		    {		    
			pE = (char*)bp.getNextEntry();
		    }
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		if ( notFound == false )
		{
		    return;
		}
		else
		{
		    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
		}
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}   
	    }	
	}
	if ( notFound ) 
	{
	    Chain msg = Chain("Object ") +  objectName + Chain(" not found");
	    throw Exception(EXLOC, msg);
	}	
    }
    catch ( Exception e )
    {	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);	    	
	
	throw e;	
    }
}

bool CegoObjectManager::objectExists(int tabSetId, const Chain& objectName, CegoObject::ObjectType type)
{


    CegoBufferPage bp;
    unsigned long lockId = 0;	    
    
    try
    {
	
	int lowPage;
	int highPage;
	
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX 
	     || type == CegoObject::BTREE 
	     || type == CegoObject::PBTREE 
	     || type == CegoObject::UBTREE 
	     || type == CegoObject::FKEY
	     || type == CegoObject::CHECK )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = objectName.getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
		
	bool found = false;
	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage++)
	{ 
	    
	    int fileId;
	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {	
		fileId = tabSetId;
	    }
	    
	    int pageId = hashPage;	    
	    bool lastPage = false;
	    	    
	    while ( ! lastPage && ! found )
	    {
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);

		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::READ);
		
		char* pE = (char*)bp.getFirstEntry();
		
		while (pE && ! found )
		{
		    
		    CegoObject oe;
		    int entrySize;
		    oe.decodeBase(pE, entrySize);
		    
		    if ( tabSetId == oe.getTabSetId() )
		    {
			bool typeMatch =  
			    ( type == CegoObject::INDEX && ( oe.getType() == CegoObject::INDEX
							     || oe.getType() == CegoObject::PINDEX
							     || oe.getType() == CegoObject::UINDEX )) ||
			    ( type == CegoObject::BTREE && ( oe.getType() == CegoObject::BTREE
							     || oe.getType() == CegoObject::PBTREE
							     || oe.getType() == CegoObject::UBTREE ));
			if ( ! typeMatch )
			    typeMatch = oe.getType() == type;
			
			if ((Chain)oe.getName() == objectName && typeMatch ) 
			{	
			    found = true;
			}
			else
			{		    		    
			    pE = (char*)bp.getNextEntry();
			}
		    }
		    else
		    {		    
			pE = (char*)bp.getNextEntry();
		    }		
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);		    
		lockId = 0;

		_pDBMng->bufferUnfix(bp, false, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}
	    }
	    
	    if ( found )
		return true;
	}
	
	return false;        
	
    }
    catch ( Exception e )
    {
	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);	    	
	
	throw e;		
    }
}

CegoDataPointer CegoObjectManager::insertData(CegoTableObject& oe, char* data, int dataSize, bool doAppend, bool allowWrite)
{
    
    unsigned long recLock = 0;
    unsigned long lockId = 0;
    CegoBufferPage bp;
    
    try
    {
	
	int lowPage;
	int highPage;
	
	if ( oe.getType() == CegoObject::INDEX 
	     || oe.getType() == CegoObject::PINDEX 
	     || oe.getType() == CegoObject::UINDEX 
	     || oe.getType() == CegoObject::FKEY )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = oe.getTabName().getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage++)
	{ 
	    
	    int pageId = hashPage;
	    
	    int fileId;
	    
	    if ( oe.getType() == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(oe.getTabSetId());
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {		      
		fileId = oe.getTabSetId();
	    }
	    
	    bool lastPage = false;	
	    
	    while ( ! lastPage )
	    {		
		_pDBMng->bufferFix(bp, oe.getTabSetId(), fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::READ); 
		
		char* pE = (char*)bp.getFirstEntry();
		
		while ( pE )
		{
		    CegoObject obj;
		    int entrySize;
		    obj.decodeBase(pE, entrySize);
		    		    
		    if ( oe.getTabSetId() == obj.getTabSetId() 
			 && (Chain)oe.getName() == (Chain)obj.getName() 
			 && oe.getType() == obj.getType())
		    {
		    	
			CegoDataPointer recDP(fileId, pageId, bp.getEntryPos());
			
			recLock = _pLockHandle->lockSysRecord(bp, recDP, CegoLockHandler::WRITE);
			
			// resolve required
			oe.decode(pE);
			
			CegoDataPointer dp;
			
			int startFileId;
			int startPageId;
			
			if ( doAppend )			    
			{			
			    startFileId = oe.getRefLastDataFileId();
			    startPageId = oe.getRefLastDataPageId();
			}
			else
			{
			    startFileId = oe.getDataFileId();
			    startPageId = oe.getDataPageId();	       
			}
			
			bool isNewPage;
			
			
			dp = insertPageData(oe.getTabSetId(), oe.getType(), startFileId, startPageId, data, dataSize, isNewPage, allowWrite, doAppend);
			
			if ( isNewPage )
			{			       
			    oe.setRefLastDataFileId(dp.getFileId());
			    oe.setRefLastDataPageId(dp.getPageId());			       
			}			
			
			_pLockHandle->unlockSysRecord(recLock);

			recLock = 0;
			
			_pLockHandle->unlockSysPage(lockId);
			lockId = 0;
			
			_pDBMng->bufferUnfix(bp, true, _pLockHandle);
			
			return dp;
			
		    }
		    else
		    {
			pE = (char*)bp.getNextEntry();
		    }
		    
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		_pDBMng->bufferUnfix(bp, false, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}
	    }
	}
	Chain msg = Chain("Object ") +  oe.getName() + Chain(" not found");
	throw Exception(EXLOC, msg);
	
    }
    catch ( Exception e )
    {
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	if ( recLock )
	{
	    _pLockHandle->unlockSysRecord(recLock);	    
	}
	throw e;
    }
}

/* 
   The second insertData method is performance optimized and can be used, if the the data pointer for the corresponding object 
   is already available (sysEntry). In this case, no lookup up is required to get the entry point for the object.
   Anyway the TableObject is given as an argument to set up the lastpage information for the object.
   The insertAtLast flag enables append mode rather then looking for unued page slots in the available data pages.
   The allowWrite flag is used to allow asynchronous writes of data pages to the data files.
   Normally, this is used for index and temp objects.
 */

CegoDataPointer CegoObjectManager::insertData( const CegoDataPointer& sysEntry, CegoTableObject& oe, char* data, int dataSize, bool doAppend, bool allowWrite)
{
		
    CegoBufferPage zerobp;    
    unsigned long recLock = 0;

    try
    {
	recLock = _pLockHandle->lockSysRecord(zerobp, sysEntry, CegoLockHandler::WRITE);

	CegoDataPointer dp;
	
	int fileId;
	int pageId;
	
	int lockFileId = oe.getDataFileId();
	int lockPageId = oe.getDataPageId();	       	    
	
	if ( doAppend )      
	{				    
	    fileId = oe.getRefLastDataFileId();
	    pageId = oe.getRefLastDataPageId();
	}
	else
	{
	    fileId = oe.getDataFileId();
	    pageId = oe.getDataPageId();	       
	}
	
	bool isNewPage;
	
	
	dp = insertPageData(oe.getTabSetId(), oe.getType(), fileId, pageId, data, dataSize, isNewPage, allowWrite, doAppend);
	if ( isNewPage )
	{
	    // setLastPage
	    oe.setRefLastDataFileId(dp.getFileId());
	    oe.setRefLastDataPageId(dp.getPageId());		  
	}
		
	_pLockHandle->unlockSysRecord(recLock);

	recLock = 0;
	
	return dp;
	
    }
    catch ( Exception e )
    {
	if ( recLock )
	{
	    _pLockHandle->unlockSysRecord(recLock);	    
	}
	
	throw e;
    }
}


void CegoObjectManager::deleteData(CegoObject::ObjectType type, int tabSetId, const CegoDataPointer& dp)
{
    
    CegoBufferPage bp;
    unsigned long lockId = 0;

    try
    {
	
	_pDBMng->bufferFix(bp, tabSetId, dp.getFileId(), dp.getPageId(), CegoBufferPool::SYNC, _pLockHandle);
	
	char* pE = (char*)bp.getPagePtr() + dp.getOffset();
	       	
	lockId = _pLockHandle->lockData(type, dp.getFileId(), dp.getPageId(), CegoLockHandler::WRITE);
	bp.freeEntry(pE);
	
	_pLockHandle->unlockData(type, lockId);
	lockId = 0;

	_pDBMng->bufferUnfix(bp, true, _pLockHandle);

    }
    catch ( Exception e)
    {

	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);

	if ( lockId )
	    _pLockHandle->unlockData(type, lockId);
	    
	throw e;
    }
}

CegoObjectCursor* CegoObjectManager::getObjectCursor(int tabSetId, const Chain& hashName, const Chain& objName, CegoObject::ObjectType type)
{
    CegoBufferPage bp;
    unsigned long lockId = 0;

    try
    {
	int lowPage;
	int highPage;
	
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX 
	     || type == CegoObject::FKEY )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	else
	{
	    lowPage = hashName.getHashPos(TABMNG_HASHSIZE);
	    highPage = lowPage + 1;
	}
		
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage++)
	{ 
	    
	    int pageId = hashPage;
	    
	    int fileId;
	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    else
	    {   
		fileId = tabSetId;
	    }
	    
	    bool lastPage = false;    
	    bool inserted = false;
	    
	    while ( ! lastPage && ! inserted)
	    {
				
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, CegoBufferPool::PERSISTENT, _pLockHandle);
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::READ);

		char* pE = (char*)bp.getFirstEntry();
		
		while (pE && ! inserted )
		{
		    CegoObject obj;
		    int entrySize;
		    
		    obj.decodeBase(pE, entrySize);
		    
		    if ( obj.getTabSetId() == tabSetId )
		    {
			bool typeMatch =  
			    ( type == CegoObject::INDEX && ( obj.getType() == CegoObject::INDEX
							     || obj.getType() == CegoObject::PINDEX
							     || obj.getType() == CegoObject::UINDEX ));
			if ( ! typeMatch )
			    typeMatch = obj.getType() == type;
			
			
			if ( (Chain)objName == (Chain)obj.getName() && typeMatch)
			{
			    
			    CegoTableObject to;
			    to.decode(pE);
			    
			    _pLockHandle->unlockSysPage(lockId);
			    lockId = 0;

			    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
			    
			    CegoObjectCursor* pC = new CegoObjectCursor(_pDBMng,
									_pLockHandle,
									tabSetId,
									type, 
									to.getDataFileId(), 
									to.getDataPageId());
			    return pC;
			    
			}
			else
			{
			    pE = (char*)bp.getNextEntry();
			}
		    }
		    else
		    {
			pE = (char*)bp.getNextEntry();
		    }
		}
		
		_pLockHandle->unlockSysPage(lockId);
		lockId = 0;

		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		_pDBMng->bufferUnfix(bp, false, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}
	    }
	}
	
	Chain msg = Chain("Object ") +  objName + Chain(" not found");
	throw Exception(EXLOC, msg);
    }
    catch ( Exception e )
    {
	
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;

    }
}

unsigned long CegoObjectManager::claimDataPtr(int tabSetId, CegoLockHandler::LockMode lockMode, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, int& len)
{
    CegoBufferPage bp;

    try
    {    
	_pDBMng->bufferFix(bp, tabSetId, dp.getFileId(), dp.getPageId(), fixMode, _pLockHandle);
        
	ptr = (char*)bp.getPagePtr() + dp.getOffset();
	len = *(int*)((long)bp.getPagePtr() + (long)dp.getOffset() - sizeof(int));
	
	unsigned long lockId=0;
		
	lockId = _pLockHandle->lockRecord(bp, dp, lockMode);
	return lockId;
    }
    catch ( Exception e )
    {
	if ( bp.isFixed() )	     
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	throw e;
    }    
}

void CegoObjectManager::releaseDataPtr(unsigned long lockId, bool isDirty)
{
    CegoBufferPage bp = _pLockHandle->getPage(lockId);
    _pDBMng->bufferUnfix(bp, isDirty, _pLockHandle);
    _pLockHandle->unlockRecord(lockId);   
}

unsigned long CegoObjectManager::releaseAndClaimDataPtr(unsigned long lockId, bool isDirty, int tabSetId, CegoLockHandler::LockMode lockMode, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, int& len)
{
    CegoBufferPage bp = _pLockHandle->getPage(lockId);

    if ( bp.getFileId() == dp.getFileId() 
	 && bp.getPageId() == dp.getPageId()  )

    {
	
	_pLockHandle->unlockRecord(lockId);

	ptr = (char*)bp.getPagePtr() + dp.getOffset();
	len = *(int*)((long)bp.getPagePtr() + (long)dp.getOffset() - sizeof(int));
	
	
	try
	{
	    lockId = _pLockHandle->lockRecord(bp, dp,  lockMode);
	}

	catch ( Exception e )
	{
	    _pDBMng->log(_modId, Logger::LOGERR, Chain("Record lock error for datapointer = ") + dp.toChain());
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	    throw Exception(EXLOC, Chain("Cannot release and claim datapointer"), e);
	}
		
	return lockId;	

    }
    else
    {
	releaseDataPtr(lockId, isDirty);
	return claimDataPtr(tabSetId, lockMode, fixMode, dp, ptr, len);
	
    }
}

CegoBufferPage CegoObjectManager::claimDataPtrUnlocked(int tabSetId, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, int& len)
{
    CegoBufferPage bp;
    
    // cout << "Claim unlocked : " << dp << endl;

    _pDBMng->bufferFix(bp, tabSetId, dp.getFileId(), dp.getPageId(), fixMode, _pLockHandle);
        
    ptr = (char*)bp.getPagePtr() + dp.getOffset();
    len = *(int*)((long)bp.getPagePtr() + (long)dp.getOffset() - sizeof(int));
    
    return bp;
}

void CegoObjectManager::releaseDataPtrUnlocked(CegoBufferPage& bp, bool isDirty)
{
    // cout << "Release unlocked : [" << bp.getFileId() << "," << bp.getPageId() << "]" << endl;
    _pDBMng->bufferUnfix(bp, isDirty, _pLockHandle);
}

void CegoObjectManager::freeObjectPages(int tabSetId, int fileId, int pageId)
{

    bool lastPage = false;

    while ( ! lastPage )
    {
	
	if (fileId == 0 && pageId == 0 )
	{
	    lastPage = true;
	}
	else
	{
	    
	    CegoBufferPage delPage;
		
	    _pDBMng->bufferFix(delPage,
			       tabSetId, 
			       fileId,
			       pageId,
			       CegoBufferPool::SYNC, _pLockHandle);
		
	    int nextFileId = delPage.getNextFileId();
	    int nextPageId = delPage.getNextPageId();

	    _pDBMng->bufferRelease(delPage, _pLockHandle);
	    
	    fileId = nextFileId;
	    pageId = nextPageId;
	    
	} 	   
    }
}

int CegoObjectManager::countObjectPages(int tabSetId, int fileId, int pageId)
{
    
    bool lastPage = false;
    int pageCount=0;

    while ( ! lastPage )
    {
	
	if (fileId == 0 && pageId == 0 )
	{
	    lastPage = true;
	}
	else
	{
	    
	    CegoBufferPage countPage;

	    
	    _pDBMng->bufferFix(countPage,
			       tabSetId, 
			       fileId,
			       pageId,
			       CegoBufferPool::SYNC, _pLockHandle);

	    pageCount++;

	    int nextFileId = countPage.getNextFileId();
	    int nextPageId = countPage.getNextPageId();

	    _pDBMng->bufferUnfix(countPage, false, _pLockHandle);
	    
	    fileId = nextFileId;
	    pageId = nextPageId;
	    
	} 	   
    }

    return pageCount;
}

void CegoObjectManager::removeEmptyPages(int tabSetId, int fileId, int pageId, int& newFileId, int& newPageId, int& newLastFileId, int& newLastPageId)
{

    bool lastPage = false;
    
    CegoBufferPage prevPage;
    CegoBufferPage chkPage;
    
    newFileId = 0;
    newPageId = 0;
    newLastFileId = 0;
    newLastPageId = 0;
    bool isFirst = true;

    while ( ! lastPage )
    {
	if (fileId == 0 && pageId == 0 )
	{
	    lastPage = true;
	}
	else
	{
	    
	    prevPage = chkPage;

	    bool isEmptyPage = true;
	    int baseFileId = fileId;
	    int basePageId = pageId;
	    
	    while ( isEmptyPage && ! lastPage )
	    {	
		_pDBMng->bufferFix(chkPage, tabSetId, fileId, pageId, CegoBufferPool::SYNC, _pLockHandle);
	       
		if ( chkPage.getNumEntries() > 0 )
		{
		    isEmptyPage = false;
		    if ( isFirst )
		    {
			newFileId = fileId;
			newPageId = pageId;
			isFirst = false;
		    }
		    newLastFileId = fileId;
		    newLastPageId = pageId;	
		}
		
		
		if ( isEmptyPage )
		{		   
		    if ( chkPage.getNextFileId() == 0 && chkPage.getNextPageId() == 0 )
		    {
			lastPage = true;			
		    }
		    
		    if ( isFirst == false || lastPage == false )
		    {
			fileId = chkPage.getNextFileId();
			pageId = chkPage.getNextPageId();

			_pDBMng->bufferRelease(chkPage, _pLockHandle); 

		    }
		    else
		    {
			newFileId = fileId;
			newPageId = pageId;			
		    }		    
		}
	    }
	    
	    if ( baseFileId != fileId || basePageId != pageId )
	    {
		
		if ( prevPage.isFixed() )
		{

		    prevPage.setNextFileId(fileId);
		    prevPage.setNextPageId(pageId);
		    
		    _pDBMng->bufferUnfix(prevPage, true, _pLockHandle);
		}
	    }
	    else
	    {
		if ( prevPage.isFixed() )
		{
		    _pDBMng->bufferUnfix(prevPage, false, _pLockHandle);
		}
	    }
	    if ( lastPage == false )
	    { 
		fileId = chkPage.getNextFileId();
		pageId = chkPage.getNextPageId();
	    }
	}
    }
    
    if ( chkPage.isFixed() )
    {
	_pDBMng->bufferUnfix(chkPage, false, _pLockHandle);
    }

    if ( newLastFileId == 0 && newLastPageId == 0 )
    {
	newLastFileId = newFileId;
	newLastPageId = newPageId;
    }
}

CegoDataPointer CegoObjectManager::insertPageData(int tabSetId, CegoObject::ObjectType type, int fileId, int pageId, char* data, int dataSize, bool& isNewPage, bool allowWrite, bool doAppend)
{

    unsigned long lockId = 0;
    CegoBufferPage bp;

    try
    {
	isNewPage=false;
	
	CegoBufferPool::FixMode fixMode = CegoBufferPool::SYNC;
	
	if ( type == CegoObject::SYSTEM )
	{
	    fixMode = CegoBufferPool::PERSISTENT; 
	}
	if ( allowWrite )
	{
	    fixMode = CegoBufferPool::NOSYNC;
	}
	
	_pDBMng->bufferFix(bp,
			   tabSetId,
			   fileId, 
			   pageId, 
			   fixMode, _pLockHandle);
	
	bool inserted = false;
	
	while ( ! inserted )
	{
	    	    
	    lockId = _pLockHandle->lockData(type, fileId, pageId, CegoLockHandler::WRITE);
	    	    
	    char *pE = (char*)bp.newEntry(dataSize);
	    
	    if (pE)
	    {
		
		_pLockHandle->unlockData(type, lockId);
		lockId = 0;
		
		memcpy(pE, data, dataSize);
		inserted = true;
		
		CegoDataPointer dp(bp.getFileId(),
				   bp.getPageId(),
				   (long)pE - (long)bp.getPagePtr());
		
		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
		
		return dp;
		
	    }
	    else
	    {
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		CegoBufferPage nbp;
		
		if (fileId == 0 && pageId == 0)
		{	 	
		    getNewFilePage(nbp, tabSetId, type, allowWrite, doAppend);
				    
		    isNewPage=true;
		    
		    fileId = nbp.getFileId();
		    pageId = nbp.getPageId();
		    bp.setNextFileId(fileId);
		    bp.setNextPageId(pageId);
		    
		    _pLockHandle->unlockData(type, lockId);		
		    lockId = 0;
		    
		    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
		    
		}
		else
		{
		    // release locked and fixed data page
		    _pLockHandle->unlockData(type, lockId);
		    lockId = 0;

		    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
		    
		    // fix next data page
		    _pDBMng->bufferFix(nbp, tabSetId, fileId, pageId, fixMode, _pLockHandle);
		    
		}		  
	    
		bp = nbp;
	    }
	}
	throw Exception(EXLOC, Chain("Cannot allocate bufferpage"));
    }
    catch ( Exception e )
    {
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockData(type, lockId);

	throw e;

    }
}

void CegoObjectManager::getNewFilePage(CegoBufferPage& bp, int tabSetId, CegoObject::ObjectType type, bool allowWrite, bool doAppend)
{

    CegoBufferPool::FixMode fixMode;
    CegoFileHandler::FileType fileType;

    if ( type == CegoObject::SYSTEM)
    {
	fixMode = CegoBufferPool::PERSISTENT;
	fileType = CegoFileHandler::SYSTEMFILE;
    }
    else if ( type == CegoObject::TABLE
	      || type == CegoObject::UINDEX
	      || type == CegoObject::PINDEX
	      || type == CegoObject::INDEX
	      || type == CegoObject::UBTREE
	      || type == CegoObject::PBTREE
	      || type == CegoObject::BTREE
	      || type  == CegoObject::VIEW)
    {
	if ( allowWrite )
	    fixMode = CegoBufferPool::NOSYNC;
	else
	    fixMode = CegoBufferPool::SYNC;

	fileType = CegoFileHandler::DATAFILE;
    }
    else if ( type == CegoObject::RBSEG )
    {
	fixMode = CegoBufferPool::SYNC;
	fileType = CegoFileHandler::TEMP;
    }
    	
    _pDBMng->emptyFix(bp, tabSetId, fixMode, fileType, _pLockHandle, doAppend);

}

int CegoObjectManager::getPageCount(int tabSetId, const Chain& objName, CegoObject::ObjectType type)
{
    CegoBufferPage bp;
    unsigned long lockId = 0;
	    
    try
    {
	int pageCount=0;
	
	int lowPage = objName.getHashPos(TABMNG_HASHSIZE);;
	int highPage = lowPage + 1;
	
	
	if ( type == CegoObject::INDEX 
	     || type == CegoObject::PINDEX 
	     || type == CegoObject::UINDEX 
	     || type == CegoObject::BTREE 
	     || type == CegoObject::PBTREE 
	     || type == CegoObject::UBTREE 
	     || type == CegoObject::FKEY )
	{ 
	    lowPage = 0;
	    highPage = TABMNG_HASHSIZE;
	}
	
	bool notFound = true;
	
	for ( int hashPage = lowPage; hashPage < highPage ; hashPage ++)
	{ 
	    
	    CegoBufferPool::FixMode lockMode = CegoBufferPool::SYNC;
	    
	    if ( type == CegoObject::SYSTEM )
	    {
		lockMode = CegoBufferPool::PERSISTENT; 
	    }
	    
	    int fileId = tabSetId;
	    
	    if ( type == CegoObject::RBSEG )
	    {
		Chain tableSet = _pDBMng->getTabSetName(tabSetId);
		fileId = _pDBMng->getTmpFid(tableSet);
	    }
	    
	    int pageId = hashPage;	
	    bool lastPage = false;
	    
	    while ( ! lastPage && notFound )
	    {
		
		_pDBMng->bufferFix(bp, tabSetId, fileId, pageId, lockMode, _pLockHandle);
		
		lockId = _pLockHandle->lockSysPage(fileId, pageId, CegoLockHandler::READ);	
		
		char* pE = (char*)bp.getFirstEntry();
		
		while (pE && notFound )
		{
		    
		    CegoObject obj;
		    
		    int size;
		    obj.decodeBase(pE, size);   

		    bool typeMatch =  
			( type == CegoObject::INDEX && ( obj.getType() == CegoObject::INDEX
							 || obj.getType() == CegoObject::PINDEX
							 || obj.getType() == CegoObject::UINDEX )) ||
			( type == CegoObject::BTREE && ( obj.getType() == CegoObject::BTREE
							 || obj.getType() == CegoObject::PBTREE
							 || obj.getType() == CegoObject::UBTREE ));
		    		   
		    if ( ! typeMatch )
			typeMatch = obj.getType() == type;
		    
		    if ( typeMatch && objName == obj.getName() )
		    {
			if ( type == CegoObject::FKEY )
			{
			    pageCount=0;
			}
			else if ( type == CegoObject::BTREE 
				  || type == CegoObject::PBTREE 
				  || type == CegoObject::UBTREE  )
			{

			    CegoBTreeObject bto;
			    
			    bto.decode(pE);   
			    
			    _pLockHandle->unlockSysPage(lockId);
			    lockId = 0;

			    notFound = false;
			    
			    fileId = bto.getDataFileId();
			    pageId = bto.getDataPageId();	       			
			   
			    CegoBTreeManager btreeMng(this, &bto);

			    btreeMng.fixRoot();
			    pageCount = btreeMng.getNumPages();			    
			    btreeMng.unfixRoot();
				    
			}
			else
			{
			    CegoTableObject to;
			    
			    to.decode(pE);   
			    
			    _pLockHandle->unlockSysPage(lockId);
			    lockId = 0;

			    notFound = false;
			    
			    fileId = to.getDataFileId();
			    pageId = to.getDataPageId();	       			
			    
			    pageCount = countObjectPages(tabSetId, fileId, pageId);
			}
		    }
		    if ( notFound ) 
			pE = (char*)bp.getNextEntry();
		}
		
		fileId = bp.getNextFileId();
		pageId = bp.getNextPageId();
		
		if (notFound)
		{
		    _pLockHandle->unlockSysPage(lockId);
		    lockId = 0;
		}
	    	
		_pDBMng->bufferUnfix(bp, false, _pLockHandle);
		
		if (fileId == 0 && pageId == 0)
		{
		    lastPage = true;
		}    
	    }
	}
	
	if ( notFound ) 
	{
	    Chain msg = Chain("Object ") +  objName + Chain(" not found");
	    throw Exception(EXLOC, msg);
	}

	return pageCount;
    }
    catch ( Exception e )
    {
	if ( bp.isFixed() )
	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
	
	if ( lockId )
	    _pLockHandle->unlockSysPage(lockId);
	
	throw e;
    }
}
