支持HW团队,就支付宝领取下面的红包吧!(2018年3月31前,就几毛,也会几块,可以和其他红包叠加使用),你领取消费,HW有奖励。红包使用无条件限制,有条件请注意是不是有病毒。

小伙伴们,给大家发红包喽!人人可领,领完就能用。祝大家领取的红包金额大大大!#吱口令#长按复制此消息,打开支付宝就能领取!er1OEj73Uj

登入 注册 | 验证
| 搜索
HelloWorld论坛 : > 计算机科学、技术、教学> 编程专题> 开源免费项目> [原创]ACE内存分配——不定长数据,不定量个数分配(四)——最终策略
 
 
 
 
 
 
类别:算法 阅读:3225 评论:0 时间:五月 27, 2013, 3:06 p.m. 关键字:ACE AVL tree 内存 平衡二叉树

 

 利用[原创]ACE内存分配——不定长数据,不定量个数分配(三)——平衡二叉树实现真正的不定长分配我们实现最终分配方案,见代码:

在_DEBUG模式下,会定时输出各种大小申请次数,可以通过调试确定分配方案,尽量让分配落在定长分配的范围里面。

刚开始调试的时候,反而比没有使用内存管理要耗cpu,后来调整了锁,略胜一点,望高手提供点优化意见。

/***************************************************************
version:  1.0
date: 16/5/2013   17:04
FileName:     hwnet_block_allocator.h
Author:       丁灵峰
Compiled on:   VC.net 2008
-------------------------------------------------------------
Description:
Modification history:
Other:

-------------------------------------------------------------
Copyright (C) 2010 - All Rights Reserved
***************************************************************
HW_ACE_ALLOCATOR_MEM_CHICK
****************************************************************/
#if (defined HW_ACE) && (defined HW_ACE_ALLOCATOR)  // 使用自定义内存管理
#ifndef _H_hwnet_date_allocator_
#define _H_hwnet_date_allocator_

#include "ace/Malloc.h"
#include <ace/Malloc_T.h>
#include <boost/shared_ptr.hpp>
#include "hwnet_variable_allocator.h"

namespace hwnet
{
        template <class ACE_LOCK>
        class ManageAllocator;
        template <class ACE_LOCK>
        class HW_Dynamic_Cached_Allocator
                : public HW_Allocator
        {
public:
  /// Create a cached memory pool with @a n_chunks chunks
  /// each with @a chunk_size size.
        HW_Dynamic_Cached_Allocator (char* pBuf, size_t n_chunks, size_t chunk_size)
                : free_list_ (ACE_PURE_FREE_LIST)
                , chunk_size_(chunk_size)
        {
                for (size_t c = 0;
                        c < n_chunks;
                        c++)
                {
                        void* placement = pBuf + c * chunk_size_;

                        this->free_list_.add (new (placement) ACE_Cached_Mem_Pool_Node<char>);
                }
                // Put into free list using placement contructor, no real memory
                // allocation in the above <new>.
        }

  /// Clear things up.
        ~HW_Dynamic_Cached_Allocator (void)
        {
                chunk_size_ = 0;
        }

  /**
   * Get a chunk of memory from free list cache.  Note that @a nbytes is
   * only checked to make sure that it's less or equal to @a chunk_size,
   * and is otherwise ignored since malloc() always returns a pointer to an
   * item of @a chunk_size size.
   */
        void *malloc (size_t nbytes = 0)
        {
                // Check if size requested fits within pre-determined size.
                if (nbytes > chunk_size_)
                        return 0;

                // addr() call is really not absolutely necessary because of the way
                // ACE_Cached_Mem_Pool_Node's internal structure arranged.
                return this->free_list_.remove ()->addr ();
        }

  /**
   * Get a chunk of memory from free list cache, giving them
   * @a initial_value.  Note that @a nbytes is only checked to make sure
   * that it's less or equal to @a chunk_size, and is otherwise ignored
   * since calloc() always returns a pointer to an item of @a chunk_size.
   */
  virtual void *calloc (size_t nbytes,
          char initial_value = '\0')
  {
          // Check if size requested fits within pre-determined size.
          if (nbytes > chunk_size_)
                  return 0;

          // addr() call is really not absolutely necessary because of the way
          // ACE_Cached_Mem_Pool_Node's internal structure arranged.
          void *ptr = this->free_list_.remove ()->addr ();
          if (ptr != 0)
                  ACE_OS::memset (ptr, initial_value, chunk_size_);
          return ptr;
  }

  /// This method is a no-op and just returns 0 since the free list
  /// only works with fixed sized entities.
  virtual void *calloc (size_t n_elem,
                        size_t elem_size,
                                                char initial_value = '\0')
  {
          ACE_NOTSUP_RETURN (0);
  }

  /// Return a chunk of memory back to free list cache.
  void free (void * ptr)
  {
          if (ptr != 0)
                  this->free_list_.add ((ACE_Cached_Mem_Pool_Node<char> *) ptr);
  }

  /// Return the number of chunks available in the cache.
  size_t size (void)
  {
          return this->free_list_.size();
  }

private:
  /// Remember how we allocate the memory in the first place so
  /// we can clear things up later.
  //char *pool_;

  /// Maintain a cached memory free list. We use @c char as template
  /// parameter, although sizeof(char) is usually less than
  /// sizeof(void*). Really important is that @a chunk_size
  /// must be greater or equal to sizeof(void*).
  ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<char>, ACE_LOCK> free_list_;

  /// Remember the size of our chunks.
  size_t chunk_size_;

        };

