FirteX-高性能全文索引和检索平台

API Documentation


首页 | 名字空间列表 | 类继承关系 | 组合类型列表 | $(BL\录(B | 文件列表 | 名字空间成员 | 组合类型成员 | 文件成员

MemCache.h

浏览该文件的文档。
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