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/linkedListNTA.h"
|
||||||
#include "operations/pageOrientedListNTA.h"
|
#include "operations/pageOrientedListNTA.h"
|
||||||
#include "operations/linearHashNTA.h"
|
#include "operations/linearHashNTA.h"
|
||||||
|
#include "operations/regions.h"
|
||||||
|
|
||||||
|
|
||||||
extern Operation operationsTable[]; /* [MAX_OPERATIONS]; memset somewhere */
|
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/arrayList.c hash.c operations/linearHash.c \
|
||||||
operations/naiveLinearHash.c operations/nestedTopActions.c \
|
operations/naiveLinearHash.c operations/nestedTopActions.c \
|
||||||
operations/linearHashNTA.c operations/linkedListNTA.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
|
# logger/logMemory.c \ ringbuffer.c \ asdfas
|
||||||
#operations/lladdhash.c
|
#operations/lladdhash.c
|
||||||
|
|
|
@ -212,15 +212,12 @@ compensated_function int TpageDealloc(int xid, int pageid) {
|
||||||
rid.page = pageid;
|
rid.page = pageid;
|
||||||
rid.slot = 0;
|
rid.slot = 0;
|
||||||
rid.size = 0;
|
rid.size = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef REUSE_PAGES
|
|
||||||
assert(freelist != pageid);
|
assert(freelist != pageid);
|
||||||
t.before = freelist;
|
t.before = freelist;
|
||||||
//#endif
|
|
||||||
Tupdate(xid, rid, &freelist, OPERATION_FREE_PAGE);
|
Tupdate(xid, rid, &freelist, OPERATION_FREE_PAGE);
|
||||||
//#ifdef REUSE_PAGES
|
|
||||||
t.after = pageid;
|
t.after = pageid;
|
||||||
freelist = pageid;
|
freelist = pageid;
|
||||||
rid.page = 0;
|
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