        template <class ACE_LOCK>
        class DateNode
        {
        public:
#ifdef _DEBUG
                DateNode<ACE_LOCK>(HW_Allocator* pParent, size_t nbytes)
#else
                DateNode<ACE_LOCK>(HW_Allocator* pParent)
#endif
                : m_pParent(pParent)
#ifdef _DEBUG
                , m_flage(0x0101010101010101)
                , m_nbytes(nbytes)
#else
#endif
                {
                        assert(m_pParent);
                }
                ~DateNode<ACE_LOCK>()
                {
                }

        public:
#ifdef _DEBUG
                size_t m_flage; // 内存分界标示,是否被越界写检查
                size_t m_nbytes; // 实际申请大小
#else
#endif
                HW_Allocator* m_pParent;
        };
        template <class ACE_LOCK>
        class AllocatorNode
                : public ACE_New_Allocator
        {
        public:
                union
                {
                        size_t m_Date;//值
                        size_t m_uBufSize; // 最小数据内存
                };
                size_t m_ihgt;//以此节点为根的树的高度
                AllocatorNode* m_pFather;//指向父节点的地址
                AllocatorNode* m_pLchild;//指向左儿子的地址
                AllocatorNode* m_pRchild;//指向右儿子的地址
                AllocatorNode* m_pNode;//指向等值节点的地址
                //static void Delete(AllocatorNode* pVoid)
                //{
                //      if (pVoid)
                //      {
                //              pVoid->~AllocatorNode();
                //      }
                //      ::free(pVoid);
                //}
                //static boost::shared_ptr<AllocatorNode> Create(size_t uBufSum // 一次申请个数
                //      , size_t MinBufSize // 最小数据内存
                //      )
                //{
                //      void *ptr = ::malloc(sizeof(AllocatorNode));
                //      if (ptr)
                //      {
                //              new (ptr) AllocatorNode(uBufSum, MinBufSize);
                //              boost::shared_ptr<AllocatorNode>((AllocatorNode*)ptr, Delete);
                //      }
                //      return boost::shared_ptr<AllocatorNode>();
                //}
        public:
                AllocatorNode(size_t uBufSum // 一次申请个数
                        , size_t MinBufSize // 最小数据内存
                        , ManageAllocator<ACE_LOCK>* pParent
                        )
                        : m_BufSum(uBufSum) // 一次申请个数
                        , m_uBufSize(MinBufSize) //  最小数据内存
                        , m_deqAllocator(NULL)
                        , m_uSizeAllocator(0)
                        , m_uUsedAllocator(0)
                        , m_pParent(pParent)
                {
                        assert(pParent);
                        m_uSizeAllocator = 1024;
                        m_deqAllocator = (HW_Allocator**)::malloc(sizeof(HW_Allocator*) * m_uSizeAllocator);
                        if (m_deqAllocator)
                        {
                                ACE_OS::memset (m_deqAllocator, 0, sizeof(HW_Allocator*)*m_uSizeAllocator);
                        }
                        else
                        {
                                m_uSizeAllocator = 0;
                        }
                }
                ~AllocatorNode();
        public:
                virtual void *malloc (size_t nbytes);
                virtual void *calloc (size_t nbytes, char initial_value = '\0')
                {
                        void* ptr = malloc(nbytes);
                        if (ptr)
                        {
                                ACE_OS::memset (ptr, initial_value, nbytes);
                        }

                        return ptr;
                }
                virtual void *calloc (size_t n_elem, size_t elem_size, char initial_value = '\0')
                {
                        return calloc (n_elem * elem_size, initial_value);
                }
//              virtual void free (void* ptr)
//              {
//                      //ACE_GUARD (ACE_LOCK, monitor, this->m_lock);
//                      if (ptr)
//                      {
//                              ((DateNode<ACE_LOCK>*)((char*)ptr - sizeof(DateNode<ACE_LOCK>)))->m_pParent->free(ptr);
//#ifdef _DEBUG
//                              std::cout << m_deqAllocator.size() << "(" << m_uBufSize << ")" << std::endl;
//#else
//#endif
//                      }
                //              }
                size_t SumTotal()
                {
                        return m_BufSum*m_uUsedAllocator;
                }
                size_t Sum()
                {
                        return m_uUsedAllocator;
                }
                size_t size()
                {
                        size_t uSize=0;
                        ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, 0);
                        for (size_t i=0
                                ; i < m_uUsedAllocator
                                ; i++)
                        {
                                uSize += m_BufSum - m_deqAllocator[i]->size();
                        }
                        return uSize;
                }
                // 释放多余空闲块
                void FreeEmpty();
        private:
                ACE_LOCK m_lock;
                size_t m_BufSum; // 一次申请个数
                HW_Allocator** m_deqAllocator;
                size_t m_uSizeAllocator;
                size_t m_uUsedAllocator;
                ManageAllocator<ACE_LOCK>* m_pParent;
        };
        template <class ACE_LOCK>
        class ManageAllocator
                : public ACE_New_Allocator
        {
                // 友元
                // 静态属性
#if defined(_DEBUG) || defined(HW_ACE_ALLOCATOR_MEM_CHICK)
                template <class T>
                class TreeNodeMem
                {
                public:
                        TreeNodeMem(T uMinBufSize, size_t uValue=1) :m_Date(uMinBufSize),m_ihgt(0), m_pFather(NULL), m_pLchild(NULL), m_pRchild(NULL), m_pNode(NULL),  m_uValue(uValue){}
                        T m_Date;//值
                        size_t m_ihgt;//以此节点为根的树的高度
                        TreeNodeMem* m_pFather;//指向父节点的地址
                        TreeNodeMem* m_pLchild;//指向左儿子的地址
                        TreeNodeMem* m_pRchild;//指向右儿子的地址
                        TreeNodeMem* m_pNode;//指向等值节点的地址
                        size_t m_uValue;
                };
#else
#endif
                // 静态函数
        public:
                static void DeleteInstance(ManageAllocator* pVoid)
                {
                        if (pVoid)
                        {
                                pVoid->~ManageAllocator();
                        }
                        ::free(pVoid);
                }
                static ManageAllocator* CreateInstance(size_t uBufSum // 一次申请个数
                        , size_t MinBufSize // 最小数据内存
                        , size_t DateSize // 建议数据初始大小
                        )
                {
                        void *ptr = ::malloc(sizeof(ManageAllocator));
                        if (ptr)
                        {
                                return new (ptr) ManageAllocator(uBufSum, MinBufSize, DateSize);
                        }
                        return NULL;
                }
                // 静态工具
                // 接口实现

                // 构造于析构
        public:
                virtual ~ManageAllocator(void)
                {
#ifdef _DEBUG
                        std::cout << "类型:";
                        insubtree(m_avlTreeMenSize.GetRoot());
                        std::cout << std::endl;
#else
#endif
                        DeleteAllocatorNode(this->m_avlTree.GetRoot());
                }
                ManageAllocator(size_t uBufSum // 一次申请个数
                        , size_t MinBufSize // 最小数据内存
                        , size_t DateSize // 建议数据初始大小
                )
                : m_Other(uBufSum, 0, this)
                , m_BufSize(1) // 单位数据内存大小
                , m_MenLeng(0) // 单位数据内存大小,几个零,二进制
                , m_DateSize(DateSize) // 建议数据初始大小
#ifdef _DEBUG
                        , m_uSim(0) // 已经使用数量
                        , m_uSimTemp(0) // 输出提示中间间隔
#else
#endif
                {
                        if (MinBufSize < sizeof(char)*AvlDateNodeUnionSize)
                        {
                                MinBufSize = sizeof(char)*AvlDateNodeUnionSize;
                        }
                        MinBufSize += sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize;
                        MinBufSize += sizeof(DateNode<ACE_LOCK>);
                        MinBufSize = ACE_MALLOC_ROUNDUP (MinBufSize, ACE_MALLOC_ALIGN);
                        while (m_BufSize < MinBufSize)
                        {
                                m_BufSize <<= 1;
                                m_MenLeng ++;
                        }
                }
                void Create(size_t uBufSum // 一次申请个数
                        , size_t uBufSize // 单位内存
                        )
                {
                        ACE_GUARD(ACE_LOCK, monitor, this->m_lock);
                        AllocatorNode<ACE_LOCK>* pNode = m_avlTree.Find(uBufSize);
                        if (pNode == NULL)
                        {
                                void* ptr = this->m_Other.malloc(sizeof(AllocatorNode<ACE_LOCK>));
                                if (ptr)
                                {
                                        AllocatorNode<ACE_LOCK>* pNode = new (ptr) AllocatorNode<ACE_LOCK>(uBufSum, uBufSize, this);
                                        this->m_avlTree.Insert(pNode);
                                }
                        }
                }

                size_t mallocT(size_t nbytes)
                {
                        // 规范大小为 m_MinBufSize 的整数倍
                        size_t iSize = (ACE_MALLOC_ROUNDUP (nbytes + (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize), m_BufSize)) >> m_MenLeng;
                        return (iSize << m_MenLeng) - (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize);
                }

                size_t mallocSize(size_t nbytes)
                {
                        AllocatorNode<ACE_LOCK>* pNode = m_avlTree.FindLessOrGreater(nbytes);
                        if (pNode)
                        {
                                return pNode->m_Date;
                        }
                        // 规范大小为 m_MinBufSize 的整数倍
                        size_t iSize = (ACE_MALLOC_ROUNDUP (nbytes + (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize) + sizeof(DateNode<ACE_LOCK>), m_BufSize)) >> m_MenLeng;
                        return (iSize << m_MenLeng) - (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize) - sizeof(DateNode<ACE_LOCK>);
                }

                // 当第一次申请空间,不知道大小的时候,调用,提供建议大小,m_DateSize要经过测试得到
                size_t mallocDate()
                {
                        return m_DateSize;
                }

                //size_t mallocSum(size_t iSize=1)
                //{
                //      // 规范大小为 m_MinBufSize 的整数倍
                //      if (iSize < 1)
                //      {
                //              iSize = 1;
                //      }
                //      return (iSize << m_MenLeng) - (sizeof(AvlDateNode<ACE_LOCK>) - sizeof(char)*AvlDateNodeUnionSize) - sizeof(DateNode<ACE_LOCK>);
                //}

                HW_Allocator* NewAllocator(size_t uBufSum // 一次申请个数
                        , size_t uBufSize // 单位内存
                        )
                {
                        if (uBufSize == 0)
                        {
                                size_t uSizeHead = ACE_MALLOC_ROUNDUP (uBufSum, AVLTreeVariableAllocator<ACE_LOCK>::s_iHeadSum) >> 2;
                                size_t uSilzeClass = ACE_MALLOC_ROUNDUP (sizeof(AVLTreeVariableAllocator<ACE_LOCK>), ACE_MALLOC_ALIGN);
                                char* pBuf = (char*)::malloc(uSilzeClass + uSizeHead + m_BufSize * uBufSum);
                                if (pBuf)
                                {
#ifdef HW_ACE_ALLOCATOR_MEM_CHICK
                                        this->AddMen(pBuf, uSilzeClass + uSizeHead + m_BufSize * uBufSum);
#else
#endif
                                        return dynamic_cast<HW_Allocator*>(new (pBuf) AVLTreeVariableAllocator<ACE_LOCK>(pBuf+uSilzeClass, pBuf+uSilzeClass+uSizeHead, uBufSum, m_BufSize, m_MenLeng));
                                }
                        }
                        else
                        {
                                uBufSize = ACE_MALLOC_ROUNDUP (uBufSize + sizeof(DateNode<ACE_LOCK>), ACE_MALLOC_ALIGN);
                                size_t uSilzeClass = ACE_MALLOC_ROUNDUP (sizeof(HW_Dynamic_Cached_Allocator<ACE_LOCK>), ACE_MALLOC_ALIGN);
                                size_t uSizeTotal = this->mallocT(uSilzeClass + uBufSize * uBufSum);
                                uBufSum = (uSizeTotal-uSilzeClass)/uBufSize;
                                char* pBuf = (char*)this->m_Other.malloc(uSizeTotal);
                                if (pBuf)
                                {
#ifdef HW_ACE_ALLOCATOR_MEM_CHICK
                                        this->AddMen(pBuf, uSilzeClass + uBufSize * uBufSum);
#else
#endif
                                        return dynamic_cast<HW_Allocator*>(new (pBuf) HW_Dynamic_Cached_Allocator<ACE_LOCK>(pBuf+uSilzeClass, uBufSum, uBufSize));
                                }
                        }
                        return NULL;
                }

                void DelAllocator(HW_Allocator* pAllocator)
                {
                        pAllocator->~HW_Allocator();
                        if (dynamic_cast<AVLTreeVariableAllocator<ACE_LOCK>*>(pAllocator) != NULL)
                        {
                                ::free(pAllocator);
                        }
                        else
                        {
                                return this->free(pAllocator);
                        }
                }

                // 操作函数
        public:
                virtual void *malloc (size_t nbytes)
                {
                        // 满足C++的标准规定:当要求的内存大小为0 byte时也应该返回有效的内存地址
                        //if (nbytes == 0)
                        //{
                        //      return NULL;
                        //}
#ifdef _DEBUG
                        {
                                ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL);
                                m_uSimTemp++;
                                TreeNodeMem<size_t>* pNode = m_avlTreeMenSize.Find(nbytes);
                                if (pNode == NULL)
                                {
                                        m_uSimTemp = 0;
                                        void* ptr = ::malloc(sizeof(TreeNodeMem<size_t>));
                                        if (ptr)
                                        {
                                                pNode = new (ptr) TreeNodeMem<size_t>(nbytes);
                                                this->m_avlTreeMenSize.Insert(pNode);
                                        }
                                        std::cout << "类型:";
                                        insubtree(m_avlTreeMenSize.GetRoot());
                                        std::cout << std::endl;
                                }
                                else
                                {
                                        pNode->m_uValue++;
                                        if (m_uSimTemp >= 100000)
                                        {
                                                m_uSimTemp = 0;
                                                std::cout << "类型 \\";
                                                insubtree(m_avlTreeMenSize.GetRoot());
                                                std::cout << std::endl;
                                                std::cout << "使用情况 \\";
                                                insubtreeNode(m_avlTree.GetRoot());
                                                std::cout << "其他(" << m_Other.SumTotal()-m_Other.size() << "," << m_Other.size() << ")" << m_Other.Sum();
                                                std::cout << std::endl;
                                        }
                                }
                        }
#else
#endif
                        // 分级 分级在对象建立后创建,以后不加修改,所以不需要加锁
                        AllocatorNode<ACE_LOCK>* pNode = m_avlTree.FindLessOrGreater(nbytes);
                        if (pNode)
                        {
                                void* ptr = pNode->malloc(nbytes);
                                if (ptr)
                                {
#ifdef _DEBUG
                                        {
                                                ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL);
                                                m_uSim++;
                                        }
#else
#endif
                                        return ptr;
                                }
                        }
                        // 不定长数据处理
                        void* ptr = m_Other.malloc(nbytes);
                        if (ptr)
                        {
#ifdef _DEBUG
                                ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL);
                                m_uSim++;
