#include <Allocator.h>
Collaboration diagram for Chunk:
Public Member Functions | |
void | setSize (size_t size) |
size_t | getSize () |
void | setChunkID (unsigned int id) |
int | getChunkID () |
void | setAllocType (AllocType type) |
AllocType | getAllocType () |
PageInfo * | getPageInfo (Database *db, void *ptr) |
void * | allocate (Database *db, DbRetVal *status=NULL) |
void * | allocate (Database *db, size_t size, DbRetVal *status=NULL) |
void | free (Database *db, void *ptr) |
ChunkIterator | getIterator () |
void | print () |
long | getTotalDataNodes () |
int | totalPages () |
int | compact () |
Friends | |
class | Database |
class | DatabaseManagerImpl |
Definition at line 95 of file Allocator.h.
Definition at line 355 of file Chunk.cxx.
References os::align(), ErrLockTimeOut, ErrNoMemory, PAGE_SIZE, printError, and Database::procSlot.
00356 { 00357 if (0 == size) return NULL; 00358 //check if the size is more than PAGE_SIZE 00359 //if it is more than the PAGE_SIZE, then allocate new 00360 //page using database and then link the curPage to the 00361 //newly allocated page 00362 //if it is less than PAGE_SIZE, then check the curpage for 00363 //free memory of specified size 00364 //if not available, then scan from the firstPage for the free 00365 //space 00366 00367 //TODO::During the scan, merge nearby nodes if both are free 00368 //if not available then allocate new page 00369 00370 size_t alignedSize = os::align(size); 00371 void *data = NULL; 00372 int ret = getChunkMutex(db->procSlot); 00373 if (ret != 0) 00374 { 00375 printError(ErrLockTimeOut,"Unable to acquire chunk Mutex"); 00376 *status = ErrLockTimeOut; 00377 return NULL; 00378 } 00379 if (alignedSize > PAGE_SIZE) 00380 { 00381 data = allocateForLargeDataSize(db, alignedSize); 00382 } 00383 else 00384 { 00385 data = allocateFromCurPageForVarSize(alignedSize); 00386 if (NULL == data) { 00387 //No available spaces in the current page. 00388 //allocate new page 00389 data= allocFromNewPageForVarSize(db, alignedSize); 00390 if (NULL == data) { 00391 printError(ErrNoMemory, "No memory in any of the pages:Increase db size"); 00392 if (status != NULL) *status = ErrNoMemory; 00393 } 00394 } 00395 } 00396 releaseChunkMutex(db->procSlot); 00397 return data; 00398 }
Here is the call graph for this function:
Definition at line 163 of file Chunk.cxx.
References DM_Alloc, ErrLockTimeOut, ErrNoMemory, os::floor(), PageInfo::hasFreeSpace_, LockTableId, PAGE_SIZE, printDebug, printError, Database::procSlot, and TransHasTableId.
Referenced by Database::allocLockHashBuckets(), Transaction::createUndoLog(), CatalogTableUSER::insert(), CatalogTableINDEXFIELD::insert(), CatalogTableINDEX::insert(), CatalogTableFIELD::insert(), CatalogTableTABLE::insert(), BucketList::insert(), and Transaction::insertIntoHasList().
00164 { 00165 PageInfo* pageInfo = ((PageInfo*)curPage_); 00166 00167 int noOfDataNodes=os::floor((PAGE_SIZE - sizeof(PageInfo))/allocSize_); 00168 char *data = ((char*)curPage_) + sizeof(PageInfo); 00169 printDebug(DM_Alloc, "Chunk::allocate id:%d curPage:%x noOfDataNodes:%d", 00170 chunkID_, curPage_, noOfDataNodes); 00171 00172 //1.scan through data list and find if any is free to use in current page 00173 //2.If there is none then 00174 // a) get new free page from db. set the prev->next to point 00175 // to this new page 00176 //4. b) initialize the free page to zero and get first data ptr. 00177 //5.If there is one, return that 00178 00179 //For allocation more than PAGE_SIZE 00180 if (0 == noOfDataNodes) 00181 { 00182 data = (char*) allocateForLargeDataSize(db); 00183 return data; 00184 } 00185 00186 int ret = getChunkMutex(db->procSlot); 00187 if (ret != 0) 00188 { 00189 if (status != NULL) *status = ErrLockTimeOut; 00190 printError(ErrLockTimeOut,"Unable to acquire chunk Mutex"); 00191 return NULL; 00192 } 00193 int i = noOfDataNodes; 00194 if (pageInfo->hasFreeSpace_ == 1) 00195 { 00196 for (i = 1; i< noOfDataNodes; i++) 00197 { 00198 if (*((int*)data) == 1) data = data + allocSize_; 00199 else break; 00200 } 00201 00202 } 00203 printDebug(DM_Alloc, "ChunkID:%d Node which might be free is %d", 00204 chunkID_, i); 00205 //It comes here if the pageInfo->hasFreeSpace ==0 00206 //or there are no free data space in this page 00207 if (i == noOfDataNodes && *((int*)data) == 1) 00208 { 00209 00210 printDebug(DM_Alloc, "ChunkID:%d curPage does not have free nodes.", chunkID_); 00211 //there are no free data space in this page 00212 pageInfo->hasFreeSpace_ = 0; 00213 if (chunkID_ == LockTableId || chunkID_ == TransHasTableId) 00214 { 00215 data = (char*) allocateFromFirstPage(db, noOfDataNodes); 00216 if (NULL == data) 00217 { 00218 data = (char*) allocateFromNewPage(db); 00219 if (data == NULL) 00220 { 00221 printError(ErrNoMemory, "No memory in any of the pages:Increase db size"); 00222 if (status != NULL) *status = ErrNoMemory; 00223 } 00224 } 00225 } 00226 else 00227 { 00228 data = (char*) allocateFromNewPage(db); 00229 if (NULL == data) 00230 { 00231 data = (char*) allocateFromFirstPage(db, noOfDataNodes); 00232 if (data == NULL) 00233 { 00234 printError(ErrNoMemory, "No memory in any of the pages:Increase db size"); 00235 if (status != NULL) *status = ErrNoMemory; 00236 } 00237 } 00238 } 00239 releaseChunkMutex(db->procSlot); 00240 return data; 00241 } 00242 *((int*)data) = 1; 00243 releaseChunkMutex(db->procSlot); 00244 return data + sizeof(int); 00245 }
Here is the call graph for this function:
Here is the caller graph for this function:
int Chunk::compact | ( | ) |
Definition at line 594 of file Chunk.cxx.
References DM_Alloc, DM_VarAlloc, os::floor(), PageInfo::isUsed_, VarSizeInfo::isUsed_, PageInfo::nextPage_, PAGE_SIZE, printDebug, and VarSizeInfo::size_.
00595 { 00596 PageInfo* pageInfo = ((PageInfo*)firstPage_); 00597 PageInfo* prevPage = pageInfo; 00598 if (NULL == pageInfo) 00599 { 00600 return 0; 00601 } 00602 pageInfo = (PageInfo*)pageInfo->nextPage_; 00603 if (0 == allocSize_) 00604 { 00605 while( pageInfo != NULL ) 00606 { 00607 bool flag = false; 00608 VarSizeInfo *varInfo = (VarSizeInfo*)(((char*)pageInfo) + 00609 sizeof(PageInfo)); 00610 while ((char*) varInfo < ((char*)pageInfo + PAGE_SIZE)) 00611 { 00612 if (1 == varInfo->isUsed_) {flag=true; break;} 00613 varInfo = (VarSizeInfo*)((char*)varInfo + sizeof(VarSizeInfo) 00614 +varInfo->size_); 00615 } 00616 if (!flag) { 00617 printDebug(DM_VarAlloc,"Freeing unused page in varsize allocator %x\n", pageInfo); 00618 prevPage->nextPage_ = pageInfo->nextPage_; 00619 pageInfo->isUsed_ = 0; 00620 } 00621 prevPage = pageInfo; 00622 pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ; 00623 printDebug(DM_VarAlloc,"compact iter %x\n", pageInfo); 00624 } 00625 }else if (allocSize_ < PAGE_SIZE) 00626 { 00627 while( pageInfo != NULL ) 00628 { 00629 bool flag = false; 00630 int noOfDataNodes=os::floor((PAGE_SIZE - sizeof(PageInfo))/allocSize_); 00631 char *data = ((char*)pageInfo) + sizeof(PageInfo); 00632 for (int i = 0; i< noOfDataNodes -1; i++) 00633 { 00634 if (1 == *((int*)data)) { flag = true; break; } 00635 data = data +allocSize_; 00636 } 00637 if (!flag) { 00638 printDebug(DM_Alloc,"Freeing unused page in fixed allocator %x\n", pageInfo); 00639 prevPage->nextPage_ = pageInfo->nextPage_; 00640 pageInfo->isUsed_ = 0; 00641 } 00642 prevPage = pageInfo; 00643 pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ; 00644 printDebug(DM_Alloc,"compact iter %x\n", pageInfo); 00645 } 00646 } 00647 return 0; 00648 }
Here is the call graph for this function:
void Chunk::free | ( | Database * | db, | |
void * | ptr | |||
) |
Definition at line 487 of file Chunk.cxx.
References ErrLockTimeOut, ErrSysFatal, os::floor(), getPageInfo(), PageInfo::hasFreeSpace_, PAGE_SIZE, printError, and Database::procSlot.
Referenced by Transaction::applyUndoLogs(), DatabaseManagerImpl::dropTable(), Transaction::releaseAllLocks(), CatalogTableUSER::remove(), CatalogTableINDEXFIELD::remove(), CatalogTableINDEX::remove(), CatalogTableFIELD::remove(), CatalogTableTABLE::remove(), BucketList::remove(), Transaction::removeFromHasList(), and Transaction::removeUndoLogs().
00488 { 00489 if (0 == allocSize_) 00490 { 00491 freeForVarSizeAllocator(ptr, db->procSlot); 00492 return; 00493 } 00494 int noOfDataNodes =os::floor((PAGE_SIZE - sizeof(PageInfo)) / allocSize_); 00495 00496 if (0 == noOfDataNodes) 00497 { 00498 freeForLargeAllocator(ptr, db->procSlot); 00499 return; 00500 } 00501 int ret = getChunkMutex(db->procSlot); 00502 if (ret != 0) 00503 { 00504 printError(ErrLockTimeOut,"Unable to acquire chunk Mutex"); 00505 return; 00506 } 00507 //below is the code for freeing in fixed size allocator 00508 00509 //unset the used flag 00510 *((int*)ptr -1 ) = 0; 00511 PageInfo *pageInfo; 00512 pageInfo = getPageInfo(db, ptr); 00513 if (NULL == pageInfo) 00514 { 00515 printError(ErrSysFatal,"Probable Data corruption: pageInfo is NULL", pageInfo ); 00516 releaseChunkMutex(db->procSlot); 00517 return; 00518 } 00519 //set the pageinfo where this ptr points 00520 pageInfo->hasFreeSpace_ = 1; 00521 releaseChunkMutex(db->procSlot); 00522 return; 00523 }
Here is the call graph for this function:
Here is the caller graph for this function:
AllocType Chunk::getAllocType | ( | ) | [inline] |
int Chunk::getChunkID | ( | ) | [inline] |
ChunkIterator Chunk::getIterator | ( | ) |
Definition at line 23 of file ChunkIterator.cxx.
References ChunkIterator::allocSize_, ChunkIterator::allocType_, ChunkIterator::chunkID_, os::floor(), ChunkIterator::iterPage_, ChunkIterator::nodeOffset_, ChunkIterator::noOfNodes_, and PAGE_SIZE.
Referenced by CatalogTableUSER::authenticate(), CatalogTableUSER::changePass(), CatalogTableINDEX::get(), CatalogTableTABLE::getChunkAndTblPtr(), CatalogTableFIELD::getFieldInfo(), CatalogTableINDEXFIELD::getFieldNameAndType(), CatalogTableFIELD::getFieldPtrs(), CatalogTableINDEX::getIndexName(), CatalogTableINDEX::getIndexPtrs(), Database::getLockHashBuckets(), CatalogTableINDEX::getNumIndexes(), CatalogTableTABLE::getTableList(), CatalogTableINDEXFIELD::insert(), CatalogTableINDEX::insert(), CatalogTableUSER::remove(), CatalogTableINDEXFIELD::remove(), CatalogTableINDEX::remove(), CatalogTableFIELD::remove(), and CatalogTableTABLE::remove().
00024 { 00025 ChunkIterator iter; 00026 iter.chunkID_ = chunkID_; 00027 iter.allocSize_ = allocSize_; 00028 iter.allocType_ = allocType_; 00029 iter.iterPage_ = firstPage_; 00030 iter.nodeOffset_ = 0; 00031 iter.noOfNodes_ = os::floor((PAGE_SIZE - sizeof(PageInfo)) / allocSize_); 00032 return iter; 00033 }
Here is the call graph for this function:
Here is the caller graph for this function:
Definition at line 530 of file Chunk.cxx.
References PageInfo::nextPage_, PageInfo::nextPageAfterMerge_, and PAGE_SIZE.
Referenced by free().
00531 { 00532 if (allocSize_ < PAGE_SIZE - sizeof(PageInfo)) { 00533 int rem = (long) ptr % 8192; 00534 return (PageInfo*)(((char*)ptr) - rem); 00535 } else { 00536 //large size allocator 00537 char *inPtr = (char*)ptr; 00538 PageInfo* pageInfo = ((PageInfo*)firstPage_); 00539 00540 while( pageInfo != NULL ) 00541 { 00542 if (inPtr > (char*) pageInfo && pageInfo->nextPageAfterMerge_ >inPtr) 00543 return pageInfo; 00544 pageInfo = (PageInfo*)pageInfo->nextPage_ ; 00545 } 00546 } 00547 return NULL; 00548 }
Here is the caller graph for this function:
size_t Chunk::getSize | ( | ) | [inline] |
Definition at line 119 of file Allocator.h.
Referenced by TableImpl::spaceUsed().
Here is the caller graph for this function:
long Chunk::getTotalDataNodes | ( | ) |
Definition at line 552 of file Chunk.cxx.
References os::floor(), VarSizeInfo::isUsed_, PAGE_SIZE, and VarSizeInfo::size_.
Referenced by DatabaseManagerImpl::printIndexInfo(), and TableImpl::spaceUsed().
00553 { 00554 long totalNodes =0; 00555 if (0 == allocSize_) //->variable size allocator 00556 { 00557 Page *page = ((PageInfo*)firstPage_); 00558 while(NULL != page) 00559 { 00560 VarSizeInfo *varInfo = (VarSizeInfo*)(((char*)page) + sizeof(PageInfo)); 00561 while ((char*) varInfo < ((char*)page + PAGE_SIZE)) 00562 { 00563 if (1 == varInfo->isUsed_) totalNodes++; 00564 varInfo = (VarSizeInfo*)((char*)varInfo + sizeof(VarSizeInfo) 00565 +varInfo->size_); 00566 } 00567 page = ((PageInfo*) page)->nextPage_; 00568 } 00569 return totalNodes; 00570 } 00571 00572 //TODO::for large size allocator 00573 if (allocSize_ >PAGE_SIZE)//->each page has only one data node 00574 return 0; 00575 00576 int noOfDataNodes=os::floor((PAGE_SIZE - sizeof(PageInfo))/allocSize_); 00577 PageInfo* pageInfo = ((PageInfo*)firstPage_); 00578 char *data = ((char*)firstPage_) + sizeof(PageInfo); 00579 int i=0; 00580 while( pageInfo != NULL ) 00581 { 00582 data = ((char*)pageInfo) + sizeof(PageInfo); 00583 for (i = 0; i< noOfDataNodes; i++) 00584 { 00585 if (*((int*)data) == 1) { totalNodes++;} 00586 data = data + allocSize_; 00587 } 00588 pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ; 00589 } 00590 return totalNodes; 00591 }
Here is the call graph for this function:
Here is the caller graph for this function:
void Chunk::print | ( | ) | [inline] |
void Chunk::setAllocType | ( | AllocType | type | ) | [inline] |
Definition at line 122 of file Allocator.h.
Referenced by Database::createSystemDatabaseChunk(), and Database::deleteSystemDatabaseChunk().
Here is the caller graph for this function:
void Chunk::setChunkID | ( | unsigned int | id | ) | [inline] |
Definition at line 120 of file Allocator.h.
Referenced by Database::createSystemDatabaseChunk(), and Database::deleteSystemDatabaseChunk().
Here is the caller graph for this function:
void Chunk::setSize | ( | size_t | size | ) |
Definition at line 28 of file Chunk.cxx.
References os::floor().
Referenced by Database::createSystemDatabaseChunk(), and Database::deleteSystemDatabaseChunk().
00029 { 00030 00031 size_t needSize = size + sizeof(int); 00032 size_t multiple = (size_t) os::floor(needSize / sizeof(size_t)); 00033 size_t rem = needSize % sizeof(size_t); 00034 if (0 == rem) 00035 allocSize_ = needSize; 00036 else 00037 allocSize_ = (multiple + 1) * sizeof(size_t); 00038 }
Here is the call graph for this function:
Here is the caller graph for this function:
int Chunk::totalPages | ( | ) |
Definition at line 650 of file Chunk.cxx.
Referenced by TableImpl::pagesUsed(), TransactionManager::printDebugInfo(), Transaction::printDebugInfo(), LockManager::printDebugInfo(), DatabaseManagerImpl::printIndexInfo(), and TableImpl::spaceUsed().
00651 { 00652 //logic is same for variable size and for large data node allocator. 00653 PageInfo* pageInfo = ((PageInfo*)firstPage_); 00654 int totPages=0; 00655 while( pageInfo != NULL ) 00656 { 00657 totPages++; 00658 pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ; 00659 } 00660 return totPages; 00661 }
Here is the caller graph for this function:
friend class Database [friend] |
Definition at line 160 of file Allocator.h.
friend class DatabaseManagerImpl [friend] |
Definition at line 161 of file Allocator.h.