⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arraypool.hpp

📁 mysql-5.0.22.tar.gz源码包
💻 HPP
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2003 MySQL AB   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#ifndef ARRAY_POOL_HPP#define ARRAY_POOL_HPP#include <ndb_global.h>#include "ndbd_malloc.hpp"#include <pc.hpp>#include <ErrorReporter.hpp>#include <NdbMem.h>#include <Bitmask.hpp>template <class T> class Array;template <class T> class SLList;template <class T> class DLList;template <class T> class DLHashTable;/** * Template class used for implementing an *   pool of object (in an array with a free list) */template <class T>class ArrayPool {public:  ArrayPool();  ~ArrayPool();    /**   * Set the size of the pool   *   * Note, can currently only be called once   */  bool setSize(Uint32 noOfElements, bool exit_on_error = true);  inline Uint32 getNoOfFree() const {    return noOfFree;  }  inline Uint32 getSize() const {    return size;  }  /**   * Update p value for ptr according to i value    */  void getPtr(Ptr<T> &);  void getPtr(ConstPtr<T> &) const;  void getPtr(Ptr<T> &, bool CrashOnBoundaryError);  void getPtr(ConstPtr<T> &, bool CrashOnBoundaryError) const;    /**   * Get pointer for i value   */  T * getPtr(Uint32 i);  const T * getConstPtr(Uint32 i) const;  T * getPtr(Uint32 i, bool CrashOnBoundaryError);  const T * getConstPtr(Uint32 i, bool CrashOnBoundaryError) const;  /**   * Update p & i value for ptr according to <b>i</b> value    */  void getPtr(Ptr<T> &, Uint32 i);  void getPtr(ConstPtr<T> &, Uint32 i) const;  void getPtr(Ptr<T> &, Uint32 i, bool CrashOnBoundaryError);  void getPtr(ConstPtr<T> &, Uint32 i, bool CrashOnBoundaryError) const;  /**   * Allocate an object from pool - update Ptr   *   * Return i   */  bool seize(Ptr<T> &);  /**   * Allocate object <b>i</b> from pool - update Ptr   */  bool seizeId(Ptr<T> &, Uint32 i);  /**   * Check if <b>i</b> is allocated.   */  bool findId(Uint32 i) const;  /**   * Return an object to pool   */  void release(Uint32 i);  /**   * Return an object to pool   */  void release(Ptr<T> &);#ifdef ARRAY_GUARD  /**   *  Checks if i is a correct seized record   *   *  @note Since this is either an expensive method,    *        or needs bitmask stuff, this method is only    *        recommended for debugging.   *   */  bool isSeized(Uint32 i) const {    if (i>=size) return false;    return BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i);  }#endifprotected:  friend class Array<T>;  friend class SLList<T>;  friend class DLList<T>;  friend class DLHashTable<T>;  /**   * Allocate <b>n</b> consecutive object from pool   *   return base   */  Uint32 seizeN(Uint32 n);  /**   * Deallocate <b>n<b> consecutive object to pool   *  starting from base   */  void releaseN(Uint32 base, Uint32 n);public:  /**   * Release a singel linked list in o(1)   * @param first i-value of first element in list   * @param last  i-value of last element in list   * @note nextPool must be used as next pointer in list   */  void releaseList(Uint32 n, Uint32 first, Uint32 last);  //private:#ifdef DEBUG  Uint32 getNoOfFree2() const {    Uint32 c2 = size;    for(Uint32 i = 0; i<((size + 31)>> 5); i++){      Uint32 w = theAllocatedBitmask[i];      for(Uint32 j = 0; j<32; j++){	if((w & 1) == 1){	  c2--;	}	w >>= 1;      }    }    return c2;  }  Uint32 getNoOfFree3() const {    Uint32 c = 0;    Ptr<T> p;    p.i = firstFree;    while(p.i != RNIL){      c++;      p.p = &theArray[p.i];      p.i = p.p->next;    }    return c;  }#endifprotected:  Uint32 firstFree;  Uint32 size;  Uint32 noOfFree;  T * theArray;  Uint32 bitmaskSz;  Uint32 *theAllocatedBitmask;};template <class T>inlineArrayPool<T>::ArrayPool(){  firstFree = RNIL;  size = 0;  noOfFree = 0;  theArray = 0;#ifdef ARRAY_GUARD  theAllocatedBitmask = 0;#endif}template <class T>inlineArrayPool<T>::~ArrayPool(){  if(theArray != 0){    ndbd_free(theArray, size * sizeof(T));    theArray = 0;#ifdef ARRAY_GUARD    delete []theAllocatedBitmask;    theAllocatedBitmask = 0;#endif  }}  /** * Set the size of the pool * * Note, can currently only be called once */template <class T>inlineboolArrayPool<T>::setSize(Uint32 noOfElements, bool exit_on_error){  if(size == 0){    if(noOfElements == 0)      return true;    theArray = (T *)ndbd_malloc(noOfElements * sizeof(T));    if(theArray == 0)    {      if (!exit_on_error)	return false;      ErrorReporter::handleAssert("ArrayPool<T>::setSize malloc failed",				  __FILE__, __LINE__, NDBD_EXIT_MEMALLOC);      return false; // not reached    }    size = noOfElements;    noOfFree = noOfElements;    /**     * Set next pointers     */    T * t = &theArray[0];    for(Uint32 i = 0; i<size; i++){      t->nextPool = (i + 1);      t++;    }    theArray[size-1].nextPool = RNIL;    firstFree = 0;#ifdef ARRAY_GUARD    bitmaskSz = (noOfElements + 31) >> 5;    theAllocatedBitmask = new Uint32[bitmaskSz];    BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask);#endif        return true;  }  if (!exit_on_error)    return false;  ErrorReporter::handleAssert("ArrayPool<T>::setSize called twice", __FILE__, __LINE__);  return false; // not reached}  template <class T>inlinevoidArrayPool<T>::getPtr(Ptr<T> & ptr){  Uint32 i = ptr.i;  if(i < size){    ptr.p = &theArray[i];#ifdef ARRAY_GUARD    if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))      return;    /**     * Getting a non-seized element     */    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);#endif  } else {    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);  }}template <class T>inlinevoidArrayPool<T>::getPtr(ConstPtr<T> & ptr) const {  Uint32 i = ptr.i;  if(i < size){    ptr.p = &theArray[i];#ifdef ARRAY_GUARD    if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))      return;    /**     * Getting a non-seized element     */    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);#endif  } else {    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);  }}template <class T>inlinevoidArrayPool<T>::getPtr(Ptr<T> & ptr, Uint32 i){  ptr.i = i;  if(i < size){    ptr.p = &theArray[i];#ifdef ARRAY_GUARD    if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))      return;    /**     * Getting a non-seized element     */    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);#endif  } else {    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);  }}template <class T>inlinevoidArrayPool<T>::getPtr(ConstPtr<T> & ptr, Uint32 i) const {  ptr.i = i;  if(i < size){    ptr.p = &theArray[i];#ifdef ARRAY_GUARD    if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))      return;    /**     * Getting a non-seized element     */    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);#endif  } else {    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);  }}  template <class T>inlineT * ArrayPool<T>::getPtr(Uint32 i){  if(i < size){#ifdef ARRAY_GUARD    if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))      return &theArray[i];    /**     * Getting a non-seized element     */    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);    return 0;#else    return &theArray[i];#endif  } else {    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);    return 0;  }}template <class T>inlineconst T * ArrayPool<T>::getConstPtr(Uint32 i) const {  if(i < size){#ifdef ARRAY_GUARD    if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))      return &theArray[i];    /**     * Getting a non-seized element     */    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);    return 0;#else    return &theArray[i];#endif  } else {    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);    return 0;  }}template <class T>inlinevoidArrayPool<T>::getPtr(Ptr<T> & ptr, bool CrashOnBoundaryError){  Uint32 i = ptr.i;  if(i < size){    ptr.p = &theArray[i];#ifdef ARRAY_GUARD    if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))      return;    /**     * Getting a non-seized element     */    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);#endif  } else {    ptr.i = RNIL;  }}template <class T>inlinevoidArrayPool<T>::getPtr(ConstPtr<T> & ptr, bool CrashOnBoundaryError) const {  Uint32 i = ptr.i;  if(i < size){    ptr.p = &theArray[i];#ifdef ARRAY_GUARD    if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))      return;    /**     * Getting a non-seized element     */    ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);#endif  } else {    ptr.i = RNIL;  }}template <class T>inlinevoidArrayPool<T>::getPtr(Ptr<T> & ptr, Uint32 i, bool CrashOnBoundaryError){  ptr.i = i;  if(i < size){    ptr.p = &theArray[i];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -