Started implementing the region allocator
This commit is contained in:
parent
d26263262b
commit
93e7e96ea3
5 changed files with 130 additions and 7 deletions
|
@ -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 */
|
||||
|
|
19
lladd/operations/regions.h
Normal file
19
lladd/operations/regions.h
Normal 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.
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
106
src/lladd/operations/regions.c
Normal file
106
src/lladd/operations/regions.c
Normal 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(®ion_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(®ion_mutex);
|
||||
}
|
||||
|
||||
void TregionFree(int xid, int firstPage) {
|
||||
|
||||
}
|
||||
|
||||
int TregionSize(int xid, int firstPage) {
|
||||
|
||||
}
|
||||
|
||||
Operation getRegionAlloc() {
|
||||
|
||||
}
|
||||
|
||||
Operation getRegionFree() {
|
||||
|
||||
}
|
Loading…
Reference in a new issue