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::releaseAllLocks(LockManager
*lockManager_
)
53 Database
*sysdb
=lockManager_
->systemDatabase_
;
54 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(TransHasTableId
);
55 TransHasNode
*iter
= hasLockList_
, *prev
;
60 printDebug(DM_Transaction
, "Releasing lock %x",prev
->node_
->ptrToTuple_
);
61 lockManager_
->releaseLock(prev
->node_
->ptrToTuple_
);
62 chunk
->free(sysdb
, prev
);
67 bool Transaction::findInHasList(Database
*sysdb
, LockHashNode
*node
)
69 TransHasNode
*iter
= hasLockList_
;
72 if (iter
->node_
== node
) return true;
78 void Transaction::appendUndoLog(Database
*sysdb
, OperationType type
,
79 void *data
, size_t size
)
81 UndoLogInfo
*logInfo
= createUndoLog(sysdb
, type
, data
, size
);
82 os::memcpy((char*)logInfo
+ sizeof(UndoLogInfo
), data
, size
);
84 printDebug(DM_Transaction
, "creating undo log and append %x optype:%d",
91 void Transaction::appendLogicalUndoLog(Database
*sysdb
, OperationType type
, void *data
,
92 size_t size
, void* indexPtr
)
94 UndoLogInfo
*logInfo
= createUndoLog(sysdb
, type
, data
, size
);
95 char **indPtr
= (char**)((char*)logInfo
+ sizeof(UndoLogInfo
));
96 *indPtr
= (char*) indexPtr
;
98 printDebug(DM_Transaction
, "creating logical undo log and append %x optype:%d",
103 UndoLogInfo
* Transaction::createUndoLog(Database
*sysdb
, OperationType type
, void *data
,
106 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
107 UndoLogInfo
*logInfo
= (UndoLogInfo
*)chunk
->allocate(sysdb
,
108 size
+ sizeof(UndoLogInfo
));
109 logInfo
->opType_
= type
;
110 logInfo
->ptrToTuple_
= data
;
111 logInfo
->size_
= size
;
112 logInfo
->next_
= NULL
;
116 void Transaction::addAtEnd(UndoLogInfo
* logInfo
)
118 //add it to the end of the log list
119 UndoLogInfo
*iter
= firstUndoLog_
;
122 firstUndoLog_
= logInfo
;
125 while(NULL
!= iter
->next_
) iter
= iter
->next_
;
126 iter
->next_
= logInfo
;
130 UndoLogInfo
* Transaction::popUndoLog()
132 UndoLogInfo
*iter
= firstUndoLog_
, *prev
= firstUndoLog_
;
138 firstUndoLog_
= iter
;
143 DbRetVal
Transaction::removeUndoLogs(Database
*sysdb
)
145 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
146 UndoLogInfo
*logInfo
= NULL
;
147 while(NULL
!= (logInfo
= popUndoLog()))
149 chunk
->free(sysdb
, logInfo
);
155 DbRetVal
Transaction::applyUndoLogs(Database
*sysdb
)
157 Chunk
*chunk
= sysdb
->getSystemDatabaseChunk(UndoLogTableID
);
158 UndoLogInfo
*logInfo
= NULL
;
159 while(NULL
!= (logInfo
= popUndoLog()))
161 switch(logInfo
->opType_
)
163 case InsertOperation
:
164 *((int*)(logInfo
->ptrToTuple_
) - 1) = 0;
165 //May memcpy is not needed as no one will update this
166 //as lock is taken on this tuple
167 os::memcpy(logInfo
->ptrToTuple_
, (char*) logInfo
+
168 sizeof(UndoLogInfo
), logInfo
->size_
);
170 case DeleteOperation
:
171 *((int*)(logInfo
->ptrToTuple_
) - 1) = 1;
172 os::memcpy(logInfo
->ptrToTuple_
, (char*) logInfo
+
173 sizeof(UndoLogInfo
), logInfo
->size_
);
175 case UpdateOperation
:
176 os::memcpy(logInfo
->ptrToTuple_
, (char*) logInfo
+
177 sizeof(UndoLogInfo
), logInfo
->size_
);
180 case InsertHashIndexOperation
:
183 case UpdateHashIndexOperation
:
186 case DeleteHashIndexOperation
:
190 chunk
->free(sysdb
, logInfo
);