2004-10-06 06:08:09 +00:00
|
|
|
#include "../page.h"
|
|
|
|
|
|
|
|
#include "fixed.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
|
|
|
|
int recordsPerPage(size_t size) {
|
|
|
|
return (USABLE_SIZE_OF_PAGE - 2*sizeof(short)) / size;
|
|
|
|
}
|
2005-02-02 02:12:40 +00:00
|
|
|
/** @todo CORRECTNESS Locking for fixedPageInitialize? (should hold writelock)*/
|
2004-10-06 06:08:09 +00:00
|
|
|
void fixedPageInitialize(Page * page, size_t size, int count) {
|
|
|
|
assert(*page_type_ptr(page) == UNINITIALIZED_PAGE);
|
|
|
|
*page_type_ptr(page) = FIXED_PAGE;
|
|
|
|
*recordsize_ptr(page) = size;
|
|
|
|
assert(count <= recordsPerPage(size));
|
|
|
|
*recordcount_ptr(page)= count;
|
|
|
|
}
|
|
|
|
|
|
|
|
short fixedPageCount(Page * page) {
|
2007-06-01 21:32:33 +00:00
|
|
|
assertlocked(page->rwlatch);
|
2004-10-06 06:08:09 +00:00
|
|
|
assert(*page_type_ptr(page) == FIXED_PAGE || *page_type_ptr(page) == ARRAY_LIST_PAGE);
|
|
|
|
return *recordcount_ptr(page);
|
|
|
|
}
|
|
|
|
|
|
|
|
short fixedPageRecordSize(Page * page) {
|
2007-06-01 21:32:33 +00:00
|
|
|
assertlocked(page->rwlatch);
|
2004-10-06 06:08:09 +00:00
|
|
|
assert(*page_type_ptr(page) == FIXED_PAGE || *page_type_ptr(page) == ARRAY_LIST_PAGE);
|
|
|
|
return *recordsize_ptr(page);
|
|
|
|
}
|
|
|
|
|
|
|
|
recordid fixedRawRallocMany(Page * page, int count) {
|
|
|
|
|
|
|
|
assert(*page_type_ptr(page) == FIXED_PAGE);
|
|
|
|
recordid rid;
|
2005-02-02 02:12:40 +00:00
|
|
|
/* We need a writelock to prevent concurrent updates to the recordcount_ptr field. */
|
2004-10-06 06:08:09 +00:00
|
|
|
writelock(page->rwlatch, 33);
|
|
|
|
if(*recordcount_ptr(page) + count <= recordsPerPage(*recordsize_ptr(page))) {
|
|
|
|
rid.page = page->id;
|
|
|
|
rid.slot = *recordcount_ptr(page);
|
|
|
|
rid.size = *recordsize_ptr(page);
|
|
|
|
*recordcount_ptr(page)+=count;
|
|
|
|
} else {
|
|
|
|
rid.page = -1;
|
|
|
|
rid.slot = -1;
|
|
|
|
rid.size = -1;
|
|
|
|
}
|
|
|
|
unlock(page->rwlatch);
|
|
|
|
|
|
|
|
return rid;
|
|
|
|
}
|
|
|
|
|
|
|
|
recordid fixedRawRalloc(Page *page) {
|
|
|
|
assert(*page_type_ptr(page) == FIXED_PAGE);
|
|
|
|
return fixedRawRallocMany(page, 1);
|
|
|
|
}
|
|
|
|
|
2007-06-01 21:32:33 +00:00
|
|
|
static int checkRidWarnedAboutUninitializedKludge = 0;
|
2004-10-06 06:08:09 +00:00
|
|
|
static void checkRid(Page * page, recordid rid) {
|
2007-06-01 21:32:33 +00:00
|
|
|
assertlocked(page->rwlatch);
|
2004-10-19 04:45:42 +00:00
|
|
|
if(*page_type_ptr(page)) {
|
|
|
|
assert(*page_type_ptr(page) == FIXED_PAGE || *page_type_ptr(page) == ARRAY_LIST_PAGE);
|
|
|
|
assert(page->id == rid.page);
|
|
|
|
assert(*recordsize_ptr(page) == rid.size);
|
2004-10-19 21:16:37 +00:00
|
|
|
// assert(recordsPerPage(rid.size) > rid.slot);
|
2004-10-19 04:45:42 +00:00
|
|
|
int recCount = *recordcount_ptr(page);
|
2004-10-19 21:16:37 +00:00
|
|
|
assert(recCount > rid.slot);
|
2004-10-19 04:45:42 +00:00
|
|
|
} else {
|
2007-06-01 22:20:25 +00:00
|
|
|
if(!checkRidWarnedAboutUninitializedKludge) {
|
|
|
|
checkRidWarnedAboutUninitializedKludge = 1;
|
|
|
|
printf("KLUDGE detected in checkRid. Fix it ASAP\n");
|
|
|
|
}
|
2004-10-19 04:45:42 +00:00
|
|
|
fixedPageInitialize(page, rid.size, recordsPerPage(rid.size));
|
|
|
|
}
|
2004-10-06 06:08:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void fixedReadUnlocked(Page * page, recordid rid, byte * buf) {
|
2007-06-01 21:32:33 +00:00
|
|
|
assertlocked(page->rwlatch);
|
2007-06-01 22:20:25 +00:00
|
|
|
checkRid(page, rid);
|
2004-10-06 06:08:09 +00:00
|
|
|
if(!memcpy(buf, fixed_record_ptr(page, rid.slot), rid.size)) {
|
|
|
|
perror("memcpy");
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void fixedRead(Page * page, recordid rid, byte * buf) {
|
|
|
|
readlock(page->rwlatch, 57);
|
2004-10-19 21:16:37 +00:00
|
|
|
|
|
|
|
// printf("R { %d %d %d }\n", rid.page, rid.slot, rid.size);
|
2004-10-06 06:08:09 +00:00
|
|
|
checkRid(page, rid);
|
|
|
|
|
2004-10-19 21:16:37 +00:00
|
|
|
|
|
|
|
|
2004-10-06 06:08:09 +00:00
|
|
|
fixedReadUnlocked(page, rid, buf);
|
|
|
|
|
|
|
|
unlock(page->rwlatch);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void fixedWriteUnlocked(Page * page, recordid rid, const byte *dat) {
|
2007-06-01 21:32:33 +00:00
|
|
|
assertlocked(page->rwlatch);
|
2004-10-19 21:16:37 +00:00
|
|
|
checkRid(page,rid);
|
2004-10-06 06:08:09 +00:00
|
|
|
if(!memcpy(fixed_record_ptr(page, rid.slot), dat, rid.size)) {
|
|
|
|
perror("memcpy");
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void fixedWrite(Page * page, recordid rid, const byte* dat) {
|
|
|
|
readlock(page->rwlatch, 73);
|
|
|
|
|
2004-10-19 21:16:37 +00:00
|
|
|
// printf("W { %d %d %d }\n", rid.page, rid.slot, rid.size);
|
|
|
|
// checkRid(page, rid);
|
2004-10-06 06:08:09 +00:00
|
|
|
|
|
|
|
fixedWriteUnlocked(page, rid, dat);
|
|
|
|
|
|
|
|
unlock(page->rwlatch);
|
|
|
|
}
|