Added test cases for Tprepare(), implemented some redo-only operations, and started to clean up record allocation/deallocation.

Also, numerous bugfixes.
This commit is contained in:
Sears Russell 2004-10-02 07:29:34 +00:00
parent 811bc5c710
commit 96e7af92a4
22 changed files with 558 additions and 48 deletions

View file

@ -96,7 +96,8 @@ terms specified in this license.
#define OPERATION_LHINSERT 5
#define OPERATION_LHREMOVE 6
#define OPERATION_DEALLOC 7
/*#define OPERATION_PAGE_ALLOC 8
#define OPERATION_REALLOC 8
/*#define OPERATION_PAGE_ALLOC ?
#define OPERATION_PAGE_DEALLOC 9 */
#define OPERATION_PAGE_SET 10
#define OPERATION_UPDATE_FREESPACE 11
@ -106,9 +107,10 @@ terms specified in this license.
#define OPERATION_FREE_PAGE 15
#define OPERATION_ALLOC_FREED 16
#define OPERATION_UNALLOC_FREED 17
#define OPERATION_NOOP 18
#define OPERATION_INSTANT_SET 19
/* number above should be less than number below */
#define MAX_OPERATIONS 20
#define MAX_OPERATIONS 40
/** This constant is used as a placeholder to mark slot locations that are invalid.
@see slotted.c, indirect.c

View file

@ -137,7 +137,8 @@ typedef struct {
#include "operations/lladdhash.h"
#include "operations/alloc.h"
#include "operations/pageOperations.h"
#include "operations/noop.h"
#include "operations/instantSet.h"
extern Operation operationsTable[]; /* [MAX_OPERATIONS]; memset somewhere */

View file

@ -13,6 +13,7 @@
Operation getAlloc();
Operation getDealloc();
Operation getRealloc();
/**
Allocate a record.

View file

@ -0,0 +1,62 @@
/*---
This software is copyrighted by the Regents of the University of
California, and other parties. The following terms apply to all files
associated with the software unless explicitly disclaimed in
individual files.
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose,
provided that existing copyright notices are retained in all copies
and that this notice is included verbatim in any distributions. No
written agreement, license, or royalty fee is required for any of the
authorized uses. Modifications to this software may be copyrighted by
their authors and need not follow the licensing terms described here,
provided that the new terms are clearly indicated on the first page of
each file where they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
GOVERNMENT USE: If you are acquiring this software on behalf of the
U.S. government, the Government shall have only "Restricted Rights" in
the software and related documentation as defined in the Federal
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are
acquiring the software on behalf of the Department of Defense, the
software shall be classified as "Commercial Computer Software" and the
Government shall have only "Restricted Rights" as defined in Clause
252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
authors grant the U.S. Government and others acting in its behalf
permission to use and distribute the software in accordance with the
terms specified in this license.
---*/
/**
* @file
*
* function definitions for set
*
* @ingroup OPERATIONS
*
* $Id$
*
**********************************************/
#ifndef __INSTANT_SET_H__
#define __INSTANT_SET_H__
#include <lladd/operations.h>
#define TinstantSet(xid,rid,dat) Tupdate(xid,rid,dat, OPERATION_INSTANT_SET)
Operation getInstantSet();
#endif

60
lladd/operations/noop.h Normal file
View file

@ -0,0 +1,60 @@
/*---
This software is copyrighted by the Regents of the University of
California, and other parties. The following terms apply to all files
associated with the software unless explicitly disclaimed in
individual files.
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose,
provided that existing copyright notices are retained in all copies
and that this notice is included verbatim in any distributions. No
written agreement, license, or royalty fee is required for any of the
authorized uses. Modifications to this software may be copyrighted by
their authors and need not follow the licensing terms described here,
provided that the new terms are clearly indicated on the first page of
each file where they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
GOVERNMENT USE: If you are acquiring this software on behalf of the
U.S. government, the Government shall have only "Restricted Rights" in
the software and related documentation as defined in the Federal
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are
acquiring the software on behalf of the Department of Defense, the
software shall be classified as "Commercial Computer Software" and the
Government shall have only "Restricted Rights" as defined in Clause
252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
authors grant the U.S. Government and others acting in its behalf
permission to use and distribute the software in accordance with the
terms specified in this license.
---*/
/**
* @file
*
* function definitions for set
*
* @ingroup OPERATIONS
*
* $Id$
*
**********************************************/
#ifndef __NOOP_H__
#define __NOOP_H__
#include <lladd/operations.h>
Operation getNoop();
#endif

