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

API Documentation


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

DynamicArray.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      : 2006/7/16
00013 //
00014 #ifndef _DYNAMICARRAY_H
00015 #define _DYNAMICARRAY_H
00016 
00017 #if _MSC_VER > 1000
00018 #pragma once
00019 #endif // _MSC_VER > 1000
00020 
00021 #include "../utility/StdHeader.h"
00022 
00023 namespace firtex
00024 {
00025         namespace utility
00026         {
00027                 #define DYNARRAY_DEFAULTBLKSIZE         128
00028 
00029                 template<class T>
00030                         class Const_NullValue
00031                 {
00032                 public:
00033                         inline operator T()const{return (T)0;}
00034                 };
00035 
00036                 template<class ElemT,class NullValue = Const_NullValue<ElemT> >
00037                 class CDynamicArray
00038                 {       
00039                 public:
00040                         typedef ElemT element_type;
00041                 public:
00042                         CDynamicArray(void);
00043                         CDynamicArray(int32_t blkSize);
00044                         CDynamicArray(size_t initSize,int32_t blkSize);
00045                         CDynamicArray(const CDynamicArray& src);
00046                         ~CDynamicArray(void);
00047                 public:
00048                         class CDynamicArrayIterator
00049                         {
00050                         public:
00051                                 CDynamicArrayIterator(CDynamicArray<ElemT,NullValue>* pParent)
00052                                         :m_pParent(pParent)
00053                                         ,m_curBlk(-1)
00054                                         ,m_curOffset(-1)                                        
00055                                 {
00056                                 }
00057                                 CDynamicArrayIterator(const CDynamicArrayIterator& clone)
00058                                         :m_pParent(clone.m_pParent)
00059                                         ,m_curBlk(clone.m_curBlk)
00060                                         ,m_curOffset(clone.m_curOffset)                                 
00061                                 {
00062                                 }
00063                                 ~CDynamicArrayIterator(){}
00064                         public:
00065                                 bool                    next()
00066                                 {                               
00067                                         if(m_curBlk == -1)
00068                                         {
00069                                                 m_curBlk = m_pParent->m_blkBase;
00070                                                 while(!m_pParent->m_blocks[m_curBlk] && (m_curBlk < m_pParent->m_numBlks) )
00071                                                         m_curBlk++;
00072                                                 if(m_curBlk >= m_pParent->m_numBlks)
00073                                                         return false;
00074                                         }
00075                                         do
00076                                         {
00077                                                 m_curOffset++;
00078                                                 if(m_curOffset >= m_pParent->m_blkSize)
00079                                                 {
00080                                                         m_curBlk++;
00081                                                         while(!m_pParent->m_blocks[m_curBlk] && (m_curBlk < m_pParent->m_numBlks) )
00082                                                                 m_curBlk++;
00083                                                         if(m_curBlk>=m_pParent->m_numBlks)
00084                                                                 return false;
00085                                                         m_curOffset = 0;
00086                                                 }
00087                                         }while(m_pParent->m_blocks[m_curBlk][m_curOffset] == NullValue());
00088                                         
00089                                         return true;
00090                                 }
00091                                 element_type    element()
00092                                 {
00093                                         return m_pParent->m_blocks[m_curBlk][m_curOffset];
00094                                 }
00095                                 size_t                  position()
00096                                 {
00097                                         return m_curBlk*m_pParent->m_blkSize + m_curOffset;
00098                                 }
00099                         protected:
00100                                 CDynamicArray<ElemT,NullValue>* m_pParent;
00101                                 int32_t                                 m_curBlk;
00102                                 int32_t                                 m_curOffset;                                    
00103                         };
00104 
00105                         typedef CDynamicArrayIterator array_iterator;
00106                 public:
00107                         ElemT&                  operator[](size_t order);
00108 
00114                         void            insert(size_t order,const ElemT& val);
00115 
00120                         array_iterator  elements();
00121 
00123             size_t              length();
00124 
00129                         size_t          setMaxlength(size_t newMaxLen);
00130 
00132                         void            clear();
00133                         
00135                         void            reset();
00136                 protected:                      
00137                         int32_t         block(size_t order);
00138                         int32_t         offset(size_t order);
00139 
00144                         void            grow(size_t newLen);
00145 
00147                         void            allocBlock(int32_t blk);
00148                 private:
00149                         ElemT**         m_blocks;       //块
00150                         int32_t         m_blkSize;      //单个块的长度
00151                         int32_t         m_blkBase;      //块基数
00152                         int32_t         m_numBlks;      //块总数
00153                         size_t          m_maxLength;    //长度
00154                 };
00156                 //
00157                 template<class ElemT,class NullValue>
00158                         CDynamicArray<ElemT,NullValue>::CDynamicArray(void)
00159                         :m_blkSize(DYNARRAY_DEFAULTBLKSIZE)
00160                         ,m_blkBase(0)
00161                         ,m_numBlks(1)
00162                         ,m_maxLength(DYNARRAY_DEFAULTBLKSIZE)
00163                 {
00164                         m_blocks = new ElemT*[m_numBlks];
00165                         m_blocks[0] = NULL;                     
00166                 }
00167                 template<class ElemT,class NullValue>
00168                         CDynamicArray<ElemT,NullValue>::CDynamicArray(int32_t blkSize)
00169                         :m_blkSize(blkSize)
00170                         ,m_blkBase(0)
00171                         ,m_numBlks(1)
00172                         ,m_maxLength(blkSize)
00173                 {
00174                         m_blocks = new ElemT*[m_numBlks];
00175                         m_blocks[0] = NULL;                     
00176                 }
00177                 template<class ElemT,class NullValue>
00178                         CDynamicArray<ElemT,NullValue>::CDynamicArray(size_t initSize,int32_t blkSize)
00179                         :m_blkSize(blkSize)
00180                         ,m_blkBase(0)
00181                         ,m_maxLength(initSize)
00182                 {
00183                         m_numBlks = (int32_t)((initSize + blkSize - 1)/blkSize);
00184                         m_blocks = new ElemT*[m_numBlks];
00185                         memset(m_blocks,0,m_numBlks*sizeof(ElemT*));
00186                 }
00187 
00188                 template<class ElemT,class NullValue>
00189                         CDynamicArray<ElemT,NullValue>::CDynamicArray(const CDynamicArray& src)
00190                 {
00191                         m_blkSize = src.m_blkSize;
00192                         m_blkBase = src.m_blkBase;
00193                         m_numBlks = src.m_numBlks;
00194                         m_maxLength = src.m_maxLength;
00195                         m_blocks = new ElemT*[m_numBlks];       //块
00196                         memcpy(m_blocks,src.m_blocks,m_numBlks*sizeof(ElemT*));
00197                         for(int32_t i = 0;i<m_numBlks;i++)
00198                         {
00199                                 allocBlock(i);
00200                                 memcpy(m_blocks[i],src.m_blocks[i],m_blkSize*sizeof(ElemT));
00201                         }
00202                 }
00203 
00204                 template<class ElemT,class NullValue>
00205                         CDynamicArray<ElemT,NullValue>::~CDynamicArray(void)
00206                 {
00207                         clear();
00208                 }
00209 
00210                 /*template<class ElemT,class NullValue>
00211                         ElemT const& CDynamicArray<ElemT,NullValue>::operator[](size_t order)const
00212                 {
00213                         FIRTEX_ASSERT((order < m_maxLength),_T("out of range"));
00214 
00215                         int32_t blk = block(order);                     
00216                         FIRTEX_ASSERT((m_blocks[blk]!=NULL),_T("access empty element"));
00217                         int32_t off = offset(order);
00218                         return m_blocks[blk][off];
00219                 }*/
00220 
00221                 template<class ElemT,class NullValue>
00222                         ElemT& CDynamicArray<ElemT,NullValue>::operator[](size_t order)
00223                 {
00224                         if(order >= m_maxLength)
00225                                 grow(order+1);          //增长
00226                         int32_t blk = block(order);
00227                         int32_t off = offset(order);
00228                         if(m_blocks[blk] == NULL)
00229                                 allocBlock(blk);
00230                         return m_blocks[blk][off];//
00231                 }               
00232                 template<class ElemT,class NullValue>
00233                         typename CDynamicArray<ElemT,NullValue>::array_iterator CDynamicArray<ElemT,NullValue>::elements()
00234                 {
00235                         return typename CDynamicArray<ElemT,NullValue>::array_iterator(this);
00236                 }
00237                 template<class ElemT,class NullValue>
00238                         void CDynamicArray<ElemT,NullValue>::insert(size_t order,const ElemT& val)
00239                 {
00240                         if(order >= m_maxLength)
00241                                 grow(order+1);          //增长
00242                         int32_t blk = block(order);
00243                         int32_t off = offset(order);
00244                         if(m_blocks[blk] == NULL)
00245                                 allocBlock(blk);
00246                         m_blocks[blk][off] = val;
00247                 }
00248 
00249                 template<class ElemT,class NullValue>
00250                         void CDynamicArray<ElemT,NullValue>::grow(size_t newLen)
00251                 {
00252                         int32_t numBlks = (int32_t)((newLen + m_blkSize - 1)/m_blkSize);
00253                         ElemT** tmpBlks = new ElemT*[numBlks];
00254                         memset(tmpBlks,0,numBlks*sizeof(ElemT*));
00255                         memcpy(tmpBlks,m_blocks,m_numBlks*sizeof(ElemT*));
00256                         delete[] m_blocks;
00257                         m_blocks = tmpBlks;
00258                         m_numBlks = numBlks;
00259                         m_maxLength = newLen;
00260                 }               
00261                 template<class ElemT,class NullValue>
00262                         void CDynamicArray<ElemT,NullValue>::allocBlock(int32_t blk)
00263                 {
00264                         FIRTEX_ASSERT((blk<m_numBlks),_T("CDynamicArray::allocBlock():ouf of range."));
00265                         m_blocks[blk] = new ElemT[m_blkSize];
00266                         for (int i = 0;i<m_blkSize;i++)
00267                         {
00268                                 m_blocks[blk][i] = NullValue();
00269                         }
00270                         //memset(m_blocks[blk],(int)NullValue,m_blkSize*sizeof(ElemT));
00271                 }
00272 
00273                 template<class ElemT,class NullValue>
00274                         void CDynamicArray<ElemT,NullValue>::clear()
00275                 {
00276                         if(m_blocks)
00277                         {
00278                                 for(int32_t i = 0;i<m_numBlks;i++)
00279                                 {
00280                                         if(m_blocks[i])
00281                                                 delete[] m_blocks[i];
00282                                 }
00283                                 delete[] m_blocks;
00284                                 m_blocks = NULL;
00285                                 m_numBlks = 0;
00286                         }
00287                         m_maxLength = 0;
00288                 }
00289                 template<class ElemT,class NullValue>
00290                         void CDynamicArray<ElemT,NullValue>::reset()
00291                 {
00292                         if(m_blocks)
00293                         {
00294                                 for(int32_t i = 0;i<m_numBlks;i++)
00295                                 {
00296                                         if(m_blocks[i])
00297                                         {
00298                                                 memset(m_blocks[i],NullValue(),m_blkSize*sizeof(ElemT));
00299                                         }
00300                                 }
00301                         }                       
00302                 }
00304                 //inline functions
00305                 template<class ElemT,class NullValue>
00306                         inline size_t CDynamicArray<ElemT,NullValue>::length()
00307                 {
00308                         int32_t length = 0;
00309                         for(int32_t i = 0;i<m_numBlks;i++)
00310                         {
00311                                 if(m_blocks[i - m_blkBase])
00312                                 {
00313                                         for(int32_t j = 0;j<m_blkSize;j++)
00314                                                 if(m_blocks[i - m_blkBase][j] != NullValue())
00315                                                         length++;
00316                                 }
00317                         }
00318                         return length;
00319                 }
00320                 template<class ElemT,class NullValue>
00321                         inline size_t CDynamicArray<ElemT,NullValue>::setMaxlength(size_t newMaxLen)
00322                 {
00323                         if(newMaxLen > m_maxLength)
00324                         {
00325                                 grow(newMaxLen);
00326                                 return newMaxLen;
00327                         }
00328                         else return m_maxLength;
00329                 }
00330                 template<class ElemT,class NullValue>
00331                         inline int32_t CDynamicArray<ElemT,NullValue>::block(size_t order)
00332                 {
00333                         return ((int32_t)(order/m_blkSize) - m_blkBase);
00334                 }
00335                 template<class ElemT,class NullValue>
00336                         inline int32_t CDynamicArray<ElemT,NullValue>::offset(size_t order)
00337                 {
00338                         return (int32_t)(order%m_blkSize);
00339                 }
00340         }
00341 }
00342 
00343 
00344 #endif

http://www.firtex.org http://www.sourceforge.net/projects/firtex