Started implementing the region allocator

This commit is contained in:
Sears Russell 2006-06-22 19:10:02 +00:00
parent d26263262b
commit 93e7e96ea3
5 changed files with 130 additions and 7 deletions

View file

@ -167,7 +167,7 @@ typedef struct {
#include "operations/linkedListNTA.h"
#include "operations/pageOrientedListNTA.h"
#include "operations/linearHashNTA.h"
#include "operations/regions.h"
extern Operation operationsTable[]; /* [MAX_OPERATIONS]; memset somewhere */

View file

@ -0,0 +1,19 @@
/**
Allocates and deallocates regions of pages. The page before each
region is of type BOUNDARY_TAG. All regions except the last one in
the page file have a BOUNDARY_TAG page immediately after the end of
the region.
Each region is managed by an allocation manager, which manages the
allocation of pages within a region. The contents of pages within
a newly allocated region are undefined.
*/
int TregionAlloc(int xid, int pageCount);
void TregionFree(int xid, int firstPage);
int TregionSize(int xid, int firstPage);
Operation getRegionAlloc();
Operation getRegionFree();
// XXX need callbacks to handle transaction commit/abort.

View file

@ -16,7 +16,8 @@ liblladd_a_SOURCES=crc32.c lhtable.c common.c stats.c io.c bufferManager.c linke
operations/arrayList.c hash.c operations/linearHash.c \
operations/naiveLinearHash.c operations/nestedTopActions.c \
operations/linearHashNTA.c operations/linkedListNTA.c \
operations/pageOrientedListNTA.c operations/bTree.c
operations/pageOrientedListNTA.c operations/bTree.c \
operations/regions.c
# logger/logMemory.c \ ringbuffer.c \ asdfas
#operations/lladdhash.c

View file

@ -212,15 +212,12 @@ compensated_function int TpageDealloc(int xid, int pageid) {
rid.page = pageid;
rid.slot = 0;
rid.size = 0;
#endif
#ifdef REUSE_PAGES
assert(freelist != pageid);
t.before = freelist;
//#endif
Tupdate(xid, rid, &freelist, OPERATION_FREE_PAGE);
//#ifdef REUSE_PAGES
t.after = pageid;
freelist = pageid;
rid.page = 0;

View file

@ -0,0 +1,106 @@
#include "../page.h"
#include <lladd/operations.h>
#define REGION_BASE (123)
#define REGION_VACANT (REGION_BASE + 0)
#define REGION_ZONED (REGION_BASE + 1)
#define REGION_OCCUPIED (REGION_BASE + 2)
#define REGION_CONDEMNED (REGION_BASE + 3)
#define boundary_tag_ptr(p) (((byte*)end_of_usable_space_ptr((p)))-sizeof(boundary_tag_t))
typedef struct boundary_tag_t {
int size;
int prev_size;
int status;
int region_xid;
int allocation_manager;
} boundary_tag_t;
void boundaryTagInit(Page * p) {
*page_type_ptr(p) = LLADD_BOUNDARY_TAG;
boundary_tag_t * tag = boundary_tag_ptr(p);
tag.size = INT32_MAX;
tag.prev_size = -1;
tag.status = REGION_VACANT;
tag.region_xid = INVALID_XID;
tag.allocation_manager = 0;
}
regionsInit() {
Page * p = loadPage(0);
if(*page_type_ptr(p) != LLADD_BOUNDARY_TAG) {
assert(*page_type_ptr(p) == 0);
boundaryTagInit(p);
}
releasePage(p);
}
pthread_mutex_t region_mutex = PTHREAD_MUTEX_INITIALIZER;
int TregionAlloc(int xid, int pageCount, int allocationManager) {
// Initial implementation. Naive first fit.
pthread_mutex_lock(&region_mutex);
int ret = -1;
Page * p = loadPage(0);
boundary_tag_t * t = boundary_tag_ptr(p);
while(t.status != REGION_VACANT || t.size < pageCount) { // XXX This while loop and the boundary tag manipulation below should be factored into two submodules.
int nextPage = p->id + t.size;
releasePage(p);
p = loadPage(nextPage);
t = boundary_tag_ptr(p);
}
t->status = REGION_ZONED;
t->region_xid = xid;
t->allocation_manager = allocationManager;
if(t->size != pageCount) {
// need to split region
if(t.size != INT_MAX) {
// allocate new boundary tag.
int newRegionSize = t->size - pageCount - 1; // pageCount must be strictly less than t->size, so this is safe.
Page * new_tag = loadPage(p->id + pageCount + 1);
boundaryTagInit(p);
boundary_tag_ptr(p)->size = newRegionSize;
boundary_tag_ptr(p)->prev_size = pageCount;
boundary_tag_ptr(p)->status = REGION_EPHEMERAL; // region disappears if transaction aborts; is VACANT if it succeeds. GET RID OF EPHEMERAL; just make it vacant, and merge on abort.
boundary_tag_ptr(p)->region_xid = xid;
boundary_tag_ptr(p)->allocation_manager = 0;
releasePage(new_tag);
Page * next = loadPage(p->id + t.size + 1);
boundary_tag_ptr(next)->prev_size = newRegionSize;
releasePage(next);
} else {
Page * new_tag = loadPage(p->id + pageCount + 1);
boundaryTagInit(p);
boundary_tag_ptr(p)->size = INT_MAX;
boundary_tag_ptr(p)->prev_size = pageCount;
boundary_tag_ptr(p)->status = REGION_EPHEMERAL;
boundary_tag_ptr(p)->region_xid = xid;
boundary_tag_ptr(p)->allocation_manager = 0;
}
}
releasePage(p);
pthread_mutex_unlock(&region_mutex);
}
void TregionFree(int xid, int firstPage) {
}
int TregionSize(int xid, int firstPage) {
}
Operation getRegionAlloc() {
}
Operation getRegionFree() {
}