00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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
00244
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
00260 break;
00261 case UpdateHashIndexOperation:
00262
00263 break;
00264 case DeleteHashIndexOperation:
00265
00266 break;
00267 }
00268 chunk->free(sysdb, logInfo);
00269 }
00270 return OK;
00271 }