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
);
27 TransHasNode
*hasNode
= (TransHasNode
*)chunk
->allocate(sysdb
);
30 printError(ErrNoMemory
, "No memory to allocate Lock node");
33 printDebug(DM_Transaction
, "insertIntoHasList new TransHasNode created:%x",
35 hasNode
->node_
= node
;
36 hasNode
->next_
= NULL
;
37 if (NULL
== hasLockList_
)
39 printDebug(DM_Transaction
, "hasLockList is null:It is now %x",hasNode
);
40 hasLockList_
= hasNode
;
44 TransHasNode
*it
= hasLockList_
;
45 while (NULL
!= it
->next_
) { it
= it
->next_
; }
47 printDebug(DM_Transaction
, "Added to hasLockList at end:%x",it
);
51 DbRetVal
Transaction::removeFromHasList(Database
*sysdb
, void *tuple
)
53 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(TransHasTableId
);
54 TransHasNode
*iter
= hasLockList_
, *prev
= hasLockList_
;
57 printError(ErrNotFound
, "There are no tuple lock in has list.");
62 if (tuple
== iter
->node_
->ptrToTuple_
)
64 prev
->next_
= iter
->next_
;
65 chunk
->free(sysdb
, iter
);
66 if (iter
== hasLockList_
) hasLockList_
= NULL
;
72 printError(ErrNotFound
, "There are no tuple lock in has list.");
77 DbRetVal
Transaction::releaseAllLocks(LockManager
*lockManager_
)
79 Database
*sysdb
=lockManager_
->systemDatabase_
;
80 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(TransHasTableId
);
81 TransHasNode
*iter
= hasLockList_
, *prev
;
86 printDebug(DM_Transaction
, "Releasing lock %x",prev
->node_
->ptrToTuple_
);
87 lockManager_
->releaseLock(prev
->node_
->ptrToTuple_
);
88 chunk
->free(sysdb
, prev
);
93 bool Transaction::findInHasList(Database
*sysdb
, LockHashNode
*node
)
95 TransHasNode
*iter
= hasLockList_
;
98 if (iter
->node_
== node
) return true;
104 DbRetVal
Transaction::appendUndoLog(Database
*sysdb
, OperationType type
,
105 void *data
, size_t size
)
107 UndoLogInfo
*logInfo
= createUndoLog(sysdb
, type
, data
, size
);
108 if (logInfo
== NULL
) return ErrNoMemory
;
109 os::memcpy((char*)logInfo
+ sizeof(UndoLogInfo
), data
, size
);
111 printDebug(DM_Transaction
, "creating undo log and append %x optype:%d",
118 DbRetVal
Transaction::appendLogicalUndoLog(Database
*sysdb
, OperationType type
, void *data
,
119 size_t size
, void* indexPtr
)
121 UndoLogInfo
*logInfo
= createUndoLog(sysdb
, type
, data
, size
);
122 if (logInfo
== NULL
) return ErrNoMemory
;
123 char **indPtr
= (char**)((char*)logInfo
+ sizeof(UndoLogInfo
));
124 *indPtr
= (char*) indexPtr
;
126 printDebug(DM_Transaction
, "creating logical undo log and append %x optype:%d",
131 UndoLogInfo
* Transaction::createUndoLog(Database
*sysdb
, OperationType type
, void *data
,
134 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
135 UndoLogInfo
*logInfo
= (UndoLogInfo
*)chunk
->allocate(sysdb
,
136 size
+ sizeof(UndoLogInfo
));
137 if (logInfo
== NULL
) return NULL
;
138 logInfo
->opType_
= type
;
139 logInfo
->ptrToTuple_
= data
;
140 logInfo
->size_
= size
;
141 logInfo
->next_
= NULL
;
145 void Transaction::addAtBegin(UndoLogInfo
* logInfo
)
147 //add it to the begin of the log list
148 logInfo
->next_
= firstUndoLog_
;
149 firstUndoLog_
= logInfo
;
153 UndoLogInfo
* Transaction::popUndoLog()
155 UndoLogInfo
*iter
= firstUndoLog_
, *prev
= firstUndoLog_
;
161 firstUndoLog_
= iter
;
166 int Transaction::noOfUndoLogs()
168 UndoLogInfo
*iter
= firstUndoLog_
;
177 void Transaction::printDebugInfo(Database
*sysdb
)
179 printf("<TransactionInfo>\n");
180 if (waitLock_
!= NULL
)
182 printf("<WaitLock>");
184 printf("</WaitLock>");
187 printf("<UndoLogs>\n");
188 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
189 printf(" <TotalPages> %d </TotalPages>\n", chunk
->totalPages());
190 UndoLogInfo
*iter
= firstUndoLog_
;
198 printf("</TotalNodes> %d </TotalNodes>\n", count
);
199 printf("</UndoLogs>\n");
201 printf("<TransHasList>\n");
202 chunk
= sysdb
->getSystemDatabaseChunk(TransHasTableId
);
203 printf(" <TotalPages> %d </TotalPages>\n", chunk
->totalPages());
204 TransHasNode
*hasIter
= hasLockList_
;
206 while (NULL
!= hasIter
)
209 hasIter
= hasIter
->next_
;
212 printf("</TotalNodes> %d </TotalNodes>\n", count
);
213 printf("</TransHasList>\n");
215 printf("</TransactionInfo>\n");
218 DbRetVal
Transaction::removeUndoLogs(Database
*sysdb
)
220 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
221 UndoLogInfo
*logInfo
= NULL
;
222 while(NULL
!= (logInfo
= popUndoLog()))
224 chunk
->free(sysdb
, logInfo
);
230 DbRetVal
Transaction::applyUndoLogs(Database
*sysdb
)
232 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
233 UndoLogInfo
*logInfo
= NULL
;
234 while(NULL
!= (logInfo
= popUndoLog()))
236 switch(logInfo
->opType_
)
238 case InsertOperation
:
239 *((int*)(logInfo
->ptrToTuple_
) - 1) = 0;
240 //May memcpy is not needed as no one will update this
241 //as lock is taken on this tuple
242 os::memcpy(logInfo
->ptrToTuple_
, (char*) logInfo
+
243 sizeof(UndoLogInfo
), logInfo
->size_
);
245 case DeleteOperation
:
246 *((int*)(logInfo
->ptrToTuple_
) - 1) = 1;
247 os::memcpy(logInfo
->ptrToTuple_
, (char*) logInfo
+
248 sizeof(UndoLogInfo
), logInfo
->size_
);
250 case UpdateOperation
:
251 os::memcpy(logInfo
->ptrToTuple_
, (char*) logInfo
+
252 sizeof(UndoLogInfo
), logInfo
->size_
);
255 case InsertHashIndexOperation
:
258 case UpdateHashIndexOperation
:
261 case DeleteHashIndexOperation
:
265 chunk
->free(sysdb
, logInfo
);