code reorg
[csql.git] / src / storage / Chunk.cxx
blobb23f83cabe9ea049ac21dc0ae068109784226f43
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 ***************************************************************************/
16 #include<Allocator.h>
17 #include<Database.h>
18 #include<os.h>
19 #include<Debug.h>
20 #include<Config.h>
21 #include<CatalogTables.h>
23 // sets the size of the Chunk allocator for fixed size
24 // allocator
25 // we need one integer to store book keeping information
26 // whether the storage allocation unit is used of not
27 // when it is deleted this flag is only set to unused
28 void Chunk::setSize(size_t size)
31 size_t needSize = size + sizeof(InUse);
32 size_t multiple = (size_t) os::floor(needSize / sizeof(size_t));
33 size_t rem = needSize % sizeof(size_t);
34 if (0 == rem)
35 allocSize_ = needSize;
36 else
37 allocSize_ = (multiple + 1) * sizeof(size_t);
40 void* Chunk::allocateForLargeDataSize(Database *db)
42 PageInfo* pageInfo = ((PageInfo*)curPage_);
43 DbRetVal ret = db->getAllocDatabaseMutex();
44 if (ret != 0)
46 printError(ErrLockTimeOut,"Unable to acquire alloc database Mutex");
47 return NULL;
50 //check whether we have space in curPage
51 if (BITSET(pageInfo->flags, HAS_SPACE))
53 char *data = ((char*)curPage_) + sizeof(PageInfo);
54 InUse oldVal = pageInfo->flags;
55 InUse newVal = oldVal;
56 CLEARBIT(newVal, HAS_SPACE);
57 int retVal = Mutex::CASGen(&pageInfo->flags, oldVal, newVal);
58 if (retVal !=0) printError(ErrSysFatal, "Unable to set flags");
59 *((InUse*)data) = 1;
60 db->releaseAllocDatabaseMutex();
61 return data + sizeof(InUse);
64 //no space in curpage , get new page from database
65 pageInfo = (PageInfo*)db->getFreePage(allocSize_);
66 if (NULL == pageInfo)
68 db->releaseAllocDatabaseMutex();
69 printError(ErrNoMemory,"No more free pages in the database");
70 return NULL;
72 printDebug(DM_Alloc, "Chunk ID:%d Large Data Item newPage:%x",
73 chunkID_, pageInfo);
74 int multiple = (int) os::floor(allocSize_ / PAGE_SIZE);
75 int offset = ((multiple + 1) * PAGE_SIZE);
77 pageInfo->setPageAsUsed(offset);
78 setPageDirty(pageInfo);
81 //create the link
82 //((PageInfo*)curPage_)->nextPage_ = (Page*) pageInfo;
83 int retVal = Mutex::CASL((long*) &(((PageInfo*)curPage_)->nextPage_),
84 (long)(((PageInfo*)curPage_)->nextPage_), (long)pageInfo);
85 if(retVal !=0) {
86 printError(ErrLockTimeOut, "Fatal: Unable to create page link.");
89 //Make this as current page
90 //curPage_ = (Page*) pageInfo;
91 retVal = Mutex::CASL((long*) &curPage_, (long)curPage_, (long)pageInfo);
92 if(retVal !=0) {
93 printError(ErrLockTimeOut, "Fatal:Unable to set current page");
96 char* data = ((char*)curPage_) + sizeof(PageInfo);
97 InUse oldVal = pageInfo->flags;
98 InUse newVal = oldVal;
99 CLEARBIT(newVal, HAS_SPACE);
100 retVal = Mutex::CASGen(&pageInfo->flags, oldVal, newVal);
101 if(retVal !=0) {
102 printError(ErrLockTimeOut, "Fatal:Unable to set flags");
104 *((InUse*)data) = 1;
105 db->releaseAllocDatabaseMutex();
106 return data + sizeof(InUse);
110 void* Chunk::allocateFromFirstPage(Database *db, int noOfDataNodes, DbRetVal *status)
112 PageInfo *pageIter = ((PageInfo*)firstPage_);
113 printDebug(DM_Alloc, "Chunk ID:%d. No free page in database",
114 chunkID_);
115 printDebug(DM_Alloc, "Scan from firstPage:%x for free nodes",
116 firstPage_);
117 char *data = NULL;
118 int i = 0;
119 //scan from first page to locate a free node available
120 while(NULL != pageIter)
122 data = ((char*)pageIter) + sizeof(PageInfo);
123 if (BITSET(pageIter->flags, HAS_SPACE))
125 for (i = 0; i< noOfDataNodes ; i++)
127 if (1 == *((InUse*)data))
128 data = data + allocSize_;
129 else break;
131 if (i != noOfDataNodes) break;
133 printDebug(DM_Alloc, "Chunk ID: %d Page :%x does not have free nodes",
134 chunkID_, pageIter);
135 pageIter = (PageInfo*)((PageInfo*) pageIter)->nextPage_;
137 if (NULL == pageIter) {
138 *status = ErrNoMemory;
139 return NULL;
141 printDebug(DM_Alloc,"ChunkID:%d Scan for free node End:Page :%x",
142 chunkID_, pageIter);
143 int ret = Mutex::CASGen(data, 0, 1);
144 if(ret !=0) {
145 *status = ErrLockTimeOut;
146 //printError(ErrLockTimeOut, "Unable to allocate from first page. Retry...");
147 return NULL;
149 setPageDirty(pageIter);
150 return data + sizeof(InUse);
153 void* Chunk::allocateFromNewPage(Database *db, DbRetVal *status)
155 DbRetVal ret = db->getAllocDatabaseMutex();
156 if (ret != 0)
158 printDebug(DM_Warning,"Unable to acquire alloc database Mutex Chunkid:%d", chunkID_);
159 *status = ErrLockTimeOut;
160 return NULL;
162 //get a new page from db
163 Page *page = db->getFreePage();
164 if (page == NULL) {
165 printError(ErrNoMemory, "Unable to allocate page");
166 db->releaseAllocDatabaseMutex();
167 *status = ErrNoMemory;
168 return NULL;
170 printDebug(DM_Alloc, "ChunkID:%d Normal Data Item newPage:%x",
171 chunkID_, page);
172 //Initialize pageInfo for this new page
173 PageInfo *pInfo = (PageInfo*)page;
174 pInfo->setPageAsUsed(0);
175 setPageDirty(pInfo);
177 char* data = ((char*)page) + sizeof(PageInfo);
178 *((InUse*)data) = 1;
180 //create the link between old page and the newly created page
181 PageInfo* pageInfo = ((PageInfo*)curPage_);
183 long oldPage = (long)pageInfo->nextPage_;
184 //pageInfo->nextPage_ = page;
185 int retVal = Mutex::CASL((long*)&pageInfo->nextPage_ , (long)pageInfo->nextPage_, (long)page);
186 if(retVal !=0) {
187 *((InUse*)data) = 0;
188 pInfo->setPageAsFree();
189 printDebug(DM_Warning, "Unable to get lock to set chunk list.");
190 *status = ErrLockTimeOut;
191 db->releaseAllocDatabaseMutex();
192 return NULL;
195 //make this new page as the current page
196 //curPage_ = page;
197 retVal = Mutex::CASL((long*)&curPage_ , (long)curPage_, (long)page);
198 if(retVal !=0) {
199 *((InUse*)data) = 0;
200 pInfo->setPageAsFree();
201 retVal = Mutex::CASL((long*)&pageInfo->nextPage_ , (long)pageInfo->nextPage_, (long)oldPage);
202 if (retVal !=0) printError(ErrSysFatal, "Fatal: Unable to reset the nextPage");
203 printDebug(DM_Warning, "Unable to get lock to set curPage");
204 *status = ErrLockTimeOut;
205 db->releaseAllocDatabaseMutex();
206 return NULL;
209 db->releaseAllocDatabaseMutex();
210 return data + sizeof(InUse);
213 //Allocates memory to store data
214 //TODO::check whether it is locked before allocating.
215 //delete tuple will set the usedflag to true, but locks will be held
216 //till commit and it shall be rolledback.So make sure that it does not
217 //allocate deleted tuple which is yet to be commited.
219 void* Chunk::allocate(Database *db, DbRetVal *status)
221 PageInfo* pageInfo = ((PageInfo*)curPage_);
223 int noOfDataNodes=(int) os::floor((PAGE_SIZE - sizeof(PageInfo))/allocSize_);
224 char *data = ((char*)curPage_) + sizeof(PageInfo);
225 printDebug(DM_Alloc, "Chunk::allocate id:%d curPage:%x noOfDataNodes:%d",
226 chunkID_, curPage_, noOfDataNodes);
228 //1.scan through data list and find if any is free to use in current page
229 //2.If there is none then
230 // a) get new free page from db. set the prev->next to point
231 // to this new page
232 //4. b) initialize the free page to zero and get first data ptr.
233 //5.If there is one, return that
235 //For allocation more than PAGE_SIZE
236 if (0 == noOfDataNodes)
238 data = (char*) allocateForLargeDataSize(db);
239 return data;
242 //Chunk Mutex is required as atomic instructions are not giving
243 // consistent results. Need more investigation to improve concurrency
244 int ret = getChunkMutex(db->procSlot);
245 if (ret != 0)
247 if (status != NULL) *status = ErrLockTimeOut;
248 printError(ErrLockTimeOut,"Unable to acquire chunk Mutex");
249 return NULL;
251 int i = noOfDataNodes;
252 if (BITSET(pageInfo->flags, HAS_SPACE))
254 for (i = 1; i< noOfDataNodes; i++)
256 if (*((InUse*)data) == 1) data = data + allocSize_;
257 else break;
261 printDebug(DM_Alloc, "ChunkID:%d Node which might be free is %d",
262 chunkID_, i);
263 //It comes here if the pageInfo hasFreeSpace
264 //or there are no free data space in this page
265 if (i == noOfDataNodes && *((InUse*)data) == 1)
268 printDebug(DM_Alloc, "ChunkID:%d curPage does not have free nodes.", chunkID_);
269 //there are no free data space in this page
270 InUse oldVal = pageInfo->flags;
271 InUse newVal = oldVal;
272 CLEARBIT(newVal, HAS_SPACE);
273 int ret = Mutex::CASGen(&pageInfo->flags, oldVal, newVal);
274 if(ret !=0) {
275 *status = ErrLockTimeOut;
276 printDebug(DM_Warning, "Unable to set hasFreespace");
277 releaseChunkMutex(db->procSlot);
278 return NULL;
280 *status = OK;
281 data = (char*) allocateFromFirstPage(db, noOfDataNodes, status);
282 releaseChunkMutex(db->procSlot);
283 if (NULL == data && *status != ErrLockTimeOut)
285 *status = OK;
286 data = (char*) allocateFromNewPage(db, status);
287 if (data == NULL && *status != ErrLockTimeOut)
289 printError(ErrNoMemory, "No memory in any of the pages:Increase db size");
290 *status = ErrNoMemory;
293 if (*status == OK) setPageDirty(db, data);
294 return data;
296 int retVal = Mutex::CASGen(data, 0, 1);
297 if(retVal !=0) {
298 *status = ErrLockTimeOut;
299 releaseChunkMutex(db->procSlot);
300 printDebug(DM_Warning, "Unable to set isUsed : retry...");
301 return NULL;
303 setPageDirty(db, data);
304 releaseChunkMutex(db->procSlot);
305 return data + sizeof(InUse);
307 void* Chunk::tryAllocate(Database *db, DbRetVal *status, int totalTries)
309 int tries=0;
310 void *node = NULL;
311 while (tries < totalTries)
313 *status = OK;
314 node= allocate(db, status);
315 if (NULL != node) break;
316 if (*status != ErrLockTimeOut)
318 printError(*status, "Unable to allocate node");
319 return NULL;
321 tries++;
322 if (0 == tries %10 )
323 printError(ErrWarning, "Unable to allocate after %d tries", tries);
325 return node;
328 void Chunk::setPageDirty(Database *db, void *ptr)
330 if (chunkID_ < LastCatalogID) return;
331 PageInfo *pageInfo = getPageInfo(db, ptr);
332 if (NULL == pageInfo)
334 printError(ErrSysFatal,"Fatal: pageInfo is NULL %x", ptr );
335 return;
337 SETBIT(pageInfo->flags, IS_DIRTY);
338 return;
340 void Chunk::setPageDirty(PageInfo *pInfo)
342 if (chunkID_ < LastCatalogID) return;
343 SETBIT(pInfo->flags, IS_DIRTY);
346 void* Chunk::allocateForLargeDataSize(Database *db, size_t size)
348 //no need to take chunk mutexes for this, as we are taking alloc database mutex
349 int multiple = (int) os::floor(size / PAGE_SIZE);
350 int offset = ((multiple + 1) * PAGE_SIZE);
351 PageInfo* pageInfo = ((PageInfo*)curPage_);
352 if(0==allocSize_)
353 pageInfo = (PageInfo*)db->getFreePage(size);
354 else
355 pageInfo = (PageInfo*)db->getFreePage(allocSize_);
356 if (NULL == pageInfo)
358 printError(ErrNoMemory,"No more free pages in the database:Increase db size");
359 return NULL;
361 printDebug(DM_VarAlloc,"Chunk::Large Data Item id:%d Size:%d curPage:%x ",
362 chunkID_, size, curPage_);
363 //TODO:: logic pending
364 if(allocSize_!=0){
365 //large size allocate for FixedSize data
366 pageInfo->nextPageAfterMerge_ = ((char*)pageInfo + offset);
367 ((PageInfo*)curPage_)->nextPage_ = (Page*) pageInfo;
368 curPage_ = (Page*) pageInfo;
369 char* data = ((char*)curPage_) + sizeof(PageInfo);
370 int ret = Mutex::CASGen(data, 0, 1);
371 if(ret !=0) {
372 printError(ErrLockTimeOut, "Lock Timeout: retry...");
373 return NULL;
375 pageInfo->isUsed_=1;
376 InUse oldVal = pageInfo->flags;
377 InUse newVal = oldVal;
378 CLEARBIT(newVal, HAS_SPACE);
379 setPageDirty(pageInfo);
380 ret = Mutex::CASGen(&pageInfo->flags, oldVal, newVal);
381 if (ret !=0) printError(ErrSysFatal, "Unable to set flags");
382 return data + sizeof(InUse);
383 }else{
384 return allocateForVarLargeSize(pageInfo, size, offset);
386 //REDESIGN MAY BE REQUIRED:Lets us live with this for now.
387 //what happens to the space lets say 10000 bytes is allocated
388 //it needs 2 pages,= 16000 bytes, 6000 bytes should not be wasted
389 //in this case.So need to take of this.
390 //Will be coded at later stage as this is developed to support
391 //undo logging and currently we shall assume that the logs generated
392 //wont be greater than PAGE_SIZE.
393 return NULL;
396 void Chunk::freeForLargeAllocator(void *ptr, int pslot)
398 //There will be max only one data element in a page.
399 //PageInfo is stored just before the data.
400 int ret = getChunkMutex(pslot);
401 if (ret != 0)
403 printError(ErrLockTimeOut,"Unable to acquire chunk Mutex");
404 return;
406 PageInfo *pageInfo = (PageInfo*)(((char*)
407 ptr) - (sizeof(PageInfo) + sizeof(InUse)));
408 PageInfo *pInfo = (PageInfo*)firstPage_, *prev = (PageInfo*)firstPage_;
409 bool found = false;
410 while(!found)
412 if (pInfo == pageInfo) {found = true; break; }
413 prev = pInfo;
414 pInfo = (PageInfo*)pInfo->nextPage_;
416 if (!found)
418 printError(ErrSysFatal,"Page %x not found in page list:Logical error", pageInfo );
419 releaseChunkMutex(pslot);
420 return ;
422 os::memset(((char*)pageInfo+sizeof(PageInfo)), 0 , allocSize_);
423 if(((PageInfo*)firstPage_)->nextPage_ != NULL){
424 pageInfo->nextPageAfterMerge_ = NULL;
425 //pageInfo->isUsed_ = 0;
426 ret = Mutex::CASGen(&pageInfo->isUsed_, pageInfo->isUsed_, 0);
427 if (ret != 0) printError(ErrSysFatal, "Unable to set isUsed flag");
428 InUse oldVal = pageInfo->flags;
429 InUse newVal = oldVal;
430 SETBIT(newVal, HAS_SPACE);
431 ret = Mutex::CASGen(&pageInfo->flags, oldVal, newVal);
432 if (ret != 0) printError(ErrSysFatal, "Unable to set flags");
433 if(pageInfo == firstPage_ && ((PageInfo*)firstPage_)->nextPage_ != NULL)
435 //firstPage_ = pageInfo->nextPage_ ;
436 ret = Mutex::CASL((long*)&firstPage_, (long) firstPage_,
437 (long)pageInfo->nextPage_);
438 if (ret != 0) printError(ErrSysFatal, "Unable to set firstPage");
439 setPageDirty(((PageInfo*)firstPage_));
441 else {
442 //prev->nextPage_ = pageInfo->nextPage_;
443 ret = Mutex::CASL((long*)&prev->nextPage_, (long) prev->nextPage_,
444 (long)pageInfo->nextPage_);
445 if (ret != 0) printError(ErrSysFatal, "Unable to set nextPage");
446 setPageDirty(prev);
449 setPageDirty(pageInfo);
450 releaseChunkMutex(pslot);
451 return;
454 //Frees the memory pointed by ptr
455 void Chunk::free(Database *db, void *ptr)
457 if (0 == allocSize_)
459 freeForVarSizeAllocator(db, ptr, db->procSlot);
460 return;
462 int noOfDataNodes =(int) os::floor((PAGE_SIZE - sizeof(PageInfo)) / allocSize_);
464 if (0 == noOfDataNodes)
466 freeForLargeAllocator(ptr, db->procSlot);
467 return;
469 int ret = getChunkMutex(db->procSlot);
470 if (ret != 0)
472 printError(ErrLockTimeOut,"Unable to acquire chunk Mutex");
473 return;
475 //unset the used flag
476 //*((int*)ptr -1 ) = 0;
477 InUse oldValue=1;
478 if (*((InUse*)ptr -1 ) == 0) {
479 printError(ErrSysFatal, "Fatal:Data node already freed %x Chunk:%d value:%d", ptr, chunkID_,
480 *((InUse*)ptr -1 ));
481 oldValue=0;
482 //return;
484 int retVal = Mutex::CASGen(((InUse*)ptr -1), oldValue, 0);
485 if(retVal !=0) {
486 printError(ErrSysFatal, "Unable to get lock to free for %x", ptr);
487 releaseChunkMutex(db->procSlot);
488 return;
490 PageInfo *pageInfo;
491 pageInfo = getPageInfo(db, ptr);
492 if (NULL == pageInfo)
494 printError(ErrSysFatal,"Fatal: pageInfo is NULL", pageInfo );
495 releaseChunkMutex(db->procSlot);
496 return;
498 //set the pageinfo where this ptr points
499 InUse oldVal = pageInfo->flags;
500 InUse newVal = oldVal;
501 SETBIT(newVal, HAS_SPACE);
502 retVal = Mutex::CASGen(&pageInfo->flags, oldVal, newVal);
503 if(retVal !=0) {
504 printError(ErrSysFatal, "Unable to get lock to set flags");
506 setPageDirty(pageInfo);
507 releaseChunkMutex(db->procSlot);
508 return;
511 //returns the pageInfo of the page where this ptr points
512 //This works only if the data size is less than PAGE_SIZE
513 //If ptr points to data which is more than PAGE_SIZE,then
514 //calling this might lead to memory corruption
515 //Note:IMPORTANT::assumes db lock is taken before calling this
516 PageInfo* Chunk::getPageInfo(Database *db, void *ptr)
518 if (allocSize_ < PAGE_SIZE - sizeof(PageInfo)) {
519 int rem = (long) ptr % PAGE_SIZE;
520 return (PageInfo*)(((char*)ptr) - rem);
521 } else {
522 //large size allocator
523 char *inPtr = (char*)ptr;
524 PageInfo* pageInfo = ((PageInfo*)firstPage_);
526 while( pageInfo != NULL )
528 if (inPtr > (char*) pageInfo && pageInfo->nextPageAfterMerge_ >inPtr)
529 return pageInfo;
530 pageInfo = (PageInfo*)pageInfo->nextPage_ ;
533 return NULL;
536 //If called on chunk used to store tuples, it returns the total number of rows
537 //present in the table
538 long Chunk::getTotalDataNodes()
540 long totalNodes =0;
541 if (0 == allocSize_) //->variable size allocator
543 return getVarTotalDataNodes();
546 //TODO::for large size allocator
547 if (allocSize_ >PAGE_SIZE)//->each page has only one data node
549 Page *page = ((PageInfo*)firstPage_);
550 while(NULL != page)
552 //current it page wise later this will done
553 if(1==*(int*)(((char*)page)+sizeof(PageInfo)))
554 totalNodes++;
555 page = ((PageInfo*) page)->nextPage_;
557 return totalNodes;
560 int noOfDataNodes=(int) os::floor((PAGE_SIZE - sizeof(PageInfo))/allocSize_);
561 PageInfo* pageInfo = ((PageInfo*)firstPage_);
562 char *data = ((char*)firstPage_) + sizeof(PageInfo);
563 int i=0;
564 while( pageInfo != NULL )
566 data = ((char*)pageInfo) + sizeof(PageInfo);
567 for (i = 0; i< noOfDataNodes; i++)
569 if (*((InUse*)data) == 1) { totalNodes++;}
570 data = data + allocSize_;
572 pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ;
574 return totalNodes;
577 //TODO::for other type of allocators
578 int Chunk::compact(int procSlot)
580 PageInfo* pageInfo = ((PageInfo*)firstPage_);
581 PageInfo* prevPage = pageInfo;
582 if (NULL == pageInfo)
584 return 0;
586 int ret = getChunkMutex(procSlot);
587 if (ret != 0)
589 printError(ErrLockTimeOut,"Unable to acquire chunk Mutex");
590 return ret;
592 pageInfo = (PageInfo*)pageInfo->nextPage_;
593 if (0 == allocSize_)
595 while( pageInfo != NULL )
597 bool flag = false;
598 VarSizeInfo *varInfo = (VarSizeInfo*)(((char*)pageInfo) +
599 sizeof(PageInfo));
600 while ((char*) varInfo < ((char*)pageInfo + PAGE_SIZE))
602 if (1 == varInfo->isUsed_) {flag=true; break;}
603 varInfo = (VarSizeInfo*)((char*)varInfo + sizeof(VarSizeInfo)
604 +varInfo->size_);
606 if (!flag) {
607 printDebug(DM_VarAlloc,"Freeing unused page in varsize allocator %x\n", pageInfo);
608 prevPage->nextPage_ = pageInfo->nextPage_;
609 pageInfo->isUsed_ = 0;
611 prevPage = pageInfo;
612 pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ;
613 printDebug(DM_VarAlloc,"compact iter %x\n", pageInfo);
615 }else if (allocSize_ < PAGE_SIZE)
617 while( pageInfo != NULL )
619 bool flag = false;
620 int noOfDataNodes=(int) os::floor((PAGE_SIZE - sizeof(PageInfo))/allocSize_);
621 char *data = ((char*)pageInfo) + sizeof(PageInfo);
622 for (int i = 0; i< noOfDataNodes ; i++)
624 if (1 == *((InUse*)data)) { flag = true; break; }
625 data = data +allocSize_;
627 if (!flag) {
628 printDebug(DM_Alloc,"Freeing unused page in fixed allocator %x\n", pageInfo);
629 prevPage->nextPage_ = pageInfo->nextPage_;
630 pageInfo->isUsed_ = 0;
631 pageInfo = (PageInfo*)(((PageInfo*)prevPage)->nextPage_) ;
632 }else{
633 prevPage = pageInfo;
634 pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ;
636 printDebug(DM_Alloc,"compact iter %x\n", pageInfo);
639 releaseChunkMutex(procSlot);
640 return 0;
643 int Chunk::totalPages()
645 //logic is same for variable size and for large data node allocator.
646 PageInfo* pageInfo = ((PageInfo*)firstPage_);
647 int totPages=0;
648 while( pageInfo != NULL )
650 totPages++;
651 pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ;
653 return totPages;
655 int Chunk::totalDirtyPages()
657 PageInfo* pageInfo = ((PageInfo*)firstPage_);
658 int dirtyPages=0;
659 while( pageInfo != NULL )
661 if(BITSET(pageInfo->flags, IS_DIRTY)) dirtyPages++;
662 pageInfo = (PageInfo*)(((PageInfo*)pageInfo)->nextPage_) ;
664 return dirtyPages;
668 int Chunk::initMutex(int id)
670 char mutName[IDENTIFIER_LENGTH];
671 if (-1 == id)
672 sprintf(mutName, "Chunk");
673 else
674 sprintf(mutName, "Chunk:%d",id);
675 return chunkMutex_.init(mutName);
677 int Chunk::getChunkMutex(int procSlot)
679 return chunkMutex_.getLock(procSlot);
681 int Chunk::releaseChunkMutex(int procSlot)
683 return chunkMutex_.releaseLock(procSlot);
685 int Chunk::destroyMutex()
687 return chunkMutex_.destroy();
689 void Chunk::setChunkNameForSystemDB(int id)
691 strcpy(chunkName,ChunkName[id]);
694 void Chunk::print()
696 printf(" <Chunk Id> %d </Chunk Id> \n",chunkID_);
697 printf(" <TotalPages> %d </TotalPages> \n",totalPages());
698 if (Conf::config.useDurability())
699 printf(" <DirtyPages> %d </DirtyPages> \n",totalDirtyPages());
700 printf(" <ChunkName > %s </ChunkName> \n",getChunkName());
701 printf(" <TotalDataNodes> %d </TotalDataNodes> \n",getTotalDataNodes());
702 printf(" <SizeOfDataNodes> %d </SizeOfDataNodes> \n",getSize());
703 printf(" <Allocation Type> ");
704 if(allocType_==0)
706 printf("FixedSizeAllocator ");
707 }else if(allocType_==1)
709 printf("VariableSizeAllocator ");
710 }else
712 printf("UnknownAllocator ");
714 printf("</Allocation Type>\n");