1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
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. *
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. *
15 ***************************************************************************/
27 FixedSizeAllocator
= 0,
28 VariableSizeAllocator
= 1,
32 //Used to store the meta data information about the variable size data
40 //Each Page has this info.
41 //pages are of size PAGE_SIZE normally.
42 //If data size is more than PAGE_SIZE then
43 //contigous pages are merged and those pages wont
44 //have this info in them.Only the start page where that
45 //data is stored will have this info
46 //This object is stored at the start of each page
54 InUse flags
; //stores hasFreeSpace and isDirty
56 Page
*nextPageAfterMerge_
; //used only in case of
57 //where pages are merged to store data which are more than
59 //More detail about how it is used is found in Database::getFreePage
61 Page
*nextPage_
; //next page in the same chunk
62 void setPageAsUsed(size_t offset
);
63 void setFirstPageAsUsed();
70 //Iterator for the data
71 //Data is stored in chunks and this class gives
76 size_t allocSize_
; // used if it is a fixed size allocator
79 //current iterating page
82 //Each page is divided into nodes of size allocSize_
83 //This gives the offset of the node in the page
88 //Total number of nodes in the page
89 //It is a constant value for this chunk
90 //and it is cached for performance
96 ChunkIterator() { pageSize
= PAGE_SIZE
; allocSize_
=0; iterPage_
= NULL
; nodeOffset_
=0;
97 chunkID_
= -1; noOfNodes_
=0; }
98 int isLargeSize() { if (noOfNodes_
== 0) return true; else return false; }
100 void* nextElementIntMatch(int value
, int offset
);
101 inline void* nextElementInt() {
103 pageSize
= PAGE_SIZE
;
104 data
= ((char*)iterPage_
) + sizeof(PageInfo
);
105 if ((*(InUse
*)data
) == 1) return data
+ sizeof(InUse
);
108 if(0 == noOfNodes_
) return nextElement();
110 while(data
< iterPageEnd
)
112 if (*((InUse
*)data
)) {
113 return data
+ sizeof(InUse
);
118 while(iterPage_
->nextPage_
!= NULL
)
120 iterPage_
= (PageInfo
*)iterPage_
->nextPage_
;
121 data
= ((char*)iterPage_
) + sizeof(PageInfo
);
122 iterPageEnd
= ((char*)iterPage_
) + pageSize
;
123 while(data
< iterPageEnd
)
125 if (*((InUse
*)data
) == 0) {
126 data
= data
+ allocSize_
;
129 return data
+sizeof(InUse
);
138 class DatabaseManagerImpl
;
144 // used if it is a fixed size allocator
146 AllocType allocType_
;
148 //Current page where the last data allocation was made
151 //Page where data allocation was made for the first time
152 //This is the start of the data
153 //Iterator should start from this page
155 char chunkName
[CHUNK_NAME_LEN
];
160 //sets the size of the allocator
161 //for fixed size allocator
162 void setSize(size_t size
);
164 void setChunkNameForSystemDB(int id
);
165 void setChunkName(char const *name
){strcpy(chunkName
,name
);}
166 char *getChunkName(){return chunkName
;}
168 size_t getSize() { return allocSize_
; }
169 void setChunkID(unsigned int id
) { chunkID_
= id
; }
170 int getChunkID() { return chunkID_
; }
171 void setAllocType(AllocType type
) { allocType_
= type
; }
172 AllocType
getAllocType() { return allocType_
; }
173 Page
* getFirstPage(){ return firstPage_
; }
174 Page
* getCurrentPage(){ return curPage_
; }
175 void setFirstPage(void *fp
) { firstPage_
= fp
;}
176 void setCurPage(void *cp
) { curPage_
= cp
;}
177 PageInfo
* getPageInfo(Database
*db
, void *ptr
);
178 void* tryAllocate(Database
*db
, DbRetVal
*status
, int totalTries
=10);
179 void* allocate(Database
*db
, DbRetVal
*status
);
181 void* allocate(Database
*db
, size_t size
, DbRetVal
*status
);
183 void free(Database
*db
, void* ptr
);
184 ChunkIterator
getIterator();
186 void printMutexInfo() { chunkMutex_
.print(); }
188 long getTotalDataNodes();
189 long getVarTotalDataNodes();
191 int totalDirtyPages();
192 int compact(int procSlot
);
197 int initMutex(int i
=-1);
198 int getChunkMutex(int procSlot
);
199 int releaseChunkMutex(int procSlot
);
202 void* allocateFromFirstPage(Database
*db
, int noOfDataNodes
, DbRetVal
*status
);
203 void* allocateFromNewPage(Database
*db
, DbRetVal
*status
);
206 int createDataBucket(Page
*page
, size_t totalSize
, size_t needSize
, int pslot
);
207 int splitDataBucket(VarSizeInfo
*varInfo
, size_t needSize
, int pslot
, DbRetVal
*status
);
208 void* varSizeFirstFitAllocate(size_t size
, int pslot
, DbRetVal
*status
);
209 void freeForVarSizeAllocator(Database
*db
, void *ptr
, int pslot
);
210 void* allocateForVarLargeSize(PageInfo
*pInfo
, size_t size
, int offset
);
211 void* allocFromNewPageForVarSize(Database
*db
, size_t size
, int pslot
,
213 void* allocateFromCurPageForVarSize(size_t size
, int pslot
, DbRetVal
*status
);
215 void* allocateForLargeDataSize(Database
*db
);
216 void* allocateForLargeDataSize(Database
*db
, size_t size
);
217 void freeForLargeAllocator(void *ptr
, int pslot
);
219 void setPageDirty(Database
*db
, void *ptr
);
220 void setPageDirty(PageInfo
*pInfo
);
223 friend class Database
;
224 friend class DatabaseManagerImpl
;