#else
#endif
                        }
                        else
                        {
                                std::cerr << "分配失败!";
                        }
                        return ptr;
                }
                virtual void *calloc (size_t nbytes, char initial_value = '\0')
                {
                        void* ptr = malloc(nbytes);
                        if (ptr)
                        {
                                ACE_OS::memset (ptr, initial_value, nbytes);
                        }

                        return ptr;
                }
                virtual void *calloc (size_t n_elem, size_t elem_size, char initial_value = '\0')
                {
                        return calloc (n_elem * elem_size, initial_value);
                }
                virtual void free (void* ptr)
                {
#ifdef _DEBUG
                        assert(m_uSim > 0);
#else
#endif
                        if (ptr)
                        {
                                DateNode<ACE_LOCK>* pNode = (DateNode<ACE_LOCK>*)((char*)ptr - sizeof(DateNode<ACE_LOCK>));
                                pNode->m_pParent->free((char*)ptr - sizeof(DateNode<ACE_LOCK>));
#ifdef _DEBUG
                                ACE_GUARD (ACE_LOCK, monitor, this->m_lock);
                                m_uSim--;
#else
#endif
                        }
                }

#ifdef HW_ACE_ALLOCATOR_MEM_CHICK
                void AddMen(void* uPose, size_t uSize)
                {
                        ACE_GUARD (ACE_LOCK, monitor, this->m_lock);
                        TreeNodeMem<void*>* pNode = this->m_avlTreeMenChick.FindLessOrGreater(uPose, false);
                        if (pNode)
                        {
                                if ((pNode->m_Date <= uPose) && ((char*)uPose+uSize <= (char*)pNode->m_Date+pNode->m_uValue))
                                {
                                        return ;
                                }
                        }
                        void* ptr = ::malloc(sizeof(TreeNodeMem<void*>));
                        if (ptr)
                        {
                                pNode = new (ptr) TreeNodeMem<void*>(uPose, uSize);
                                this->m_avlTreeMenChick.Insert(pNode);
                        }
#ifdef _DEBUG
                        std::cout << "内存添加:" << uPose << ",\t" << (void*)((char*)uPose+uSize) << std::endl;
#endif

                }
                void DelMen(void* uPose, size_t uSize)
                {
                        ACE_GUARD (ACE_LOCK, monitor, this->m_lock);
                        TreeNodeMem<void*>* pNode = this->m_avlTreeMenChick.Find(uPose);
                        if (pNode == NULL)
                        {
                                return ;
                        }
                        if ((pNode->m_Date != uPose) || (pNode->m_uValue != uSize))
                        {
                                return ;
                        }
                        this->m_avlTreeMenChick.Delete(pNode);
                        pNode->~TreeNodeMem<void*>();
                        ::free(pNode);
#ifdef _DEBUG
                        std::cout << "内存删除:" << uPose << ",\t" << (void*)((char*)uPose+uSize) << std::endl;
#else
#endif
                }
                virtual void free_chick (void* ptr)
                {
                        ACE_GUARD (ACE_LOCK, monitor, this->m_lock);
                        TreeNodeMem<void*>* pNode = this->m_avlTreeMenChick.FindLessOrGreater((char*)ptr, false);
                        if (pNode)
                        {
                                if ((pNode->m_Date < ptr) && ((char*)ptr <= (char*)pNode->m_Date+pNode->m_uValue))
                                {
                                        return free(ptr);
                                }
                        }
#ifdef _DEBUG
                        std::cout << "删除:" << ptr << std::endl;
#else
#endif
                        pNode = this->m_avlTreeMenChick.FindLessOrGreater((char*)ptr, false);
                        if (pNode)
                        {
                                if ((pNode->m_Date < ptr) && ((char*)ptr <= (char*)pNode->m_Date+pNode->m_uValue))
                                {
                                        return free(ptr);
                                }
                        }
                        return ::free(ptr);
                }
