Bugfix for pageOrientedList.
This commit is contained in:
parent
1260710a27
commit
a4c13449b8
4 changed files with 57 additions and 42 deletions
|
@ -56,6 +56,12 @@ terms specified in this license.
|
|||
slot 0 is a long that points to the next page in the list.
|
||||
|
||||
The rest of the slots store data.
|
||||
|
||||
@todo Performance optimization for pageOrientedList: Currently, when
|
||||
the list overflows onto a new page, that page is inserted into the
|
||||
end of the list. Instead, insert this page in after the first page,
|
||||
so that subsequent inserts only have to check the first page before
|
||||
finding a (mostly) empty one.
|
||||
|
||||
$Id $
|
||||
*/
|
||||
|
|
|
@ -87,20 +87,23 @@ int TpagedListFind(int xid, recordid list, const byte * key, int keySize, byte *
|
|||
rid.slot = header.thisPage;
|
||||
|
||||
while(rid.slot || header.nextPage.size != -1) {
|
||||
rid.size = TrecordSize(xid, rid);
|
||||
|
||||
pagedListEntry * dat = malloc(rid.size);
|
||||
Tread(xid, rid, dat);
|
||||
|
||||
if(!memcmp(dat+1, key, keySize)) {
|
||||
int valueSize = rid.size - keySize - sizeof(pagedListEntry);
|
||||
*value = malloc(valueSize);
|
||||
memcpy(*value, ((byte*)(dat+1))+keySize, valueSize);
|
||||
free(dat);
|
||||
return valueSize;
|
||||
}
|
||||
if(dat->nextEntry) { // another entry on this page
|
||||
if(rid.slot) {
|
||||
rid.size = TrecordSize(xid, rid);
|
||||
pagedListEntry * dat;
|
||||
dat = malloc(rid.size);
|
||||
Tread(xid, rid, dat);
|
||||
|
||||
if(!memcmp(dat+1, key, keySize)) {
|
||||
int valueSize = rid.size - keySize - sizeof(pagedListEntry);
|
||||
*value = malloc(valueSize);
|
||||
memcpy(*value, ((byte*)(dat+1))+keySize, valueSize);
|
||||
free(dat);
|
||||
return valueSize;
|
||||
}
|
||||
// if(dat->nextEntry) { // another entry on this page
|
||||
rid.slot = dat->nextEntry;
|
||||
free(dat); // }
|
||||
} else if (header.nextPage.size != -1) { // another page
|
||||
rid.page = header.nextPage.page;
|
||||
Tread(xid, header.nextPage, &header);
|
||||
|
@ -109,7 +112,7 @@ int TpagedListFind(int xid, recordid list, const byte * key, int keySize, byte *
|
|||
rid.slot = 0;
|
||||
}
|
||||
|
||||
free(dat);
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
@ -125,43 +128,48 @@ int TpagedListRemove(int xid, recordid list, const byte * key, int keySize) {
|
|||
short lastSlot = -1;
|
||||
headerRid = list;
|
||||
while(rid.slot || header.nextPage.size != -1) {
|
||||
rid.size = TrecordSize(xid, rid);
|
||||
pagedListEntry * dat = malloc(rid.size);
|
||||
Tread(xid, rid, dat);
|
||||
|
||||
if(!memcmp(dat+1, key, keySize)) {
|
||||
|
||||
if(lastSlot != -1) {
|
||||
recordid lastRid = rid;
|
||||
lastRid.slot = lastSlot;
|
||||
lastRid.size = TrecordSize(xid, lastRid);
|
||||
pagedListEntry * lastRidBuf = malloc(lastRid.size);
|
||||
Tread(xid, lastRid, lastRidBuf);
|
||||
lastRidBuf->nextEntry = dat->nextEntry;
|
||||
Tset(xid, lastRid, lastRidBuf);
|
||||
free(lastRidBuf);
|
||||
} else {
|
||||
header.thisPage = dat->nextEntry;
|
||||
Tset(xid, headerRid, &header);
|
||||
if(rid.slot) {
|
||||
rid.size = TrecordSize(xid, rid);
|
||||
pagedListEntry * dat = malloc(rid.size);
|
||||
Tread(xid, rid, dat);
|
||||
|
||||
if(!memcmp(dat+1, key, keySize)) {
|
||||
|
||||
if(lastSlot != -1) {
|
||||
recordid lastRid = rid;
|
||||
lastRid.slot = lastSlot;
|
||||
lastRid.size = TrecordSize(xid, lastRid);
|
||||
pagedListEntry * lastRidBuf = malloc(lastRid.size);
|
||||
Tread(xid, lastRid, lastRidBuf);
|
||||
lastRidBuf->nextEntry = dat->nextEntry;
|
||||
Tset(xid, lastRid, lastRidBuf);
|
||||
free(lastRidBuf);
|
||||
} else {
|
||||
header.thisPage = dat->nextEntry;
|
||||
Tset(xid, headerRid, &header);
|
||||
}
|
||||
Tdealloc(xid, rid);
|
||||
free(dat);
|
||||
return 1;
|
||||
}
|
||||
Tdealloc(xid, rid);
|
||||
free(dat);
|
||||
return 1;
|
||||
}
|
||||
if(dat->nextEntry) { // another entry on this page
|
||||
lastSlot = rid.slot;
|
||||
rid.slot = dat->nextEntry;
|
||||
// }
|
||||
// if(dat->nextEntry) { // another entry on this page
|
||||
// lastSlot = rid.slot;
|
||||
// rid.slot = dat->nextEntry;
|
||||
free(dat);
|
||||
} else if (header.nextPage.size != -1) { // another page
|
||||
lastSlot = -1;
|
||||
rid.page = header.nextPage.page;
|
||||
headerRid = header.nextPage;
|
||||
Tread(xid, header.nextPage, &header);
|
||||
rid.slot = header.thisPage;
|
||||
} else { // we've reached the end of the last page
|
||||
rid.slot = 0;
|
||||
// } else { // we've reached the end of the last page
|
||||
// rid.slot = 0;
|
||||
}
|
||||
|
||||
free(dat);
|
||||
// free(dat);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -163,7 +163,8 @@ START_TEST(linearHashNTAVariableSizetest)
|
|||
if(!(i % (NUM_ENTRIES/10))) {
|
||||
printf("+"); fflush(stdout);
|
||||
}
|
||||
assert(sizeof(recordid) == ThashLookup(xid, hashHeader, (byte*)&i, sizeof(int), (byte**)&val2));
|
||||
int ret = ThashLookup(xid, hashHeader, (byte*)&i, sizeof(int), (byte**)&val2);
|
||||
assert(sizeof(recordid) == ret);
|
||||
assert(val2->page == i * NUM_ENTRIES);
|
||||
assert(val2->slot == val2->page * NUM_ENTRIES);
|
||||
assert(val2->size == val2->slot * NUM_ENTRIES);
|
||||
|
@ -176,7 +177,7 @@ START_TEST(linearHashNTAVariableSizetest)
|
|||
|
||||
|
||||
#define NUM_THREADS 100
|
||||
#define NUM_T_ENTRIES 1000
|
||||
#define NUM_T_ENTRIES 500
|
||||
typedef struct {
|
||||
int thread;
|
||||
recordid rid;
|
||||
|
|
|
@ -50,7 +50,7 @@ terms specified in this license.
|
|||
|
||||
#define LOG_NAME "check_pageOrientedListNTA.log"
|
||||
/** @test */
|
||||
#define NUM_ENTRIES 2000
|
||||
#define NUM_ENTRIES 3000
|
||||
START_TEST(pagedListCheck) {
|
||||
Tinit();
|
||||
|
||||
|
|
Loading…
Reference in a new issue