View file

@ -87,8 +87,10 @@ extern recordid prepare_bogus_rec;
@todo Tprepare() shouldn't take a record or buffer as arguments...
@param xid Transaction id.
@param rec must be a valid record id. any valid recordid will do. This parameter will be removed eventually.
@param dat unused.
*/
#define Tprepare(xid, rec, dat) Tupdate(xid, rec, 0, OPERATION_PREPARE)
#define Tprepare(xid, rec) Tupdate(xid, rec, 0, OPERATION_PREPARE)
Operation getPrepare();
@ -97,4 +99,6 @@ Operation getPrepare();
*/
int prepareGuard(LogEntry * e, void * state);
void * getPrepareGuardState();
int prepareAction(void * state);
#endif

View file

@ -3,6 +3,12 @@
lib_LIBRARIES=liblladd.a
#liblladd_a_LIBADD=logger/liblogger.a operations/liboperations.a
# removed: recovery.c transactional.c logger.c logger/logparser.c logger/logstreamer.c
liblladd_a_SOURCES=common.c stats.c io.c bufferManager.c linkedlist.c operations.c pageFile.c pageCache.c page.c blobManager.c recovery2.c transactional2.c logger/logEntry.c logger/logWriter.c logger/logHandle.c logger/logger2.c operations/pageOperations.c page/indirect.c operations/decrement.c operations/increment.c operations/prepare.c operations/set.c operations/alloc.c page/slotted.c operations/lladdhash.c page/header.c
liblladd_a_SOURCES=common.c stats.c io.c bufferManager.c linkedlist.c operations.c \
pageFile.c pageCache.c page.c blobManager.c recovery2.c transactional2.c \
logger/logEntry.c logger/logWriter.c logger/logHandle.c logger/logger2.c \
operations/pageOperations.c page/indirect.c operations/decrement.c \
operations/increment.c operations/prepare.c operations/set.c \
operations/alloc.c operations/noop.c operations/instantSet.c \
page/slotted.c operations/lladdhash.c page/header.c
AM_CFLAGS= -g -Wall -pedantic -std=gnu99

View file

