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
53 Page
*nextPageAfterMerge_
; //used only in case of
54 //where pages are merged to store data which are more than
56 //More detail about how it is used is found in Database::getFreePage
58 Page
*nextPage_
; //next page in the same chunk
59 void setPageAsUsed(size_t offset
);
60 void setFirstPageAsUsed();
67 //Iterator for the data
68 //Data is stored in chunks and this class gives
73 size_t allocSize_
; // used if it is a fixed size allocator
76 //current iterating page
79 //Each page is divided into nodes of size allocSize_
80 //This gives the offset of the node in the page
85 //Total number of nodes in the page
86 //It is a constant value for this chunk
87 //and it is cached for performance
93 ChunkIterator() { pageSize
= PAGE_SIZE
; allocSize_
=0; iterPage_
= NULL
; nodeOffset_
=0;
94 chunkID_
= -1; noOfNodes_
=0; }
95 int isLargeSize() { if (noOfNodes_
== 0) return true; else return false; }
97 void* nextElementIntMatch(int value
, int offset
);
98 inline void* nextElementInt() {
100 pageSize
= PAGE_SIZE
;
101 data
= ((char*)iterPage_
) + sizeof(PageInfo
);
102 if ((*(InUse
*)data
) == 1) return data
+ sizeof(InUse
);
105 if(0 == noOfNodes_
) return nextElement();
107 while(data
< iterPageEnd
)
109 if (*((InUse
*)data
)) {
110 return data
+ sizeof(InUse
);
115 while(iterPage_
->nextPage_
!= NULL
)
117 iterPage_
= (PageInfo
*)iterPage_
->nextPage_
;
118 data
= ((char*)iterPage_
) + sizeof(PageInfo
);
119 iterPageEnd
= ((char*)iterPage_
) + pageSize
;
120 while(data
< iterPageEnd
)
122 if (*((InUse
*)data
) == 0) {
123 data
= data
+ allocSize_
;
126 return data
+sizeof(InUse
);
135 class DatabaseManagerImpl
;
141 // used if it is a fixed size allocator
143 AllocType allocType_
;
145 //Current page where the last data allocation was made
148 //Page where data allocation was made for the first time
149 //This is the start of the data
150 //Iterator should start from this page
152 char chunkName
[CHUNK_NAME_LEN
];
157 //sets the size of the allocator
158 //for fixed size allocator
159 void setSize(size_t size
);
161 void setChunkNameForSystemDB(int id
);
162 void setChunkName(char const *name
){strcpy(chunkName
,name
);}
163 char *getChunkName(){return chunkName
;}
165 size_t getSize() { return allocSize_
; }
166 void setChunkID(unsigned int id
) { chunkID_
= id
; }
167 int getChunkID() { return chunkID_
; }
168 void setAllocType(AllocType type
) { allocType_
= type
; }
169 AllocType
getAllocType() { return allocType_
; }
170 Page
* getFirstPage(){ return firstPage_
; }
171 Page
* getCurrentPage(){ return curPage_
; }
172 void setFirstPage(void *fp
) { firstPage_
= fp
;}
173 void setCurPage(void *cp
) { curPage_
= cp
;}
174 PageInfo
* getPageInfo(Database
*db
, void *ptr
);
175 void* allocate(Database
*db
, DbRetVal
*status
);
177 void* allocate(Database
*db
, size_t size
, DbRetVal
*status
);
179 void free(Database
*db
, void* ptr
);
180 ChunkIterator
getIterator();
183 long getTotalDataNodes();
185 int compact(int procSlot
);
190 int getChunkMutex(int procSlot
);
191 int releaseChunkMutex(int procSlot
);
193 int createDataBucket(Page
*page
, size_t totalSize
, size_t needSize
, int pslot
);
194 int splitDataBucket(VarSizeInfo
*varInfo
, size_t needSize
, int pslot
, DbRetVal
*status
);
195 void* varSizeFirstFitAllocate(size_t size
, int pslot
, DbRetVal
*status
);
196 void freeForLargeAllocator(void *ptr
, int pslot
);
197 void freeForVarSizeAllocator(void *ptr
, int pslot
);
199 void* allocateForLargeDataSize(Database
*db
);
200 void* allocateFromFirstPage(Database
*db
, int noOfDataNodes
, DbRetVal
*status
);
201 void* allocateFromNewPage(Database
*db
, DbRetVal
*status
);
203 void* allocateForLargeDataSize(Database
*db
, size_t size
);
204 void* allocFromNewPageForVarSize(Database
*db
, size_t size
, int pslot
,
206 void* allocateFromCurPageForVarSize(size_t size
, int pslot
, DbRetVal
*status
);
209 friend class Database
;
210 friend class DatabaseManagerImpl
;