src/server/Transaction.cxx

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by www.databasecache.com                           *
00003  *   Contact: praba_tuty@databasecache.com                                 *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015   ***************************************************************************/
00016 #include<Transaction.h>
00017 #include<Lock.h>
00018 #include<Database.h>
00019 #include<Allocator.h>
00020 #include<CatalogTables.h>
00021 #include<Debug.h>
00022 
00023 DbRetVal Transaction::insertIntoHasList(Database *sysdb, LockHashNode *node)
00024 {
00025     //allocate lock node
00026     Chunk *chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
00027     DbRetVal rv = OK;
00028     TransHasNode *hasNode = (TransHasNode*)chunk->allocate(sysdb, &rv);
00029     if (NULL == hasNode)
00030     {
00031         printError(rv, "Could not allocate Lock node");
00032         return rv;
00033     }
00034     printDebug(DM_Transaction, "insertIntoHasList new TransHasNode created:%x",
00035                                                        hasNode);
00036     hasNode->node_ = node;
00037     hasNode->next_ = NULL;
00038     if (NULL == hasLockList_)
00039     {
00040         printDebug(DM_Transaction, "hasLockList is null:It is now %x",hasNode);
00041         hasLockList_ = hasNode;
00042         return OK;
00043     }
00044 
00045     TransHasNode *it = hasLockList_;
00046     while (NULL != it->next_) { it = it->next_; }
00047     it->next_ = hasNode;
00048     printDebug(DM_Transaction, "Added to hasLockList at end:%x",it);
00049     return OK;
00050 }
00051 
00052 DbRetVal Transaction::removeFromHasList(Database *sysdb, void *tuple)
00053 {
00054     Chunk *chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
00055     TransHasNode *iter = hasLockList_, *prev = hasLockList_;
00056     if (NULL == iter)
00057     {
00058         printError(ErrNotFound, "There are no tuple lock in has list.");
00059         return ErrNotFound;
00060     }
00061     while (iter != NULL)
00062     {
00063         if (tuple == iter->node_->ptrToTuple_)
00064         {
00065             prev->next_ = iter->next_;
00066             chunk->free(sysdb, iter);
00067             if (iter == hasLockList_) hasLockList_ = NULL;
00068             return OK;
00069         }
00070         prev = iter;
00071         iter = iter->next_;
00072     }
00073     printError(ErrNotFound, "There are no tuple lock in has list.");
00074     return ErrNotFound;
00075 }
00076 
00077 
00078 DbRetVal Transaction::releaseAllLocks(LockManager *lockManager_)
00079 {
00080     Database *sysdb =lockManager_->systemDatabase_;
00081     Chunk *chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
00082     TransHasNode *iter  = hasLockList_, *prev;
00083     while (NULL != iter)
00084     {
00085         prev = iter;
00086         iter = iter->next_;
00087         printDebug(DM_Transaction, "Releasing lock %x",prev->node_->ptrToTuple_);
00088         lockManager_->releaseLock(prev->node_->ptrToTuple_);
00089         chunk->free(sysdb, prev);
00090     }
00091     hasLockList_ = NULL;
00092     return OK;
00093 }
00094 bool Transaction::findInHasList(Database *sysdb, LockHashNode *node)
00095 {
00096     TransHasNode *iter  = hasLockList_;
00097     while (NULL != iter)
00098     {
00099         if (iter->node_ == node) return true;
00100         iter = iter->next_;
00101     }
00102     return false;
00103 }
00104 
00105 DbRetVal Transaction::appendUndoLog(Database *sysdb, OperationType type,
00106                                                void *data, size_t size)
00107 {
00108     DbRetVal rv =OK;
00109     UndoLogInfo *logInfo = createUndoLog(sysdb, type, data, size, &rv);
00110     if (logInfo == NULL) return rv;
00111     os::memcpy((char*)logInfo + sizeof(UndoLogInfo), data, size);
00112     addAtBegin(logInfo);
00113     printDebug(DM_Transaction, "creating undo log and append %x optype:%d",
00114                                                logInfo, type);
00115     return OK;
00116 }
00117 
00118 
00119 
00120 DbRetVal Transaction::appendLogicalUndoLog(Database *sysdb, OperationType type, void *data,
00121                        size_t size, void* indexPtr)
00122 {
00123     DbRetVal rv = OK;
00124     UndoLogInfo *logInfo = createUndoLog(sysdb, type, data, size, &rv);
00125     if (logInfo == NULL) return rv;
00126     char **indPtr = (char**)((char*)logInfo + sizeof(UndoLogInfo));
00127     *indPtr = (char*)  indexPtr;
00128     addAtBegin(logInfo);
00129     printDebug(DM_Transaction, "creating logical undo log and append %x optype:%d",
00130                                                logInfo, type);
00131     return rv;
00132 }
00133 
00134 UndoLogInfo* Transaction::createUndoLog(Database *sysdb, OperationType type, void *data,
00135                        size_t size, DbRetVal *rv)
00136 {
00137     Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
00138     UndoLogInfo *logInfo = (UndoLogInfo*)chunk->allocate(sysdb,
00139                                                 size + sizeof(UndoLogInfo), rv);
00140     if (logInfo == NULL) return NULL;
00141     logInfo->opType_ = type;
00142     logInfo->ptrToTuple_ = data;
00143     logInfo->size_ = size;
00144     logInfo->next_ = NULL;
00145     return logInfo;
00146 }
00147 
00148 void Transaction::addAtBegin(UndoLogInfo* logInfo)
00149 {
00150     //add it to the begin of the log list
00151     logInfo->next_ = firstUndoLog_;
00152     firstUndoLog_ = logInfo;
00153     return;
00154 }
00155 
00156 UndoLogInfo* Transaction::popUndoLog()
00157 {
00158     UndoLogInfo *iter = firstUndoLog_, *prev = firstUndoLog_;
00159     if(NULL != iter)
00160     {
00161         prev = iter;
00162         iter = iter->next_;
00163     }
00164     firstUndoLog_ = iter;
00165     return prev;
00166 
00167 }
00168 
00169 int Transaction::noOfUndoLogs()
00170 {
00171     UndoLogInfo *iter = firstUndoLog_;
00172     int count =0;
00173     while(NULL != iter)
00174     {
00175         count++;
00176         iter = iter->next_;
00177     }
00178     return count;
00179 }
00180 void Transaction::printDebugInfo(Database *sysdb)
00181 {
00182    printf("<TransactionInfo>\n");
00183    if (waitLock_ != NULL) 
00184    {
00185        printf("<WaitLock>");
00186        waitLock_->print();
00187        printf("</WaitLock>");
00188 
00189    }
00190    printf("<UndoLogs>\n");
00191    Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
00192    printf("  <TotalPages> %d </TotalPages>\n", chunk->totalPages());
00193    UndoLogInfo *iter = firstUndoLog_;
00194    int count =0;
00195    while(NULL != iter)
00196    {
00197       iter->print();
00198       iter = iter->next_;
00199       count++;
00200    }
00201    printf("</TotalNodes> %d </TotalNodes>\n", count);
00202    printf("</UndoLogs>\n");
00203 
00204    printf("<TransHasList>\n");
00205    chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
00206    printf("  <TotalPages> %d </TotalPages>\n", chunk->totalPages());
00207    TransHasNode *hasIter  = hasLockList_;
00208    count =0;
00209    while (NULL != hasIter)
00210    {
00211        hasIter->print();
00212        hasIter = hasIter->next_;
00213        count++;
00214    }
00215    printf("</TotalNodes> %d </TotalNodes>\n", count);
00216    printf("</TransHasList>\n");
00217 
00218    printf("</TransactionInfo>\n");
00219    return ;
00220 }
00221 DbRetVal Transaction::removeUndoLogs(Database *sysdb)
00222 {
00223     Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
00224     UndoLogInfo *logInfo = NULL;
00225     while(NULL != (logInfo = popUndoLog()))
00226     {
00227         chunk->free(sysdb, logInfo);
00228     }
00229     return OK;
00230 }
00231 
00232 
00233 DbRetVal Transaction::applyUndoLogs(Database *sysdb)
00234 {
00235     Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
00236     UndoLogInfo *logInfo = NULL;
00237     while(NULL != (logInfo = popUndoLog()))
00238     {
00239         switch(logInfo->opType_)
00240         {
00241                 case InsertOperation:
00242                 *((int*)(logInfo->ptrToTuple_) - 1) = 0;
00243                 //May memcpy is not needed as no one will update this
00244                 //as lock is taken on this tuple
00245                 os::memcpy(logInfo->ptrToTuple_, (char*) logInfo +
00246                             sizeof(UndoLogInfo), logInfo->size_);
00247                 break;
00248                 case DeleteOperation:
00249                 *((int*)(logInfo->ptrToTuple_) - 1) = 1;
00250                 os::memcpy(logInfo->ptrToTuple_, (char*) logInfo +
00251                             sizeof(UndoLogInfo), logInfo->size_);
00252                 break;
00253                 case UpdateOperation:
00254                 os::memcpy(logInfo->ptrToTuple_, (char*) logInfo +
00255                             sizeof(UndoLogInfo), logInfo->size_);
00256                 break;
00257 
00258                 case InsertHashIndexOperation:
00259                 //TODO
00260                 break;
00261                 case UpdateHashIndexOperation:
00262                //TODO
00263                break;
00264                 case DeleteHashIndexOperation:
00265                //TODO
00266                break;
00267             }
00268         chunk->free(sysdb, logInfo);
00269     }
00270     return OK;
00271 }

Generated on Mon Jun 9 22:37:15 2008 for csql by  doxygen 1.4.7