Bugfix for pageOrientedList.

This commit is contained in:
Sears Russell 2005-01-31 02:18:46 +00:00
parent 1260710a27
commit a4c13449b8
4 changed files with 57 additions and 42 deletions

View file

@ -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 $
*/

View file

@ -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;

View file

@ -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;

View file

@ -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();