#else
#endif
                

#ifdef _DEBUG
                /// Return the number of chunks available in the cache.
                size_t Size (void)
                {
                        return m_uSim;
                }
#else
#endif
                //中序遍历函数
                void DeleteAllocatorNode(AllocatorNode<ACE_LOCK>* pNode)
                {
                        if(pNode==NULL) return;
                        DeleteAllocatorNode(pNode->m_pLchild);//先遍历左子树
                        pNode->~AllocatorNode<ACE_LOCK>();
                        this->m_Other.free(pNode);
                        DeleteAllocatorNode(pNode->m_pRchild);//再遍历右子树
                }
                //中序遍历函数
                void insubtreeFreeEmpty(AllocatorNode<ACE_LOCK>* pNode)
                {
                        if(pNode==NULL) return;
                        insubtreeFreeEmpty(pNode->m_pLchild);//先遍历左子树
                        pNode->FreeEmpty();
                        insubtreeFreeEmpty(pNode->m_pRchild);//再遍历右子树
                }
                // 释放多余空闲块
                void FreeEmpty()
                {
                        insubtreeFreeEmpty(m_avlTree.GetRoot());
                        // 不定长数据处理
                        m_Other.FreeEmpty();
                }

                // 工具函数
        private:
        protected:
#ifdef _DEBUG
                //中序遍历函数
                void insubtree(TreeNodeMem<size_t>* pNode)
                {
                        if(pNode==NULL) return;
                        insubtree(pNode->m_pLchild);//先遍历左子树
                        std::cout << pNode->m_Date << "(" << pNode->m_uValue << ")   ";
                        insubtree(pNode->m_pRchild);//再遍历右子树
                }
                //中序遍历函数
                void insubtreeNode(AllocatorNode<ACE_LOCK>* pNode)
                {
                        if(pNode==NULL) return;
                        insubtreeNode(pNode->m_pLchild);//先遍历左子树
                        std::cout << pNode->m_Date << "(" << pNode->SumTotal()-pNode->size() << "," << pNode->size() << ")" << pNode->Sum() << "  ";
                        insubtreeNode(pNode->m_pRchild);//再遍历右子树
                }
