1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
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. *
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. *
15 ***************************************************************************/
16 #include<Transaction.h>
20 #include<CatalogTables.h>
23 DbRetVal
Transaction::insertIntoHasList(Database
*sysdb
, LockHashNode
*node
)
26 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(TransHasTableId
);
28 TransHasNode
*hasNode
= (TransHasNode
*)chunk
->allocate(sysdb
, &rv
);
31 printError(rv
, "Could not allocate Lock node");
34 printDebug(DM_Transaction
, "insertIntoHasList new TransHasNode created:%x",
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
;
45 TransHasNode
*it
= hasLockList_
;
46 while (NULL
!= it
->next_
) { it
= it
->next_
; }
48 printDebug(DM_Transaction
, "Added to hasLockList at end:%x",it
);
52 DbRetVal
Transaction::removeFromHasList(Database
*sysdb
, void *tuple
)
54 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(TransHasTableId
);
55 TransHasNode
*iter
= hasLockList_
, *prev
= hasLockList_
;
58 printError(ErrNotFound
, "There are no tuple lock in has list.");
63 if (tuple
== iter
->node_
->ptrToTuple_
)
65 prev
->next_
= iter
->next_
;
66 chunk
->free(sysdb
, iter
);
67 if (iter
== hasLockList_
) hasLockList_
= NULL
;
73 printError(ErrNotFound
, "There are no tuple lock in has list.");
78 DbRetVal
Transaction::releaseAllLocks(LockManager
*lockManager_
)
80 Database
*sysdb
=lockManager_
->systemDatabase_
;
81 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(TransHasTableId
);
82 TransHasNode
*iter
= hasLockList_
, *prev
;
87 printDebug(DM_Transaction
, "Releasing lock %x",prev
->node_
->ptrToTuple_
);
88 lockManager_
->releaseLock(prev
->node_
->ptrToTuple_
);
89 chunk
->free(sysdb
, prev
);
94 bool Transaction::findInHasList(Database
*sysdb
, LockHashNode
*node
)
96 TransHasNode
*iter
= hasLockList_
;
99 if (iter
->node_
== node
) return true;
105 DbRetVal
Transaction::appendUndoLog(Database
*sysdb
, OperationType type
,
106 void *data
, size_t size
)
109 UndoLogInfo
*logInfo
= createUndoLog(sysdb
, type
, data
, size
, &rv
);
110 if (logInfo
== NULL
) return rv
;
111 os::memcpy((char*)logInfo
+ sizeof(UndoLogInfo
), data
, size
);
113 printDebug(DM_Transaction
, "creating undo log and append %x optype:%d",
120 DbRetVal
Transaction::appendLogicalUndoLog(Database
*sysdb
, OperationType type
, void *data
,
121 size_t size
, void* indexPtr
)
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
;
129 printDebug(DM_Transaction
, "creating logical undo log and append %x optype:%d",
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
) {
141 printError(*rv
, "Unable to allocate undo log record\n");
144 logInfo
->opType_
= type
;
145 logInfo
->ptrToTuple_
= data
;
146 logInfo
->size_
= size
;
147 logInfo
->next_
= NULL
;
151 void Transaction::addAtBegin(UndoLogInfo
* logInfo
)
153 //add it to the begin of the log list
154 logInfo
->next_
= firstUndoLog_
;
155 firstUndoLog_
= logInfo
;
159 UndoLogInfo
* Transaction::popUndoLog()
161 UndoLogInfo
*iter
= firstUndoLog_
, *prev
= firstUndoLog_
;
167 firstUndoLog_
= iter
;
172 int Transaction::noOfUndoLogs()
174 UndoLogInfo
*iter
= firstUndoLog_
;
183 void Transaction::printDebugInfo(Database
*sysdb
)
185 printf("<TransactionInfo>\n");
186 if (waitLock_
!= NULL
)
188 printf("<WaitLock>");
190 printf("</WaitLock>");
193 printf("<UndoLogs>\n");
194 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
195 printf(" <TotalPages> %d </TotalPages>\n", chunk
->totalPages());
196 UndoLogInfo
*iter
= firstUndoLog_
;
204 printf("</TotalNodes> %d </TotalNodes>\n", count
);
205 printf("</UndoLogs>\n");
207 printf("<TransHasList>\n");
208 chunk
= sysdb
->getSystemDatabaseChunk(TransHasTableId
);
209 printf(" <TotalPages> %d </TotalPages>\n", chunk
->totalPages());
210 TransHasNode
*hasIter
= hasLockList_
;
212 while (NULL
!= hasIter
)
215 hasIter
= hasIter
->next_
;
218 printf("</TotalNodes> %d </TotalNodes>\n", count
);
219 printf("</TransHasList>\n");
221 printf("</TransactionInfo>\n");
224 DbRetVal
Transaction::removeUndoLogs(Database
*sysdb
)
226 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
227 UndoLogInfo
*logInfo
= NULL
;
228 while(NULL
!= (logInfo
= popUndoLog()))
230 chunk
->free(sysdb
, logInfo
);
236 DbRetVal
Transaction::applyUndoLogs(Database
*sysdb
)
238 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
239 UndoLogInfo
*logInfo
= NULL
;
240 while(NULL
!= (logInfo
= popUndoLog()))
242 switch(logInfo
->opType_
)
244 case InsertOperation
:
245 *((int*)(logInfo
->ptrToTuple_
) - 1) = 0;
246 //May memcpy is not needed as no one will update this
247 //as lock is taken on this tuple
248 os::memcpy(logInfo
->ptrToTuple_
, (char*) logInfo
+
249 sizeof(UndoLogInfo
), logInfo
->size_
);
251 case DeleteOperation
:
252 *((int*)(logInfo
->ptrToTuple_
) - 1) = 1;
253 os::memcpy(logInfo
->ptrToTuple_
, (char*) logInfo
+
254 sizeof(UndoLogInfo
), logInfo
->size_
);
256 case UpdateOperation
:
257 os::memcpy(logInfo
->ptrToTuple_
, (char*) logInfo
+
258 sizeof(UndoLogInfo
), logInfo
->size_
);
261 case InsertHashIndexOperation
:
264 case UpdateHashIndexOperation
:
267 case DeleteHashIndexOperation
:
271 chunk
->free(sysdb
, logInfo
);