windows changes
[csql.git] / include / Allocator.h
blob452b57bc209bd480a5914019dc624938014d44ab
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 #ifndef ALLOCATOR_H
17 #define ALLOCATOR_H
18 #include<os.h>
19 #include<Mutex.h>
20 #include<ErrorType.h>
21 #include<Config.h>
23 typedef void Page;
25 enum AllocType
27 FixedSizeAllocator = 0,
28 VariableSizeAllocator = 1,
29 UnknownAllocator
32 //Used to store the meta data information about the variable size data
33 class VarSizeInfo
35 public:
36 InUse size_;
37 InUse isUsed_;
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
47 #define HAS_SPACE 1
48 #define IS_DIRTY 2
50 class PageInfo
52 public:
53 InUse isUsed_;
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
58 //PAGE_SIZE.
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();
64 void setPageAsFree();
67 class Chunk;
70 //Iterator for the data
71 //Data is stored in chunks and this class gives
72 //iterator for it.
73 class ChunkIterator
75 int chunkID_;
76 size_t allocSize_; // used if it is a fixed size allocator
77 AllocType allocType_;
79 //current iterating page
80 PageInfo *iterPage_;
82 //Each page is divided into nodes of size allocSize_
83 //This gives the offset of the node in the page
84 int nodeOffset_;
85 char *data;
86 char *iterPageEnd;
88 //Total number of nodes in the page
89 //It is a constant value for this chunk
90 //and it is cached for performance
91 int noOfNodes_;
94 public:
95 int pageSize;
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; }
99 void* nextElement();
100 void* nextElementIntMatch(int value, int offset);
101 inline void* nextElementInt() {
102 if (!data) {
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();
109 data += allocSize_;
110 while(data < iterPageEnd)
112 if (*((InUse*)data)) {
113 return data + sizeof(InUse);
114 } else {
115 data += allocSize_;
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_;
127 nodeOffset_++;
128 } else
129 return data +sizeof(InUse);
132 return NULL;
134 friend class Chunk;
137 class Database;
138 class DatabaseManagerImpl;
140 class Chunk
142 int chunkID_;
144 // used if it is a fixed size allocator
145 size_t allocSize_;
146 AllocType allocType_;
148 //Current page where the last data allocation was made
149 Page *curPage_;
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
154 Page *firstPage_;
155 char chunkName[CHUNK_NAME_LEN];
156 Mutex chunkMutex_;
158 public:
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);
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();
185 void print();
187 long getTotalDataNodes();
188 int totalPages();
189 int totalDirtyPages();
190 int compact(int procSlot);
192 private:
194 int initMutex();
195 int getChunkMutex(int procSlot);
196 int releaseChunkMutex(int procSlot);
197 int destroyMutex();
198 int createDataBucket(Page *page, size_t totalSize, size_t needSize, int pslot);
199 int splitDataBucket(VarSizeInfo *varInfo, size_t needSize, int pslot, DbRetVal *status);
200 void* varSizeFirstFitAllocate(size_t size, int pslot, DbRetVal *status);
201 void freeForLargeAllocator(void *ptr, int pslot);
202 void freeForVarSizeAllocator(Database *db, void *ptr, int pslot);
204 void* allocateForLargeDataSize(Database *db);
205 void* allocateFromFirstPage(Database *db, int noOfDataNodes, DbRetVal *status);
206 void* allocateFromNewPage(Database *db, DbRetVal *status);
208 void* allocateForLargeDataSize(Database *db, size_t size);
209 void* allocFromNewPageForVarSize(Database *db, size_t size, int pslot,
210 DbRetVal *status);
211 void* allocateFromCurPageForVarSize(size_t size, int pslot, DbRetVal *status);
212 void setPageDirty(Database *db, void *ptr);
213 void setPageDirty(PageInfo *pInfo);
216 friend class Database;
217 friend class DatabaseManagerImpl;
219 #endif