#else
#endif

                // 禁止
        private:
                ManageAllocator(const ManageAllocator&); //复制构造
                ManageAllocator & operator= (const ManageAllocator&); // 等于重载

                // 属性
        public:
        protected:
                ACE_LOCK m_lock;
                AVLTree<AllocatorNode<ACE_LOCK>, size_t> m_avlTree; // 平衡二叉树
                AllocatorNode<ACE_LOCK> m_Other;
                size_t m_BufSize; // 单位数据内存大小
                size_t m_MenLeng; // 单位数据内存大小,几个零,二进制
                size_t m_DateSize; // 建议数据初始大小
#ifdef _DEBUG
                size_t m_uSim; // 已经使用数量
                size_t m_uSimTemp; // 输出提示中间间隔
                AVLTree<TreeNodeMem<size_t>, size_t> m_avlTreeMenSize; // 平衡二叉树 用于记录申请个数
#else
#endif

#ifdef HW_ACE_ALLOCATOR_MEM_CHICK
                AVLTree<TreeNodeMem<void*>, void*> m_avlTreeMenChick; // 平衡二叉树 用于类型检查
#else
#endif
        };
        template <class ACE_LOCK>
        AllocatorNode<ACE_LOCK>::~AllocatorNode()
        {
                for (size_t i=0
                        ; i < m_uUsedAllocator
                        ; i++)
                {
                        this->m_pParent->DelAllocator(m_deqAllocator[i]);
                }
                ::free(m_deqAllocator);
        }
        // 释放多余空闲块
        template <class ACE_LOCK>
        void AllocatorNode<ACE_LOCK>::FreeEmpty()
        {
                ACE_GUARD (ACE_LOCK, monitor, this->m_lock);
                bool bFlage=true; // 我们只释放第二块
                for (size_t i=0
                        ; i < m_uUsedAllocator
                        ; i++)
                {
                        if (m_BufSum == m_deqAllocator[i]->size())
                        {
                                if (bFlage)
                                {
                                        this->m_pParent->DelAllocator(m_deqAllocator[i]);
                                        m_deqAllocator[i] = NULL;
                                        for (size_t j=i
                                                ; j < m_uUsedAllocator
                                                ; j++)
                                        {
                                                m_deqAllocator[j] = m_deqAllocator[j+1];
                                        }
                                        m_uUsedAllocator--;
                                }
                                else
                                {
                                        bFlage = true;
                                }
                        }
                }
        }
        template <class ACE_LOCK>
        void* AllocatorNode<ACE_LOCK>::malloc (size_t nbytes)
        {
                // 还有空闲
                if (m_uUsedAllocator > 0)
                {
                        for (int i=m_uUsedAllocator/2; i>=0; i--)
                        {
                                HW_Allocator* pAllocator = m_deqAllocator[0];
                                if ((pAllocator) && (pAllocator->size() > 0))
                                {
                                        void* ptr = pAllocator->malloc(nbytes);
                                        if (ptr)
                                        {
#ifdef _DEBUG
                                                new (ptr) DateNode<ACE_LOCK>(dynamic_cast<HW_Allocator*>(pAllocator), nbytes);
#else
                                                new (ptr) DateNode<ACE_LOCK>(dynamic_cast<HW_Allocator*>(pAllocator));
#endif
                                                return (char*)ptr + sizeof(DateNode<ACE_LOCK>);
                                        }
                                }

                                ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL);
                                if ((pAllocator) && (pAllocator == m_deqAllocator[0]))
                                {
                                        for (size_t i=0
                                                ; i < m_uUsedAllocator
                                                ; i++)
                                        {
                                                m_deqAllocator[i] = m_deqAllocator[i+1];
                                        }
                                        m_deqAllocator[m_uUsedAllocator-1] = pAllocator;
                                }
                        }
                }
                // 重新分配
                if (m_uSizeAllocator < m_uUsedAllocator+1)
                {
                        size_t uSizeAllocator = m_uSizeAllocator + 1024;
                        HW_Allocator** deqAllocator = (HW_Allocator**)::malloc(sizeof(HW_Allocator*) * uSizeAllocator);
                        if (deqAllocator)
                        {
                                ACE_OS::memset (deqAllocator, 0, sizeof(HW_Allocator*)*uSizeAllocator);
                                for (size_t i=0
                                        ; i < m_uUsedAllocator
                                        ; i++)
                                {
                                        deqAllocator[i] = m_deqAllocator[i];
                                }
                                ::free(m_deqAllocator);
                                m_deqAllocator = deqAllocator;
                                m_uSizeAllocator = uSizeAllocator;
                        }
                        else
                        {
                                return NULL;
                        }
                }
                HW_Allocator* pAllocator = this->m_pParent->NewAllocator(m_BufSum, m_uBufSize);
                if (pAllocator)
                {
                        {
                                ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL);
                                m_deqAllocator[m_uUsedAllocator] = pAllocator;
                                m_uUsedAllocator++;
                        }
                        void* ptr = pAllocator->malloc(nbytes);
                        if (ptr)
                        {
#ifdef _DEBUG
                                new (ptr) DateNode<ACE_LOCK>(dynamic_cast<HW_Allocator*>(pAllocator), nbytes);
#else
                                new (ptr) DateNode<ACE_LOCK>(dynamic_cast<HW_Allocator*>(pAllocator));
#endif
                                return (char*)ptr + sizeof(DateNode<ACE_LOCK>);
                        }
                }
                return NULL;
        }
}
#endif // #ifndef _H_hwnet_date_allocator_
#endif // HW_ACE HW_ACE_ALLOCATOR  //使用自定义内存管理

    使用方法:

std::set<size_t> setMinSize;
setMinSize.insert(40);
setMinSize.insert(1024);
boost::shared_ptr<ManageAllocator<ACE_SYNCH_RECURSIVE_MUTEX> > Block::gPManageBlockAllocator;
gPManageBlockAllocator.reset(new ManageAllocator<ACE_SYNCH_RECURSIVE_MUTEX>(setMinSize, 1024, 1024*16));
ACE_Allocator::instance (dynamic_cast<ACE_Allocator*>(gPManageBlockAllocator.get()));

 

[挂载人]初学MPEG [审核人]初学MPEG 推荐

个人签名--------------------------------------------------------------------------------

Please Login (or Sign Up) to leave a comment