From ad2ea646882560a6a6299c84369677edd15e616b Mon Sep 17 00:00:00 2001 From: prabatuty Date: Fri, 11 Apr 2008 11:07:41 +0000 Subject: [PATCH] 1908554 With 1 million records DMLTest insert and delete are slow --- src/server/Chunk.cxx | 90 ++++++++++++++++++++++++++-------------------- src/server/Database.cxx | 49 +++++++++++++++---------- src/server/Transaction.cxx | 31 ++++------------ 3 files changed, 90 insertions(+), 80 deletions(-) diff --git a/src/server/Chunk.cxx b/src/server/Chunk.cxx index 6545e50d..89d07f7a 100644 --- a/src/server/Chunk.cxx +++ b/src/server/Chunk.cxx @@ -18,6 +18,7 @@ #include #include #include +#include // sets the size of the Chunk allocator for fixed size // allocator @@ -209,16 +210,31 @@ void* Chunk::allocate(Database *db, DbRetVal *status) printDebug(DM_Alloc, "ChunkID:%d curPage does not have free nodes.", chunkID_); //there are no free data space in this page pageInfo->hasFreeSpace_ = 0; - - data = (char*) allocateFromNewPage(db); - if (NULL == data) + if (chunkID_ == LockTableId || chunkID_ == TransHasTableId) { - data = (char*) allocateFromFirstPage(db, noOfDataNodes); - if (data == NULL) - { + data = (char*) allocateFromFirstPage(db, noOfDataNodes); + if (NULL == data) + { + data = (char*) allocateFromNewPage(db); + if (data == NULL) + { printError(ErrNoMemory, "No memory in any of the pages:Increase db size"); if (status != NULL) *status = ErrNoMemory; - } + } + } + } + else + { + data = (char*) allocateFromNewPage(db); + if (NULL == data) + { + data = (char*) allocateFromFirstPage(db, noOfDataNodes); + if (data == NULL) + { + printError(ErrNoMemory, "No memory in any of the pages:Increase db size"); + if (status != NULL) *status = ErrNoMemory; + } + } } releaseChunkMutex(db->procSlot); return data; @@ -277,35 +293,19 @@ void* Chunk::allocFromNewPageForVarSize(Database *db, size_t size) return NULL; } - Page *newPage = db->getFreePage(); - if (NULL == newPage) + void *vnode = varSizeFirstFitAllocate(size); + if (vnode != NULL) { - void *data = varSizeFirstFitAllocate(size); - db->releaseAllocDatabaseMutex(); - return data; + db->releaseAllocDatabaseMutex(); + return vnode; } - db->releaseAllocDatabaseMutex(); - -/* -//Do not remove the below code -//this will search from the firstPage for free slot first and then -//if it does not find, then it allocates new page. -//Need to check performance before changing the algo -void *vnode = varSizeFirstFitAllocate(size); -if (vnode != NULL) -{ - db->releaseAllocDatabaseMutex(); - return vnode; -} -Page *newPage = db->getFreePage(); -db->releaseAllocDatabaseMutex(); + Page *newPage = db->getFreePage(); + db->releaseAllocDatabaseMutex(); if (NULL == newPage) { return NULL; } -*/ - printDebug(DM_VarAlloc, "ChunkID:%d New Page: %x ", chunkID_, newPage); PageInfo *pInfo = (PageInfo*) newPage; @@ -354,7 +354,6 @@ void* Chunk::allocateFromCurPageForVarSize(size_t size) //Allocates memory to store data of variable size void* Chunk::allocate(Database *db, size_t size, DbRetVal *status) { - if (0 == size) return NULL; //check if the size is more than PAGE_SIZE //if it is more than the PAGE_SIZE, then allocate new @@ -400,6 +399,9 @@ void* Chunk::allocate(Database *db, size_t size, DbRetVal *status) //Assumes chunk mutex is already taken, before calling this void* Chunk::varSizeFirstFitAllocate(size_t size) { + printDebug(DM_VarAlloc, "Chunk::varSizeFirstFitAllocate size:%d firstPage:%x", + size, firstPage_); + Page *page = ((PageInfo*)firstPage_); size_t alignedSize = os::align(size); while(NULL != page) @@ -412,12 +414,18 @@ void* Chunk::varSizeFirstFitAllocate(size_t size) if( alignedSize < varInfo->size_) { splitDataBucket(varInfo, alignedSize); - return (char*)varInfo + sizeof(VarSizeInfo); + return ((char*)varInfo) + sizeof(VarSizeInfo); + } + else if (alignedSize == varInfo->size_) { + varInfo->isUsed_ = 1; + printDebug(DM_VarAlloc, "VarSizeFirstFitAllocate returning %x", ((char*)varInfo) +sizeof(VarSizeInfo)); + return ((char *) varInfo) + sizeof(VarSizeInfo); } } varInfo = (VarSizeInfo*)((char*)varInfo + sizeof(VarSizeInfo) +varInfo->size_); } + printDebug(DM_VarAlloc, "Chunk:This page does not have free data nodes page:%x", page); page = ((PageInfo*) page)->nextPage_; } return NULL; @@ -520,14 +528,20 @@ void Chunk::free(Database *db, void *ptr) //Note:IMPORTANT::assumes db lock is taken before calling this PageInfo* Chunk::getPageInfo(Database *db, void *ptr) { - char *inPtr = (char*)ptr; - PageInfo* pageInfo = ((PageInfo*)firstPage_); - - while( pageInfo != NULL ) - { - if (inPtr > (char*) pageInfo && ((char*)pageInfo + PAGE_SIZE) >inPtr) + if (allocSize_ < PAGE_SIZE - sizeof(PageInfo)) { + int rem = (long) ptr % 8192; + return (PageInfo*)(((char*)ptr) - rem); + } else { + //large size allocator + char *inPtr = (char*)ptr; + PageInfo* pageInfo = ((PageInfo*)firstPage_); + + while( pageInfo != NULL ) + { + if (inPtr > (char*) pageInfo && pageInfo->nextPageAfterMerge_ >inPtr) return pageInfo; - pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ; + pageInfo = (PageInfo*)pageInfo->nextPage_ ; + } } return NULL; } diff --git a/src/server/Database.cxx b/src/server/Database.cxx index 17decbff..9d55d9cc 100644 --- a/src/server/Database.cxx +++ b/src/server/Database.cxx @@ -174,35 +174,38 @@ DbRetVal Database::releaseDatabaseMutex(bool procAccount) //NOTE::IMPORTANT::assumes alloc database lock is taken before calling this Page* Database::getFreePage() { - Page* page = getFirstPage(); - printDebug(DM_Alloc, "Database::getFreePage firstPage:%x",page); + //Page* page = getFirstPage(); + Page* page = getCurrentPage(); + //printDebug(DM_Alloc, "Database::getFreePage firstPage:%x",page); + printDebug(DM_Alloc, "Database::getFreePage currentpage:%x",page); PageInfo* pageInfo = ((PageInfo*)page); - + char* endAddr = ((char*)getMetaDataPtr()) + getMaxSize(); + int pageSize = PAGE_SIZE; while( 1 == pageInfo->isUsed_) { //If any pages are merged to store data larger than PAGE_SIZE //move to the next page after the merge and check whether it is used if ( pageInfo->nextPageAfterMerge_ == NULL) { - pageInfo = (PageInfo*)((char*)pageInfo + PAGE_SIZE); + pageInfo = (PageInfo*)((char*)pageInfo + pageSize); printDebug(DM_Alloc,"Normal Page:Moving to page:%x",pageInfo); } else { pageInfo = (PageInfo*)pageInfo->nextPageAfterMerge_; printDebug(DM_Alloc,"Merged Page:Moving to page:%x",pageInfo); } - if (!isValidAddress((char*) pageInfo)) + if ((char*)pageInfo >= endAddr) { //printError(ErrSysInternal,"Invalid address %x",pageInfo); return NULL; } } - if (!isValidAddress(((char*) pageInfo) + PAGE_SIZE)) + if (!isValidAddress(((char*) pageInfo) + pageSize)) { - printError(ErrSysInternal, "Invalid address %x",((char*) pageInfo) + PAGE_SIZE); + printError(ErrSysInternal, "Invalid address %x",((char*) pageInfo) + pageSize); return NULL; } - //setCurrentPage((Page*) pageInfo); + setCurrentPage((Page*) pageInfo); printDebug(DM_Alloc,"Database::getFreePage returning page:%x",pageInfo); return (Page*) pageInfo ; } @@ -216,14 +219,15 @@ Page* Database::getFreePage(size_t size) int multiple = size / PAGE_SIZE; int offset = ((multiple + 1) * PAGE_SIZE); printDebug(DM_Alloc, "Database::getFreePage firstPage:%x size:%ld",page, size); - + char* endAddr = ((char*)getMetaDataPtr()) + getMaxSize(); + int pageSize = PAGE_SIZE; while(true){ while( 1 == pageInfo->isUsed_) { //If any pages are merged to store data larger than PAGE_SIZE //move to the next page after the merge and check whether it is used if ( pageInfo->nextPageAfterMerge_ == NULL) { - pageInfo = (PageInfo*)((char*)pageInfo + PAGE_SIZE); + pageInfo = (PageInfo*)((char*)pageInfo + pageSize); printDebug(DM_Alloc,"Normal Page:Moving to page:%x",pageInfo); } else { @@ -233,7 +237,7 @@ Page* Database::getFreePage(size_t size) } int i = 0; PageInfo *pInfo = pageInfo; - if (!isValidAddress(((char*)pInfo) + offset)) + if ((((char*)pInfo) + offset) >= endAddr) { printError(ErrSysInternal,"Invalid address %x",((char*)pInfo) + offset); return NULL; @@ -241,13 +245,13 @@ Page* Database::getFreePage(size_t size) for (i = 0; i< multiple + 1; i++) { if (1 == pInfo->isUsed_) break; - pInfo = (PageInfo*)((char*)pInfo + PAGE_SIZE); + pInfo = (PageInfo*)((char*)pInfo + pageSize); } if ( i == (multiple + 1)) break; } printDebug(DM_Alloc,"Database::getFreePage returning page:%x",pageInfo); - //setCurrentPage((Page*) pageInfo); + setCurrentPage((Page*) pageInfo); return (Page*) pageInfo ; } @@ -436,11 +440,20 @@ Transaction* Database::getSystemDatabaseTrans(int slot) //used in case of system database ThreadInfo* Database::getThreadInfo(int slot) { - size_t offset = os::alignLong(sizeof (DatabaseMetaData)); - offset = offset + os::alignLong( MAX_CHUNKS * sizeof (Chunk)); - offset = offset + os::alignLong( Conf::config.getMaxProcs() * sizeof(Transaction)); - offset = offset + slot * sizeof (ThreadInfo); - return (ThreadInfo*)(((char*) metaData_) + offset); +/* size_t offset = os::alignLong(sizeof (DatabaseMetaData)); + offset = offset + os::alignLong( MAX_CHUNKS * sizeof (Chunk)); + offset = offset + os::alignLong( Conf::config.getMaxProcs() * sizeof(Transaction)); + offset = offset + slot * sizeof (ThreadInfo); + return (ThreadInfo*)(((char*) metaData_) + offset); +*/ + + static size_t offset = os::alignLong(sizeof (DatabaseMetaData)) + + os::alignLong( MAX_CHUNKS * sizeof (Chunk)) + + os::alignLong( Conf::config.getMaxProcs()*sizeof(Transaction)); + + size_t off = offset + slot * sizeof (ThreadInfo); + return (ThreadInfo*)(((char*) metaData_) + off); + } bool Database::isValidAddress(void* addr) diff --git a/src/server/Transaction.cxx b/src/server/Transaction.cxx index 10e6f69c..4901f7e9 100644 --- a/src/server/Transaction.cxx +++ b/src/server/Transaction.cxx @@ -42,7 +42,7 @@ DbRetVal Transaction::insertIntoHasList(Database *sysdb, LockHashNode *node) } TransHasNode *it = hasLockList_; - while (NULL != it->next_) it = it->next_; + while (NULL != it->next_) { it = it->next_; } it->next_ = hasNode; printDebug(DM_Transaction, "Added to hasLockList at end:%x",it); return OK; @@ -54,40 +54,23 @@ DbRetVal Transaction::removeFromHasList(Database *sysdb, void *tuple) TransHasNode *iter = hasLockList_, *prev = hasLockList_; if (NULL == iter) { - printError(ErrNotExists, "There are no tuple lock in has list."); - return ErrNotExists; + printError(ErrNotFound, "There are no tuple lock in has list."); + return ErrNotFound; } - while (iter->next_ != NULL) + while (iter != NULL) { if (tuple == iter->node_->ptrToTuple_) { prev->next_ = iter->next_; chunk->free(sysdb, iter); + if (iter == hasLockList_) hasLockList_ = NULL; return OK; } prev = iter; iter = iter->next_; } - if( iter == hasLockList_) // there is only one node in the list - { - if (tuple == iter->node_->ptrToTuple_) - { - chunk->free(sysdb, hasLockList_); - hasLockList_ = NULL; - return OK; - } - - } - if( prev == hasLockList_) // there are only two node in the list - { - if (tuple == iter->node_->ptrToTuple_) - { - hasLockList_->next_ = NULL; - chunk->free(sysdb, iter); - return OK; - } - } - return OK; + printError(ErrNotFound, "There are no tuple lock in has list."); + return ErrNotFound; } -- 2.11.4.GIT