@ -101,7 +101,7 @@ void bufDeinit() {
for( p = (Page*)pblHtFirst( activePages ); p; p = (Page*)pblHtNext(activePages)) {
pblHtRemove( activePages, 0, 0 )
pblHtRemove( activePages, 0, 0 );
DEBUG("+");
/** @todo No one seems to set the dirty flag... */
/*if(p->dirty && (ret = pageWrite(p)/ *flushPage(*p)* /)) {

View file

@ -109,6 +109,10 @@ LogEntry * LogUpdate(TransactionLog * l, Page * p, recordid rid, int operation,
}
e = allocUpdateLogEntry(l->prevLSN, l->xid, operation, rid, args, argSize, preImage);
writeLogEntry(e);

View file

@ -54,7 +54,26 @@ static int operate(int xid, Page * p, lsn_t lsn, recordid rid, const void * dat)
static int deoperate(int xid, Page * p, lsn_t lsn, recordid rid, const void * dat) {
/* Page * loadedPage = loadPage(rid.page); */
/** Has no effect during normal operation, other than updating the LSN. */
/* slottedPostRalloc(p, lsn, rid); */
/* Page * loadedPage = loadPage(rid.page); */
assert(rid.page == p->id);
slottedDeRalloc(p, lsn, rid);
/* releasePage(loadedPage); */
return 0;
}
static int reoperate(int xid, Page *p, lsn_t lsn, recordid rid, const void * dat) {
/* operate(xid, p, lsn, rid, dat); */
if(rid.size >= BLOB_THRESHOLD_SIZE) {
rid.size = BLOB_REC_SIZE; /* Don't reuse blob space yet... */
}
slottedPostRalloc(p, lsn, rid);
writeRecord(xid, p, lsn, rid, dat);
return 0;
}
@ -69,6 +88,27 @@ Operation getAlloc() {
}
Operation getDealloc() {
Operation o = {
OPERATION_DEALLOC,
SIZEOF_RECORD,
OPERATION_REALLOC,
&deoperate
};
return o;
}
/*This is only used to undo deallocs... */
Operation getRealloc() {
Operation o = {
OPERATION_REALLOC,
0,
OPERATION_NOOP,
&reoperate
};
return o;
}
recordid Talloc(int xid, long size) {
recordid rid;
@ -84,18 +124,11 @@ recordid Talloc(int xid, long size) {
}
Operation getDealloc() {
Operation o = {
OPERATION_DEALLOC,
0,
OPERATION_ALLOC,
&deoperate
};
return o;
}
void Tdealloc(int xid, recordid rid) {
Tupdate(xid, rid, NULL, OPERATION_DEALLOC);
void * preimage = malloc(rid.size);
Page * p = loadPage(rid.page);
readRecord(xid, p, rid, preimage);
releasePage(p); /** @todo race in Tdealloc; do we care? */
Tupdate(xid, rid, preimage, OPERATION_DEALLOC);
free(preimage);
}

View file

@ -0,0 +1,60 @@
/*---
This software is copyrighted by the Regents of the University of
California, and other parties. The following terms apply to all files
associated with the software unless explicitly disclaimed in
individual files.
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose,
provided that existing copyright notices are retained in all copies
and that this notice is included verbatim in any distributions. No
written agreement, license, or royalty fee is required for any of the
authorized uses. Modifications to this software may be copyrighted by
their authors and need not follow the licensing terms described here,
provided that the new terms are clearly indicated on the first page of
each file where they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
GOVERNMENT USE: If you are acquiring this software on behalf of the
U.S. government, the Government shall have only "Restricted Rights" in
the software and related documentation as defined in the Federal
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are
acquiring the software on behalf of the Department of Defense, the
software shall be classified as "Commercial Computer Software" and the
Government shall have only "Restricted Rights" as defined in Clause
252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
authors grant the U.S. Government and others acting in its behalf
permission to use and distribute the software in accordance with the
terms specified in this license.
---*/
/**********************************************
* $Id$
*
* sets the given reference to dat
**********************************************/
#include <lladd/operations/instantSet.h>
#include <lladd/operations/set.h>
#include "../page.h"
/** @todo The spirit of instantSet suggests that it should hold a
shorter write lock than set, but instant set was written before
the lock manager... */
Operation getInstantSet() {
Operation o = getSet();
o.id = OPERATION_INSTANT_SET;
o.undo = OPERATION_NOOP;
return o;
}

View file

@ -63,6 +63,7 @@ int lHtValid(int xid, lladdHash_t *ht) {
} else {
ret = 1;
}
releasePage(p);
return ret;
}
/**

View file

@ -0,0 +1,64 @@
/*---
This software is copyrighted by the Regents of the University of
California, and other parties. The following terms apply to all files
associated with the software unless explicitly disclaimed in
individual files.
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose,
provided that existing copyright notices are retained in all copies
and that this notice is included verbatim in any distributions. No
written agreement, license, or royalty fee is required for any of the
authorized uses. Modifications to this software may be copyrighted by
their authors and need not follow the licensing terms described here,
provided that the new terms are clearly indicated on the first page of
each file where they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
GOVERNMENT USE: If you are acquiring this software on behalf of the
U.S. government, the Government shall have only "Restricted Rights" in
the software and related documentation as defined in the Federal
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are
acquiring the software on behalf of the Department of Defense, the
software shall be classified as "Commercial Computer Software" and the
Government shall have only "Restricted Rights" as defined in Clause
252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
authors grant the U.S. Government and others acting in its behalf
permission to use and distribute the software in accordance with the
terms specified in this license.
---*/
/**********************************************
* $Id$
*
* sets the given reference to dat
**********************************************/
#include <lladd/operations/noop.h>
#include "../page.h"
static int operate(int xid, Page *p, lsn_t lsn, recordid rid, const void *dat) {
pageWriteLSN(p, lsn);
return 0;
}
Operation getNoop() {
Operation o = {
OPERATION_NOOP,
0,
OPERATION_NOOP,
&operate
};
return o;
}

View file

@ -49,7 +49,7 @@ terms specified in this license.
#include <lladd/operations/prepare.h>
#include "../logger/logWriter.h"
#include <malloc.h>
#include <assert.h>
recordid prepare_bogus_rec = { 0, 0, 0};
static int operate(int xid, Page * p, lsn_t lsn, recordid rid, const void *dat) {
@ -61,12 +61,7 @@ Operation getPrepare() {
Operation o = {
OPERATION_PREPARE, /* id */
0, /* No extra data. */
OPERATION_PREPARE, /* If we set this to NO_INVERSE, it
will needlessly store a
pre-image of something... since
OPERATION_PREPARE just performs
a log flush, calling it during
redo is harmless. */
OPERATION_NOOP,
&operate /* Function */
};
return o;
@ -74,22 +69,46 @@ Operation getPrepare() {
/** PrepareGuardState is 1 if the iterator should continue on the next
(previous) log entry, 0 otherwise. */
typedef int PrepareGuardState;
typedef struct{
int continueIterating;
int prevLSN;
int xid;
} PrepareGuardState;
void * getPrepareGuardState() {
PrepareGuardState * s = malloc (sizeof(PrepareGuardState));
*s = 1;
s->continueIterating = 1;
s->prevLSN = -1;
s->xid = -1;
return s;
}
int prepareGuard(LogEntry * e, void * state) {
PrepareGuardState * pgs = state;
int ret = *pgs;
int ret = pgs->continueIterating;
if(e->type == UPDATELOG) {
if(e->contents.update.funcID == OPERATION_PREPARE) {
*pgs = 0;
pgs->continueIterating = 0;
pgs->prevLSN = e->prevLSN;
}
}
if(pgs->xid == -1) {
pgs->xid = e->xid;
} else {
assert(pgs->xid == e->xid);
}
return ret;
}
/** @todo When fleshing out the logHandle's prepareAction interface, figure out what the return value should mean... */
int prepareAction(
void * state) {
PrepareGuardState * pgs = state;
if(!pgs->continueIterating) {
assert(pgs->prevLSN != -1);
Trevive(pgs->xid, pgs->prevLSN);
}
return 0;
}

View file

@ -169,7 +169,7 @@ void pageCommit(int xid) {
void pageAbort(int xid) {
}
/*
static int pageAllocUnlocked() {
int ret = lastAllocedPage;
Page * p;
@ -186,7 +186,7 @@ static int pageAllocUnlocked() {
releasePage(p);
return ret;
}
}*/
/**
@todo DATA CORRUPTION BUG pageAllocMultiple needs to scan forward in the store file until

View file

@ -283,12 +283,16 @@ recordid slottedPostRalloc(Page * page, lsn_t lsn, recordid rid) {
slottedPageInitialize(page);
}
if(*slot_length_ptr(page, rid.slot) == 0 /*|| *slot_length_ptr(page, rid.slot) == -1*/) {
if((*slot_length_ptr(page, rid.slot) == 0) || (*slot_ptr(page, rid.slot) == INVALID_SLOT)) {
/* if(*slot_ptr(page, rid.slot) == INVALID_SLOT) { */
__really_do_ralloc(page, rid);
} else {
int ijk = rid.size;
int lmn = *slot_length_ptr(page, rid.slot);
assert((rid.size == *slot_length_ptr(page, rid.slot)) ||
(*slot_length_ptr(page, rid.slot) >= PAGE_SIZE));
@ -302,13 +306,16 @@ recordid slottedPostRalloc(Page * page, lsn_t lsn, recordid rid) {
}
void slottedDeRalloc(Page * page, recordid rid) {
void slottedDeRalloc(Page * page, lsn_t lsn, recordid rid) {
readlock(page->rwlatch, 443);
*slot_ptr(page, rid.slot) = INVALID_SLOT;
*slot_length_ptr(page, rid.slot) = *freelist_ptr(page);
*freelist_ptr(page) = rid.slot;
/* *slot_length_ptr(page, rid.slot) = 0; */
pageWriteLSN(page, lsn);
unlock(page->rwlatch);
}

View file

@ -111,7 +111,7 @@ recordid slottedPostRalloc(Page * page, lsn_t lsn, recordid rid);
*
* @param rid the recordid to be freed.
*/
void slottedDeRalloc(Page * page, recordid rid);
void slottedDeRalloc(Page * page, lsn_t lsn, recordid rid);
void slottedPageInit();
void slottedPageDeinit();

View file

@ -179,12 +179,13 @@ static void Undo(int recovery) {
/* printf("!"); fflush(NULL); */
prepare_guard_state = getPrepareGuardState();
while(rollbackLSNs != NULL) {
LogEntry * e;
lsn_t rollback = popMaxVal(&rollbackLSNs);
prepare_guard_state = getPrepareGuardState();
DEBUG("Undoing LSN %ld\n", (long int)rollback);
if(recovery) {
/** @todo shouldn't be hardcoded here! */
@ -250,10 +251,11 @@ static void Undo(int recovery) {
}
free(e);
}
prepareAction(prepare_guard_state);
free(prepare_guard_state);
/* printf("$"); fflush(NULL); */
}
free(prepare_guard_state);
}
void InitiateRecovery() {

View file

@ -41,6 +41,7 @@ void setupOperationsTable() {
/* operationsTable[OPERATION_LHINSERT] = getLHInsert();
operationsTable[OPERATION_LHREMOVE] = getLHRemove(); */
operationsTable[OPERATION_DEALLOC] = getDealloc();
operationsTable[OPERATION_REALLOC] = getRealloc();
/* operationsTable[OPERATION_PAGE_ALLOC] = getPageAlloc();
operationsTable[OPERATION_PAGE_DEALLOC] = getPageDealloc(); */
operationsTable[OPERATION_PAGE_SET] = getPageSet();
@ -53,7 +54,8 @@ void setupOperationsTable() {
operationsTable[OPERATION_FREE_PAGE] = getFreePageOperation();
operationsTable[OPERATION_ALLOC_FREED] = getAllocFreedPage();
operationsTable[OPERATION_UNALLOC_FREED] = getUnallocFreedPage();
operationsTable[OPERATION_NOOP] = getNoop();
operationsTable[OPERATION_INSTANT_SET] = getInstantSet();
}
@ -219,6 +221,9 @@ int Tdeinit() {
void Trevive(int xid, long lsn) {
int index = xid % MAX_TRANSACTIONS;
pthread_mutex_lock(&transactional_2_mutex);
DEBUG("Reviving xid %d at lsn %ld\n", xid, lsn);
if(XactionTable[index].xid != INVALID_XTABLE_XID) {
if(xid != XactionTable[index].xid) {
printf("Clashing Tprepare()'ed XID's encountered on recovery!!\n");

View file

@ -43,6 +43,8 @@ terms specified in this license.
#include <assert.h>
#include <lladd/transactional.h>
#include "../../src/lladd/logger/logWriter.h"
#include <lladd/bufferManager.h>
#include "../check_includes.h"
@ -51,7 +53,11 @@ terms specified in this license.
#define LOG_NAME "check_operations.log"
void simulateBufferManagerCrash();
extern int numActiveXactions;
/**
@test
Assuming that the Tset() operation is implemented correctly, checks
that doUpdate, redoUpdate and undoUpdate are working correctly, for
operations that use physical logging.
@ -197,6 +203,179 @@ START_TEST(operation_physical_do_undo) {
}
END_TEST
/**
@test check the Tprepare() call by simulating crashes.
*/
START_TEST(operation_prepare) {
/* Check this sequence prepare, action, crash, recover, read, action, abort, read again. */
Tinit();
int loser = Tbegin();
int prepared = Tbegin();
int winner = Tbegin();
recordid a = Talloc(winner, sizeof(int));
recordid b = Talloc(winner, sizeof(int));
int one =1;
int two =2;
int three=3;
Tset(winner, a, &one);
Tset(winner, b, &one);
Tset(loser, a, &three);
Tset(prepared, b, &three);
Tprepare(prepared, a);
Tset(prepared, b, &two);
Tcommit(winner);
simulateBufferManagerCrash();
closeLogWriter();
numActiveXactions = 0;
Tinit();
int in;
Tread(prepared, b, &in);
assert(in == three);
Tset(prepared, b, &two);
Tabort(prepared);
int checker = Tbegin();
Tread(checker, b, &in);
assert(in == one);
Tread(checker, a, &in);
assert(in == one);
Tcommit(checker);
Tdeinit();
/* Check this sequence prepare, action, crash, recover, read, action, _COMMIT_, read again. */
Tinit();
loser = Tbegin();
prepared = Tbegin();
winner = Tbegin();
a = Talloc(winner, sizeof(int));
b = Talloc(winner, sizeof(int));
one =1;
two =2;
three=3;
Tset(winner, a, &one);
Tset(winner, b, &one);
Tset(loser, a, &three);
Tset(prepared, b, &three);
Tprepare(prepared, a);
Tset(prepared, b, &two);
Tcommit(winner);
simulateBufferManagerCrash();
closeLogWriter();
numActiveXactions = 0;
Tinit();
Tread(prepared, b, &in);
assert(in == three);
Tset(prepared, b, &two);
Tcommit(prepared);
checker = Tbegin();
Tread(checker, b, &in);
assert(in == two);
Tread(checker, a, &in);
assert(in == one);
Tcommit(checker);
Tdeinit();
} END_TEST
/**
@test make sure the TinstantSet() operation works as expected during normal operation.
@todo need to write test for TinstantSet() for the recovery case...
*/
START_TEST(operation_instant_set) {
Tinit();
int xid = Tbegin();
recordid rid = Talloc(xid, sizeof(int)); /** @todo probably need an immediate version of TpageAlloc... */
int one = 1;
int two = 2;
int three = 3;
Tset(xid, rid, &one);
Tcommit(xid);
xid = Tbegin();
TinstantSet(xid, rid, &two);
Tset(xid, rid, &three);
Tabort(xid);
xid = Tbegin();
Tread(xid, rid, &three);
assert(two == three);
Tcommit(xid);
Tdeinit();
Tinit();
xid = Tbegin();
Tread(xid, rid, &three);
assert(two == three);
Tcommit(xid);
Tdeinit();
} END_TEST
/**
Add suite declarations here
@ -208,7 +387,8 @@ Suite * check_suite(void) {
/* Sub tests are added, one per line, here */
tcase_add_test(tc, operation_physical_do_undo);
tcase_add_test(tc, operation_instant_set);
tcase_add_test(tc, operation_prepare);
/* --------------------------------------------- */
tcase_add_checked_fixture(tc, setup, teardown);
suite_add_tcase(s, tc);

View file

@ -83,7 +83,7 @@ static void * multiple_simultaneous_pages ( void * arg_ptr) {
readRecord(1, p, rid[k], (byte*)&j);
assert((j + 1) == i + k);
slottedDeRalloc(p, rid[k]);
slottedDeRalloc(p, lsn, rid[k]);
sched_yield();
}
}
@ -123,7 +123,7 @@ static void* worker_thread(void * arg_ptr) {
if(! first ) {
readRecord(1, p, rid, (byte*)&j);
assert((j + 1) == i);
slottedDeRalloc(p, rid);
slottedDeRalloc(p, lsn, rid);
sched_yield();
}

View file

@ -177,7 +177,6 @@ START_TEST(pageOpCheckAllocDealloc) {
} END_TEST
Suite * check_suite(void) {
Suite *s = suite_create("pageOperations");
/* Begin a new test */