1959716 DMLThreadTest fails to read records sometimes
[csql.git] / src / server / Transaction.cxx
blob1e63c50eece4a5a4a6a532c9076a732179184583
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 ***************************************************************************/
16 #include<Transaction.h>
17 #include<Lock.h>
18 #include<Database.h>
19 #include<Allocator.h>
20 #include<CatalogTables.h>
21 #include<Debug.h>
23 DbRetVal Transaction::insertIntoHasList(Database *sysdb, LockHashNode *node)
25 //allocate lock node
26 Chunk *chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
27 DbRetVal rv = OK;
28 TransHasNode *hasNode = (TransHasNode*)chunk->allocate(sysdb, &rv);
29 if (NULL == hasNode)
31 printError(rv, "Could not allocate Lock node");
32 return rv;
34 printDebug(DM_Transaction, "insertIntoHasList new TransHasNode created:%x",
35 hasNode);
36 hasNode->node_ = node;
37 hasNode->next_ = NULL;
38 if (NULL == hasLockList_)
40 printDebug(DM_Transaction, "hasLockList is null:It is now %x",hasNode);
41 hasLockList_ = hasNode;
42 return OK;
45 TransHasNode *it = hasLockList_;
46 while (NULL != it->next_) { it = it->next_; }
47 it->next_ = hasNode;
48 printDebug(DM_Transaction, "Added to hasLockList at end:%x",it);
49 return OK;
52 DbRetVal Transaction::removeFromHasList(Database *sysdb, void *tuple)
54 Chunk *chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
55 TransHasNode *iter = hasLockList_, *prev = hasLockList_;
56 if (NULL == iter)
58 printError(ErrNotFound, "There are no tuple lock in has list.");
59 return ErrNotFound;
61 while (iter != NULL)
63 if (tuple == iter->node_->ptrToTuple_)
65 prev->next_ = iter->next_;
66 chunk->free(sysdb, iter);
67 if (iter == hasLockList_) hasLockList_ = NULL;
68 return OK;
70 prev = iter;
71 iter = iter->next_;
73 printError(ErrNotFound, "There are no tuple lock in has list.");
74 return ErrNotFound;
78 DbRetVal Transaction::releaseAllLocks(LockManager *lockManager_)
80 Database *sysdb =lockManager_->systemDatabase_;
81 Chunk *chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
82 TransHasNode *iter = hasLockList_, *prev;
83 while (NULL != iter)
85 prev = iter;
86 iter = iter->next_;
87 printDebug(DM_Transaction, "Releasing lock %x",prev->node_->ptrToTuple_);
88 lockManager_->releaseLock(prev->node_->ptrToTuple_);
89 chunk->free(sysdb, prev);
91 hasLockList_ = NULL;
92 return OK;
94 bool Transaction::findInHasList(Database *sysdb, LockHashNode *node)
96 TransHasNode *iter = hasLockList_;
97 while (NULL != iter)
99 if (iter->node_ == node) return true;
100 iter = iter->next_;
102 return false;
105 DbRetVal Transaction::appendUndoLog(Database *sysdb, OperationType type,
106 void *data, size_t size)
108 DbRetVal rv =OK;
109 UndoLogInfo *logInfo = createUndoLog(sysdb, type, data, size, &rv);
110 if (logInfo == NULL) return rv;
111 os::memcpy((char*)logInfo + sizeof(UndoLogInfo), data, size);
112 addAtBegin(logInfo);
113 printDebug(DM_Transaction, "creating undo log and append %x optype:%d",
114 logInfo, type);
115 return OK;
120 DbRetVal Transaction::appendLogicalUndoLog(Database *sysdb, OperationType type, void *data,
121 size_t size, void* indexPtr)
123 DbRetVal rv = OK;
124 UndoLogInfo *logInfo = createUndoLog(sysdb, type, data, size, &rv);
125 if (logInfo == NULL) return rv;
126 char **indPtr = (char**)((char*)logInfo + sizeof(UndoLogInfo));
127 *indPtr = (char*) indexPtr;
128 addAtBegin(logInfo);
129 printDebug(DM_Transaction, "creating logical undo log and append %x optype:%d",
130 logInfo, type);
131 return rv;
134 UndoLogInfo* Transaction::createUndoLog(Database *sysdb, OperationType type, void *data,
135 size_t size, DbRetVal *rv)
137 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
138 UndoLogInfo *logInfo = (UndoLogInfo*)chunk->allocate(sysdb,
139 size + sizeof(UndoLogInfo), rv);
140 if (logInfo == NULL) return NULL;
141 logInfo->opType_ = type;
142 logInfo->ptrToTuple_ = data;
143 logInfo->size_ = size;
144 logInfo->next_ = NULL;
145 return logInfo;
148 void Transaction::addAtBegin(UndoLogInfo* logInfo)
150 //add it to the begin of the log list
151 logInfo->next_ = firstUndoLog_;
152 firstUndoLog_ = logInfo;
153 return;
156 UndoLogInfo* Transaction::popUndoLog()
158 UndoLogInfo *iter = firstUndoLog_, *prev = firstUndoLog_;
159 if(NULL != iter)
161 prev = iter;
162 iter = iter->next_;
164 firstUndoLog_ = iter;
165 return prev;
169 int Transaction::noOfUndoLogs()
171 UndoLogInfo *iter = firstUndoLog_;
172 int count =0;
173 while(NULL != iter)
175 count++;
176 iter = iter->next_;
178 return count;
180 void Transaction::printDebugInfo(Database *sysdb)
182 printf("<TransactionInfo>\n");
183 if (waitLock_ != NULL)
185 printf("<WaitLock>");
186 waitLock_->print();
187 printf("</WaitLock>");
190 printf("<UndoLogs>\n");
191 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
192 printf(" <TotalPages> %d </TotalPages>\n", chunk->totalPages());
193 UndoLogInfo *iter = firstUndoLog_;
194 int count =0;
195 while(NULL != iter)
197 iter->print();
198 iter = iter->next_;
199 count++;
201 printf("</TotalNodes> %d </TotalNodes>\n", count);
202 printf("</UndoLogs>\n");
204 printf("<TransHasList>\n");
205 chunk = sysdb->getSystemDatabaseChunk(TransHasTableId);
206 printf(" <TotalPages> %d </TotalPages>\n", chunk->totalPages());
207 TransHasNode *hasIter = hasLockList_;
208 count =0;
209 while (NULL != hasIter)
211 hasIter->print();
212 hasIter = hasIter->next_;
213 count++;
215 printf("</TotalNodes> %d </TotalNodes>\n", count);
216 printf("</TransHasList>\n");
218 printf("</TransactionInfo>\n");
219 return ;
221 DbRetVal Transaction::removeUndoLogs(Database *sysdb)
223 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
224 UndoLogInfo *logInfo = NULL;
225 while(NULL != (logInfo = popUndoLog()))
227 chunk->free(sysdb, logInfo);
229 return OK;
233 DbRetVal Transaction::applyUndoLogs(Database *sysdb)
235 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
236 UndoLogInfo *logInfo = NULL;
237 while(NULL != (logInfo = popUndoLog()))
239 switch(logInfo->opType_)
241 case InsertOperation:
242 *((int*)(logInfo->ptrToTuple_) - 1) = 0;
243 //May memcpy is not needed as no one will update this
244 //as lock is taken on this tuple
245 os::memcpy(logInfo->ptrToTuple_, (char*) logInfo +
246 sizeof(UndoLogInfo), logInfo->size_);
247 break;
248 case DeleteOperation:
249 *((int*)(logInfo->ptrToTuple_) - 1) = 1;
250 os::memcpy(logInfo->ptrToTuple_, (char*) logInfo +
251 sizeof(UndoLogInfo), logInfo->size_);
252 break;
253 case UpdateOperation:
254 os::memcpy(logInfo->ptrToTuple_, (char*) logInfo +
255 sizeof(UndoLogInfo), logInfo->size_);
256 break;
258 case InsertHashIndexOperation:
259 //TODO
260 break;
261 case UpdateHashIndexOperation:
262 //TODO
263 break;
264 case DeleteHashIndexOperation:
265 //TODO
266 break;
268 chunk->free(sysdb, logInfo);
270 return OK;