added simplistic support for log reordering
This commit is contained in:
parent
45a2410a25
commit
b1f44ab005
10 changed files with 296 additions and 18 deletions
|
@ -14,6 +14,7 @@ ADD_LIBRARY(stasis crc32.c redblack.c lhtable.c rw.c doubleLinkedList.c
|
||||||
logger/inMemoryLog.c
|
logger/inMemoryLog.c
|
||||||
logger/logHandle.c logger/logger2.c
|
logger/logHandle.c logger/logger2.c
|
||||||
logger/logMemory.c page/raw.c page/slotted.c page/lsnFree.c
|
logger/logMemory.c page/raw.c page/slotted.c page/lsnFree.c
|
||||||
|
logger/reorderingHandle.c
|
||||||
page/fixed.c compensations.c
|
page/fixed.c compensations.c
|
||||||
operations/pageOperations.c page/indirect.c
|
operations/pageOperations.c page/indirect.c
|
||||||
operations/decrement.c operations/increment.c
|
operations/decrement.c operations/increment.c
|
||||||
|
|
|
@ -10,6 +10,7 @@ libstasis_la_SOURCES=crc32.c redblack.c lhtable.c rw.c doubleLinkedList.c common
|
||||||
logger/filePool.c \
|
logger/filePool.c \
|
||||||
logger/inMemoryLog.c logger/logHandle.c logger/logger2.c \
|
logger/inMemoryLog.c logger/logHandle.c logger/logger2.c \
|
||||||
logger/logMemory.c \
|
logger/logMemory.c \
|
||||||
|
logger/reorderingHandle.c \
|
||||||
page/raw.c page/slotted.c page/lsnFree.c page/fixed.c compensations.c \
|
page/raw.c page/slotted.c page/lsnFree.c page/fixed.c compensations.c \
|
||||||
operations/pageOperations.c page/indirect.c operations/decrement.c \
|
operations/pageOperations.c page/indirect.c operations/decrement.c \
|
||||||
operations/increment.c operations/prepare.c operations/set.c \
|
operations/increment.c operations/prepare.c operations/set.c \
|
||||||
|
|
101
src/stasis/logger/reorderingHandle.c
Normal file
101
src/stasis/logger/reorderingHandle.c
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
#include <stasis/transactional.h>
|
||||||
|
#include <stasis/logger/reorderingHandle.h>
|
||||||
|
#include <string.h>
|
||||||
|
static void* stasis_log_reordering_handle_worker(void * a) {
|
||||||
|
stasis_log_reordering_handle_t * h = (typeof(h))a;
|
||||||
|
pthread_mutex_lock(&h->mut);
|
||||||
|
while(h->cur_len || !h->closed) {
|
||||||
|
while(h->cur_len) {
|
||||||
|
size_t chunk_len = 0;
|
||||||
|
while(chunk_len < h->chunk_len && h->cur_len) {
|
||||||
|
LogEntry * e = LogUpdate(h->log,
|
||||||
|
h->l,
|
||||||
|
h->queue[h->cur_off].p,
|
||||||
|
h->queue[h->cur_off].op,
|
||||||
|
h->queue[h->cur_off].arg,
|
||||||
|
h->queue[h->cur_off].arg_size);
|
||||||
|
assert(e->xid != INVALID_XID);
|
||||||
|
chunk_len += sizeofLogEntry(e);
|
||||||
|
Page * p = h->queue[h->cur_off].p;
|
||||||
|
|
||||||
|
h->cur_len--;
|
||||||
|
h->cur_off = (h->cur_off+1)%h->max_len;
|
||||||
|
|
||||||
|
writelock(p->rwlatch,0);
|
||||||
|
stasis_page_lsn_write(e->xid, p, e->LSN);
|
||||||
|
unlock(p->rwlatch);
|
||||||
|
releasePage(p);
|
||||||
|
}
|
||||||
|
if(chunk_len > 0) {
|
||||||
|
lsn_t to_force = h->l->prevLSN;
|
||||||
|
pthread_mutex_unlock(&h->mut);
|
||||||
|
LogForce(h->log, to_force, LOG_FORCE_COMMIT);
|
||||||
|
pthread_mutex_lock(&h->mut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_cond_signal(&h->done);
|
||||||
|
if(!h->closed) { // XXX hack!
|
||||||
|
pthread_cond_wait(&h->ready, &h->mut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&h->mut);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stasis_log_reordering_handle_flush(stasis_log_reordering_handle_t * h) {
|
||||||
|
pthread_mutex_lock(&h->mut);
|
||||||
|
while(h->cur_len > 0) {
|
||||||
|
pthread_cond_wait(&h->done, &h->mut);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&h->mut);
|
||||||
|
}
|
||||||
|
void stasis_log_reordering_handle_close(stasis_log_reordering_handle_t * h) {
|
||||||
|
h->closed = 1;
|
||||||
|
pthread_cond_signal(&h->ready);
|
||||||
|
pthread_join(h->worker,0);
|
||||||
|
assert(h->cur_len == 0);
|
||||||
|
pthread_mutex_destroy(&h->mut);
|
||||||
|
pthread_cond_destroy(&h->ready);
|
||||||
|
pthread_cond_destroy(&h->done);
|
||||||
|
free(h->queue);
|
||||||
|
free(h);
|
||||||
|
}
|
||||||
|
stasis_log_reordering_handle_t *
|
||||||
|
stasis_log_reordering_handle_open(TransactionLog * l,
|
||||||
|
stasis_log_t* log,
|
||||||
|
size_t chunk_len,
|
||||||
|
size_t max_len) {
|
||||||
|
stasis_log_reordering_handle_t * ret = malloc(sizeof(*ret));
|
||||||
|
|
||||||
|
ret->l = l;
|
||||||
|
ret->log = log;
|
||||||
|
pthread_mutex_init(&ret->mut,0);
|
||||||
|
pthread_cond_init(&ret->done,0);
|
||||||
|
pthread_cond_init(&ret->ready,0);
|
||||||
|
ret->closed = 0;
|
||||||
|
ret->queue = malloc(sizeof(stasis_log_reordering_op_t)*max_len);
|
||||||
|
ret->chunk_len = chunk_len;
|
||||||
|
ret->max_len = max_len;
|
||||||
|
ret->cur_off = 0;
|
||||||
|
ret->cur_len = 0;
|
||||||
|
pthread_create(&ret->worker,0,stasis_log_reordering_handle_worker,ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void stasis_log_reordering_handle_append(stasis_log_reordering_handle_t * h,
|
||||||
|
Page * p,
|
||||||
|
unsigned int op,
|
||||||
|
const byte * arg,
|
||||||
|
size_t arg_size
|
||||||
|
) {
|
||||||
|
while(h->cur_len == h->max_len) {
|
||||||
|
pthread_cond_wait(&h->done, &h->mut);
|
||||||
|
}
|
||||||
|
intptr_t idx = (h->cur_off+h->cur_len)%h->max_len;
|
||||||
|
h->queue[idx].p = p;
|
||||||
|
h->queue[idx].op = op;
|
||||||
|
h->queue[idx].arg = malloc(arg_size);
|
||||||
|
memcpy(h->queue[idx].arg,arg,arg_size);
|
||||||
|
h->queue[idx].arg_size = arg_size;
|
||||||
|
h->cur_len++;
|
||||||
|
pthread_cond_signal(&h->ready);
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#include <stasis/operations.h>
|
#include <stasis/operations.h>
|
||||||
#include <stasis/page.h>
|
#include <stasis/page.h>
|
||||||
|
#include <stasis/logger/reorderingHandle.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
static int op_lsn_free_set(const LogEntry *e, Page *p) {
|
static int op_lsn_free_set(const LogEntry *e, Page *p) {
|
||||||
if(*stasis_page_type_ptr(p) != SLOTTED_LSN_FREE_PAGE) { abort() ; }
|
if(*stasis_page_type_ptr(p) != SLOTTED_LSN_FREE_PAGE) { abort() ; }
|
||||||
|
@ -24,7 +24,8 @@ static int op_lsn_free_unset(const LogEntry *e, Page *p) {
|
||||||
memcpy(p->memAddr + a[0], b+a[1], a[1]);
|
memcpy(p->memAddr + a[0], b+a[1], a[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int TsetLSNFree(int xid, recordid rid, const void * dat) {
|
int TsetLsnFreeReorderable(int xid, stasis_log_reordering_handle_t * h,
|
||||||
|
recordid rid, const void * dat) {
|
||||||
Page * p = loadPage(xid, rid.page);
|
Page * p = loadPage(xid, rid.page);
|
||||||
readlock(p->rwlatch,0);
|
readlock(p->rwlatch,0);
|
||||||
rid = stasis_record_dereference(xid,p,rid);
|
rid = stasis_record_dereference(xid,p,rid);
|
||||||
|
@ -34,6 +35,7 @@ int TsetLSNFree(int xid, recordid rid, const void * dat) {
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
abort();
|
abort();
|
||||||
unlock(p->rwlatch);
|
unlock(p->rwlatch);
|
||||||
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
rid.size = stasis_record_type_to_size(rid.size);
|
rid.size = stasis_record_type_to_size(rid.size);
|
||||||
intptr_t sz = 2 * (sizeof(pageoff_t) + rid.size);
|
intptr_t sz = 2 * (sizeof(pageoff_t) + rid.size);
|
||||||
|
@ -51,12 +53,18 @@ int TsetLSNFree(int xid, recordid rid, const void * dat) {
|
||||||
stasis_record_read(xid, p, rid, b+rid.size);
|
stasis_record_read(xid, p, rid, b+rid.size);
|
||||||
|
|
||||||
unlock(p->rwlatch);
|
unlock(p->rwlatch);
|
||||||
|
if(!h) {
|
||||||
Tupdate(xid,rid.page,buf,sz,OPERATION_SET_LSN_FREE);
|
Tupdate(xid,rid.page,buf,sz,OPERATION_SET_LSN_FREE);
|
||||||
|
} else {
|
||||||
|
TreorderableUpdate(xid,h,rid.page,buf,sz,OPERATION_SET_LSN_FREE);
|
||||||
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int TsetLsnFree(int xid, recordid rid, const void * dat) {
|
||||||
|
return TsetLsnFreeReorderable(xid, 0, rid, dat);
|
||||||
|
}
|
||||||
|
|
||||||
Operation getSetLsnFree() {
|
Operation getSetLsnFree() {
|
||||||
Operation o = {
|
Operation o = {
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
static TransactionLog XactionTable[MAX_TRANSACTIONS];
|
TransactionLog XactionTable[MAX_TRANSACTIONS];
|
||||||
static int numActiveXactions = 0;
|
static int numActiveXactions = 0;
|
||||||
static int xidCount = 0;
|
static int xidCount = 0;
|
||||||
|
|
||||||
|
@ -312,6 +312,35 @@ static compensated_function void TactionHelper(int xid,
|
||||||
unlock(p->rwlatch);
|
unlock(p->rwlatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TreorderableUpdate(int xid, void * hp, pageid_t page,
|
||||||
|
const void *dat, size_t datlen, int op) {
|
||||||
|
stasis_log_reordering_handle_t * h = (typeof(h))hp;
|
||||||
|
assert(xid >= 0 && XactionTable[xid % MAX_TRANSACTIONS].xid == xid);
|
||||||
|
Page * p = loadPage(xid, page);
|
||||||
|
try {
|
||||||
|
if(globalLockManager.writeLockPage) {
|
||||||
|
globalLockManager.writeLockPage(xid, p->id);
|
||||||
|
}
|
||||||
|
} end;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&h->mut);
|
||||||
|
|
||||||
|
// e = LogUpdate(stasis_log_file, &XactionTable[xid % MAX_TRANSACTIONS],
|
||||||
|
// p, op, dat, datlen);
|
||||||
|
stasis_log_reordering_handle_append(h, p, op, dat, datlen);
|
||||||
|
|
||||||
|
LogEntry * e = allocUpdateLogEntry(-1, h->l->xid, op,
|
||||||
|
p ? p->id : INVALID_PAGE,
|
||||||
|
dat, datlen);
|
||||||
|
e->LSN = 0;
|
||||||
|
writelock(p->rwlatch,0);
|
||||||
|
doUpdate(e, p);
|
||||||
|
unlock(p->rwlatch);
|
||||||
|
pthread_mutex_unlock(&h->mut);
|
||||||
|
releasePage(p);
|
||||||
|
freeLogEntry(e);
|
||||||
|
}
|
||||||
|
|
||||||
compensated_function void TupdateStr(int xid, pageid_t page,
|
compensated_function void TupdateStr(int xid, pageid_t page,
|
||||||
const char *dat, size_t datlen, int op) {
|
const char *dat, size_t datlen, int op) {
|
||||||
Tupdate(xid, page, dat, datlen, op);
|
Tupdate(xid, page, dat, datlen, op);
|
||||||
|
|
|
@ -55,6 +55,20 @@ terms specified in this license.
|
||||||
#ifndef __LOGGER2_H__
|
#ifndef __LOGGER2_H__
|
||||||
#define __LOGGER2_H__
|
#define __LOGGER2_H__
|
||||||
|
|
||||||
|
#include <stasis/common.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Contains the state needed by the logging layer to perform
|
||||||
|
operations on a transaction.
|
||||||
|
*/
|
||||||
|
typedef struct TransactionLog {
|
||||||
|
int xid;
|
||||||
|
lsn_t prevLSN;
|
||||||
|
lsn_t recLSN;
|
||||||
|
} TransactionLog;
|
||||||
|
|
||||||
|
typedef struct stasis_log_t stasis_log_t;
|
||||||
|
|
||||||
#include <stasis/operations.h>
|
#include <stasis/operations.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,21 +78,16 @@ terms specified in this license.
|
||||||
*/
|
*/
|
||||||
typedef int (guard_fcn_t)(const LogEntry *, void *);
|
typedef int (guard_fcn_t)(const LogEntry *, void *);
|
||||||
|
|
||||||
typedef struct stasis_log_t stasis_log_t;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LOG_FORCE_COMMIT, LOG_FORCE_WAL
|
LOG_FORCE_COMMIT, LOG_FORCE_WAL
|
||||||
} stasis_log_force_mode_t;
|
} stasis_log_force_mode_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Contains the state needed by the logging layer to perform
|
XXX TransactionTable should be private to transactional2.c!
|
||||||
operations on a transaction.
|
*/
|
||||||
*/
|
extern TransactionLog XactionTable[MAX_TRANSACTIONS];
|
||||||
typedef struct {
|
|
||||||
int xid;
|
|
||||||
lsn_t prevLSN;
|
|
||||||
lsn_t recLSN;
|
|
||||||
} TransactionLog;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This is the log implementation that is being used.
|
This is the log implementation that is being used.
|
||||||
|
|
43
stasis/logger/reorderingHandle.h
Normal file
43
stasis/logger/reorderingHandle.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef __STASIS_LOG_REORDERING_HANDLE_H
|
||||||
|
#define __STASIS_LOG_REORDERING_HANDLE_H
|
||||||
|
#include <stasis/common.h>
|
||||||
|
#include <stasis/logger/logger2.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Page * p;
|
||||||
|
unsigned int op;
|
||||||
|
byte * arg;
|
||||||
|
size_t arg_size;
|
||||||
|
} stasis_log_reordering_op_t;
|
||||||
|
|
||||||
|
typedef struct stasis_log_reordering_handle_t {
|
||||||
|
TransactionLog *l;
|
||||||
|
stasis_log_t * log;
|
||||||
|
pthread_mutex_t mut;
|
||||||
|
pthread_cond_t done;
|
||||||
|
pthread_cond_t ready;
|
||||||
|
int closed;
|
||||||
|
pthread_t worker;
|
||||||
|
stasis_log_reordering_op_t * queue;
|
||||||
|
size_t chunk_len;
|
||||||
|
size_t max_len;
|
||||||
|
size_t cur_off;
|
||||||
|
size_t cur_len;
|
||||||
|
} stasis_log_reordering_handle_t;
|
||||||
|
|
||||||
|
#include <stasis/page.h>
|
||||||
|
|
||||||
|
void stasis_log_reordering_handle_flush(stasis_log_reordering_handle_t * h);
|
||||||
|
void stasis_log_reordering_handle_close(stasis_log_reordering_handle_t * h);
|
||||||
|
stasis_log_reordering_handle_t *
|
||||||
|
stasis_log_reordering_handle_open(TransactionLog * l,
|
||||||
|
stasis_log_t* log,
|
||||||
|
size_t chunk_len,
|
||||||
|
size_t max_len);
|
||||||
|
void stasis_log_reordering_handle_append(stasis_log_reordering_handle_t * h,
|
||||||
|
Page * p,
|
||||||
|
unsigned int op,
|
||||||
|
const byte * arg,
|
||||||
|
size_t arg_size);
|
||||||
|
|
||||||
|
#endif //__STASIS_LOG_REORDERING_HANDLE_H
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef __LSN_FREE_SET_H
|
#ifndef __LSN_FREE_SET_H
|
||||||
#define __LSN_FREE_SET_H
|
#define __LSN_FREE_SET_H
|
||||||
|
#include <stasis/logger/reorderingHandle.h>
|
||||||
Operation getSetLsnFree();
|
Operation getSetLsnFree();
|
||||||
Operation getSetLsnFreeInverse();
|
Operation getSetLsnFreeInverse();
|
||||||
int TsetLSNFree(int xid, recordid rid, const void *dat);
|
int TsetLsnFree(int xid, recordid rid, const void *dat);
|
||||||
|
int TsetLsnReorderable(int xid, stasis_log_reordering_handle_t * h,
|
||||||
|
recordid rid, const void *dat);
|
||||||
#endif //__LSN_FREE_SET_H
|
#endif //__LSN_FREE_SET_H
|
||||||
|
|
|
@ -541,7 +541,6 @@ terms specified in this license.
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
|
||||||
BEGIN_C_DECLS
|
BEGIN_C_DECLS
|
||||||
|
|
||||||
//XXX doesn't belong here.
|
//XXX doesn't belong here.
|
||||||
|
@ -615,6 +614,9 @@ compensated_function void Tupdate(int xid, pageid_t page,
|
||||||
*/
|
*/
|
||||||
compensated_function void TupdateStr(int xid, pageid_t page,
|
compensated_function void TupdateStr(int xid, pageid_t page,
|
||||||
const char *dat, size_t datlen, int op);
|
const char *dat, size_t datlen, int op);
|
||||||
|
|
||||||
|
void TreorderableUpdate(int xid, void * h, pageid_t page,
|
||||||
|
const void * dat, size_t datlen, int op);
|
||||||
/**
|
/**
|
||||||
* Read the value of a record.
|
* Read the value of a record.
|
||||||
*
|
*
|
||||||
|
|
|
@ -50,6 +50,7 @@ terms specified in this license.
|
||||||
#include <stasis/page.h>
|
#include <stasis/page.h>
|
||||||
#define LOG_NAME "check_operations.log"
|
#define LOG_NAME "check_operations.log"
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -586,7 +587,7 @@ START_TEST(operation_lsn_free) {
|
||||||
int foo;
|
int foo;
|
||||||
Tread(xid[i%2],rid[i], &foo);
|
Tread(xid[i%2],rid[i], &foo);
|
||||||
assert(foo == 42);
|
assert(foo == 42);
|
||||||
TsetLSNFree(xid[i%2], rid[i], &i);
|
TsetLsnFree(xid[i%2], rid[i], &i);
|
||||||
Tread(xid[i%2],rid[i], &foo);
|
Tread(xid[i%2],rid[i], &foo);
|
||||||
assert(foo == i);
|
assert(foo == i);
|
||||||
}
|
}
|
||||||
|
@ -614,6 +615,85 @@ START_TEST(operation_lsn_free) {
|
||||||
|
|
||||||
} END_TEST
|
} END_TEST
|
||||||
|
|
||||||
|
|
||||||
|
START_TEST(operation_reorderable) {
|
||||||
|
Tinit();
|
||||||
|
recordid rid[100];
|
||||||
|
{
|
||||||
|
int xid = Tbegin();
|
||||||
|
pageid_t pid = TpageAlloc(xid);
|
||||||
|
Page * p = loadPage(xid,pid);
|
||||||
|
writelock(p->rwlatch,0);
|
||||||
|
stasis_slotted_lsn_free_initialize_page(p);
|
||||||
|
// XXX hack!
|
||||||
|
byte * old = malloc(PAGE_SIZE);
|
||||||
|
memcpy(old, p->memAddr, PAGE_SIZE);
|
||||||
|
int fortyTwo = 42;
|
||||||
|
for(int i = 0; i < 100; i++) {
|
||||||
|
rid[i] = stasis_record_alloc_begin(xid, p, sizeof(int));
|
||||||
|
stasis_record_alloc_done(xid, p, rid[i]);
|
||||||
|
stasis_record_write(xid, p, -1, rid[i], (const byte*)&fortyTwo);
|
||||||
|
}
|
||||||
|
byte * new = malloc(PAGE_SIZE);
|
||||||
|
memcpy(new, p->memAddr, PAGE_SIZE);
|
||||||
|
memcpy(p->memAddr, old, PAGE_SIZE);
|
||||||
|
unlock(p->rwlatch);
|
||||||
|
releasePage(p);
|
||||||
|
TpageSet(xid, pid, new);
|
||||||
|
free(old);
|
||||||
|
free(new);
|
||||||
|
Tcommit(xid);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int xid[2];
|
||||||
|
|
||||||
|
xid[0] = Tbegin();
|
||||||
|
xid[1] = Tbegin();
|
||||||
|
|
||||||
|
stasis_log_reordering_handle_t * rh
|
||||||
|
= stasis_log_reordering_handle_open(
|
||||||
|
&XactionTable[xid[0]% MAX_TRANSACTIONS],
|
||||||
|
stasis_log_file,
|
||||||
|
100, // bytes (far too low!)
|
||||||
|
5 // log entries
|
||||||
|
);
|
||||||
|
for(int i = 0; i < 100; i++) {
|
||||||
|
int foo;
|
||||||
|
Tread(xid[i%2],rid[i], &foo);
|
||||||
|
assert(foo == 42);
|
||||||
|
if(i%2) {
|
||||||
|
TsetLsnFree(xid[i%2], rid[i], &i);
|
||||||
|
} else {
|
||||||
|
TsetLsnFreeReorderable(xid[i%2], rh, rid[i], &i);
|
||||||
|
}
|
||||||
|
Tread(xid[i%2],rid[i], &foo);
|
||||||
|
assert(foo == i);
|
||||||
|
}
|
||||||
|
stasis_log_reordering_handle_close(rh);
|
||||||
|
Tcommit(xid[0]);
|
||||||
|
Tabort(xid[1]);
|
||||||
|
}
|
||||||
|
Tdeinit();
|
||||||
|
|
||||||
|
Tinit();
|
||||||
|
{
|
||||||
|
int xid = Tbegin();
|
||||||
|
|
||||||
|
for(int i = 0; i < 100; i++) {
|
||||||
|
int foo;
|
||||||
|
Tread(xid, rid[i], &foo);
|
||||||
|
if(i%2) {
|
||||||
|
assert(foo == 42);
|
||||||
|
} else {
|
||||||
|
assert(foo == i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tcommit(xid);
|
||||||
|
}
|
||||||
|
Tdeinit();
|
||||||
|
|
||||||
|
} END_TEST
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Add suite declarations here
|
Add suite declarations here
|
||||||
*/
|
*/
|
||||||
|
@ -634,7 +714,8 @@ Suite * check_suite(void) {
|
||||||
tcase_add_test(tc, operation_alloc_test);
|
tcase_add_test(tc, operation_alloc_test);
|
||||||
tcase_add_test(tc, operation_array_list);
|
tcase_add_test(tc, operation_array_list);
|
||||||
tcase_add_test(tc, operation_lsn_free);
|
tcase_add_test(tc, operation_lsn_free);
|
||||||
/* --------------------------------------------- */
|
tcase_add_test(tc, operation_reorderable);
|
||||||
|
/* --------------------------------------------- */
|
||||||
tcase_add_checked_fixture(tc, setup, teardown);
|
tcase_add_checked_fixture(tc, setup, teardown);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue