FirteX-高性能全文索引和检索平台API Documentation |
00001 // 00002 // Copyright(C) 2005--2006 Institute of Computing Tech, Chinese Academy of Sciences. 00003 // All rights reserved. 00004 // This file is part of FirteX (www.firtex.org) 00005 // 00006 // Use of the FirteX is subject to the terms of the software license set forth in 00007 // the LICENSE file included with this software, and also available at 00008 // http://www.firtex.org/license.html 00009 // 00010 // Author : 郭瑞杰(GuoRuijie) 00011 // Email : ruijieguo@software.ict.ac.cn,ruijieguo@gmail.com 00012 // Created : 2005/10/19 00013 // 00014 00015 #ifndef _MEMCACHE_H 00016 #define _MEMCACHE_H 00017 00018 #include "Config.h" 00019 #include <cmath> 00020 #include <vector> 00021 using namespace std; 00022 00023 #define MINPOW 5 00024 #define MAXPOW 32 00025 #define NLISTS MAXPOW-MINPOW+1 00026 00027 namespace firtex 00028 { 00029 namespace utility 00030 { 00031 static size_t POW_TABLE[] = 00032 { 00033 1,2,4,8,16,32,64,128,256,512, 00034 1024,2048,4096,8192,16384,32768,65536,131072,262144,524288, 00035 1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912, 00036 1073741824,2147483648, 00037 }; 00038 00039 template<typename T> 00040 class CMemCache 00041 { 00042 public: 00046 CMemCache(size_t cachesize); 00047 00052 CMemCache(T* cache, size_t cachesize); 00053 00054 CMemCache(); 00055 00056 ~CMemCache(); 00057 public: 00062 T* getMem(size_t chunksize); 00063 00064 00071 T* getMoreMem(size_t newsize, T* location, size_t oldsize); 00072 00078 void freeMem(T* location, size_t memsize); 00079 00083 void flushMem(); 00084 00088 const T* getBegin(); 00089 00093 const T* getEnd(); 00094 00098 const size_t getSize(){return m_size;} 00099 00103 bool isEmpty(){return (m_end==m_begin);} 00104 00108 CMemCache<T>* grow(size_t growSize); 00112 bool isGrowed(){return (m_pGrowCache!=NULL);} 00113 00114 private: 00120 T* getFromFree(size_t csize); 00121 00122 T* m_begin; 00123 size_t m_size; 00124 T* m_end; 00125 int m_typesize; 00126 00127 vector<T*>m_freelist[NLISTS]; 00128 bool m_bOurmem; 00129 00130 CMemCache<T>* m_pGrowCache; 00131 }; 00132 00133 00135 //implimemtation 00136 template<typename T> 00137 CMemCache<T>::CMemCache(size_t cachesize) 00138 { 00139 m_typesize = sizeof(T); 00140 m_size = cachesize; 00141 m_begin = (T*) malloc(m_size*m_typesize); 00142 if(m_begin == NULL) 00143 { 00144 FIRTEX_THROW3(OUTOFMEM_ERROR,_T("CMemCache alloc memory failed.")); 00145 } 00146 m_end = m_begin; 00147 m_bOurmem = true; 00148 m_pGrowCache = NULL; 00149 } 00150 00151 template<typename T> 00152 CMemCache<T>::CMemCache(T* cache, size_t cachesize) 00153 { 00154 m_size = cachesize; 00155 m_begin = cache; 00156 m_end = m_begin; 00157 m_typesize = sizeof(T); 00158 m_bOurmem = false; 00159 m_pGrowCache = NULL; 00160 } 00161 00162 template<typename T> 00163 CMemCache<T>::CMemCache() 00164 { 00165 m_size = 0; 00166 } 00167 00168 template<typename T> 00169 CMemCache<T>::~CMemCache() 00170 { 00171 if (m_bOurmem) 00172 free(m_begin); 00173 for (int i=0; i<NLISTS; i++) 00174 { 00175 m_freelist[i].clear(); 00176 } 00177 00178 if(m_pGrowCache) 00179 { 00180 delete m_pGrowCache; 00181 m_pGrowCache = NULL; 00182 } 00183 } 00184 00185 template<typename T> 00186 T* CMemCache<T>::getMem(size_t chunksize) 00187 { 00188 if ((chunksize < MINPOW) || (chunksize > MAXPOW)) 00189 return NULL; 00190 00191 size_t size = POW_TABLE[chunksize]; 00192 00193 T *retval = NULL; 00194 00195 // 优先使用m_freelist里的空闲内存 00196 retval = getFromFree(chunksize); 00197 if (retval != NULL) 00198 { 00199 return retval; 00200 } 00201 00202 // 从空闲块中获取 00203 if ((m_end - m_begin) + size > m_size) 00204 { 00205 //从新增长的内存中获取 00206 if(m_pGrowCache) 00207 return m_pGrowCache->getMem(chunksize); 00208 return NULL; 00209 } 00210 // give a chunk from the m_end, update m_end 00211 retval = m_end; 00212 m_end += size; 00213 00214 return retval; 00215 } 00216 00217 00218 template<typename T> 00219 T* CMemCache<T>::getMoreMem(size_t newsize, T* location, size_t oldsize) 00220 { 00221 if (oldsize >= newsize) 00222 return NULL; 00223 00224 if ((oldsize < MINPOW) || (oldsize > MAXPOW)) 00225 return NULL; 00226 00227 if ((newsize < MINPOW) || (newsize > MAXPOW)) 00228 return NULL; 00229 00230 T* retval = getMem(newsize); 00231 if (retval == NULL) 00232 return NULL; 00233 00234 //拷贝旧内存块中的数据到新内存块 00235 memcpy(retval, location, (size_t) (POW_TABLE[oldsize]*m_typesize)); 00236 00237 00238 // 保存释放的内存块以重新利用 00239 m_freelist[oldsize-MINPOW].push_back(location); 00240 00241 return retval; 00242 } 00243 00244 template<typename T> 00245 void CMemCache<T>::freeMem(T* location, size_t memsize) 00246 { 00247 // 保存释放的内存块以重新利用 00248 if( (location >= m_begin) && (location < (m_begin + m_size))) 00249 m_freelist[memsize-MINPOW].push_back(location); 00250 else 00251 { 00252 //是新增长缓存中的内存 00253 if(m_pGrowCache) 00254 m_pGrowCache->freeMem(location,memsize); 00255 } 00256 } 00257 00258 00259 template<typename T> 00260 void CMemCache<T>::flushMem() 00261 { 00262 //清空 00263 m_end = m_begin; 00264 00265 //清空freelist 00266 for (int i=0; i<NLISTS; i++) 00267 { 00268 m_freelist[i].clear(); 00269 } 00270 if(m_pGrowCache) 00271 { 00272 delete m_pGrowCache; 00273 m_pGrowCache = NULL; 00274 } 00275 } 00276 00277 template<typename T> 00278 const T* CMemCache<T>::getBegin() 00279 { 00280 return m_begin; 00281 } 00282 00283 template<typename T> 00284 const T* CMemCache<T>::getEnd() 00285 { 00286 return m_end; 00287 } 00288 00289 template<typename T> 00290 inline T* CMemCache<T>::getFromFree(size_t csize) 00291 { 00292 if (m_freelist[csize-MINPOW].empty()) 00293 { 00294 if(m_pGrowCache) 00295 { 00296 return m_pGrowCache->getFromFree(csize); 00297 } 00298 return NULL; 00299 } 00300 00301 T* retval = m_freelist[csize-MINPOW].back(); 00302 m_freelist[csize-MINPOW].pop_back(); 00303 00304 return retval; 00305 } 00306 00307 template<typename T> 00308 CMemCache<T>* CMemCache<T>::grow(size_t growSize) 00309 { 00310 if(m_pGrowCache) 00311 return m_pGrowCache->grow(growSize); 00312 00313 m_pGrowCache = new CMemCache(growSize); 00314 return m_pGrowCache; 00315 } 00316 00317 #include "typedefs.h" 00318 typedef CMemCache<firtex::loc_t> CPosMemCache; 00319 } 00320 } 00321 00322 00323 00324 #endif 00325
http://www.firtex.org http://www.sourceforge.net/projects/firtex