void coalesceIfNecessary(buffer* aBuffer) { if (aBuffer->size == 8192) { removeBufferFromFreeList(aBuffer, getFreeList(aBuffer->size)); if (debug) printf("Coalesced to max size\n"); freeListPointers* freeLists = (freeListPointers*)entryPoint->ptr; pageHeaderInfo* pageHeader = (void*)aBuffer->start - sizeof(pageHeaderInfo); if (debug) printf("The start is at %p and the page header is at %p\n", aBuffer->start, pageHeader); free_page(pageHeader->pageInfo); freeLists->numAllocatedPages--; if (freeLists->numAllocatedPages == 0) { free_page(entryPoint); entryPoint = 0; } return; } buffer* buddy = getBuddy(aBuffer); if (debug) printf("Trying to coalesce a buffer of size %i\n", aBuffer->size); if (!buddy->isAllocated && buddy->size == aBuffer->size) { freeListInfo* freeList = getFreeList(buddy->size); removeBufferFromFreeList(buddy, freeList); removeBufferFromFreeList(aBuffer, freeList); buffer* parent = buddy < aBuffer ? buddy : aBuffer; parent->size = parent->size*2; addBufferToFreeList(parent, getFreeList(parent->size)); coalesceIfNecessary(parent); } }
void splitLargerList(int size) { freeListInfo* freeList; if (size != 8192) { freeList = getFreeList(size*2); freeListInfo* smallFreeList = getFreeList(size); if (freeList->nextBuffer == 0) { if (debug) printf("Splitting %i into %i\n", size*2, size); splitLargerList(size*2); } splitLargeBufferToSmallBuffer(freeList, smallFreeList, size); return; } freeList = getFreeList(size); if (freeList->nextBuffer == 0) { kpage_t* page = get_page(); freeListPointers* freeLists = (freeListPointers*)entryPoint->ptr; freeLists->numAllocatedPages++; pageHeaderInfo* pageHeader = (pageHeaderInfo*)page->ptr; pageHeader->pageInfo = page; pageHeader->nextPage = 0; addPageToFreeList(pageHeader, freeList); void* pageBegin = page->ptr + sizeof(pageHeaderInfo); int numBuffers = (page->size - sizeof(pageHeaderInfo)) / size; numBuffers = numBuffers == 0 ? 1 : numBuffers; if (debug) printf("of size %i at %p with %i buffers\n", page->size, pageBegin, numBuffers); int i; buffer* aBuffer = 0; for (i = 0; i < numBuffers; i++) { aBuffer = (pageBegin + i * size); if (debug) printf("Buffer %i starts at %p ", i + 1, aBuffer); aBuffer->header = 0; aBuffer->start = pageBegin; aBuffer->isAllocated = 0; aBuffer->size = size; if (debug) printf("and points to %p\n", aBuffer->header); addBufferToFreeList(aBuffer, freeList); } } }
KeyPageAddr KeyFile::fetchNewPage(bool leafPage) { KeyPageAddr addr; KeyPage page(m_pageInfo); KeyPageAddr freeList = getFreeList(); if(freeList == DB_NULLADDR) { try { addr = getLast() + 1; page.init(leafPage); writePage(addr, page); setLast(addr); } catch(sqlca) { return DB_NULLADDR; } } else { try { addr = freeList; readPage(freeList, page); logPage( freeList, page); freeList = page.getNextFree(); setFreeList(freeList,-1); page.init(leafPage); writePage(addr, page); } catch(sqlca) { return DB_NULLADDR; } } return addr; }
void* kma_malloc(kma_size_t size) { if (debug) printf("\nREQUEST %i\n", size); if (entryPoint == 0) { entryPoint = getEntryPoint(); } int adjustedSize = size + sizeof(buffer); int bufferSize = getBufferSize(adjustedSize); freeListInfo* freeList = getFreeList(bufferSize); if (freeList == NULL) { return NULL; } getSpaceIfNeeded(freeList, bufferSize); return getNextBuffer(freeList); }
void KeyFile::releasePage(KeyPageAddr addr) { KeyPage page(m_pageInfo); page.setNextFree(getFreeList()); writePage(addr, page); setFreeList(addr,1); }