Chinaunix首页 | 论坛 | 博客
  • 博客访问: 565173
  • 博文数量: 104
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1559
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-21 00:58
个人简介

锻炼精神,首先要锻炼肉体

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-05-10 18:18:22

这篇文章用来记录过去的一周中,使用 boost 和 template 模板编程来实现一个简单的缓冲区。
程序中主要有两个主要的类 : Cache , CachePool 
其中 CachePool 操纵的对象是需要缓存的实例,该实例既可以出自 class ,也可以是 struct。
Cache 的操作对象便是 CachePool , 在 Cache 的内部首先根据需要来创建一个可以缓冲的类型列表,
将其定义为 CacheableTypes 类型。 CacheableTypes 本质上是 boost::mpl::vector < 多个类型名称>

然后根据 CacheableType 定义的 vector 作为头部创建以对象类型为索引的 map ,并将其定义为 CacheMap_t 变量
CacheMap_t 内部定义是这样的
CachMap  > 
CacheMap.value (pair) :  >
 
使用画图的方法简单表示出来就是这样:



编程环境 : vs2010

代码如下所示 

.hpp 文件中既可以写头文件中的内容,比如说类的声明,以及方法的定义,
也可以添加 .cpp 文件中的内容,比如说,在类的外面给出类中声明的方法的实现代码。

// SharedPtr.hpp

点击(此处)折叠或打开

  1. #ifndef SHARED_PTR_HPP__
  2. #define SHARED_PTR_HPP__


  3. #include <boost/shared_ptr.hpp>
  4. template <typename T>
  5. class sharedptr
  6. {
  7. public :
  8.     typedef boost::shared_ptr<T> type ;
  9. } ;


  10. #endif


// CacheableTyeps.hpp

点击(此处)折叠或打开

  1. #ifndef CACHE_ABLE_TYPES_HPP__
  2. #define CACHE_ABLES_TYPES_HPP__

  3. #include <boost/mpl/vector.hpp>
  4. #include <string>

  5. class obj1
  6. {
  7. public :

  8.     obj1( std::string name )
  9.     {
  10.         std::cout <<"create "<< name << std::endl ;
  11.         _name = name ;
  12.         
  13.     }

  14.     void print ()
  15.     {
  16.         std::cout<<"print " << _name <<std::endl ;
  17.     }
  18.     
  19. public:
  20.     std::string _name ;
  21. } ;

  22. class obj2
  23. {
  24. public :
  25.     obj2( std::string n )
  26.     {
  27.         std::cout <<"create "<<n << std::endl ;
  28.         name = n ;
  29.     }
  30.     void print ()
  31.     {
  32.         std::cout <<"print "<< name <<std::endl ;
  33.     }
  34.     
  35. public :
  36.     std::string name ;
  37. } ;

  38. class obj3
  39. {
  40. public :
  41.     obj3( std::string n )
  42.     {
  43.         std::cout <<"create "<<n<< std::endl ;
  44.         name = n ;
  45.     }

  46.     void print ()
  47.     {
  48.         std::cout<<"print " << name <<std::endl ;
  49.     }
  50.     
  51. public :
  52.     std::string name ;
  53. } ;

  54. typedef struct btnode
  55. {
  56.     std::string name ;
  57.     btnode () :name(NULL)
  58.     {}
  59.     btnode ( std::string & n ) : name (n)
  60.     {}
  61. }BtNode_t ;

  62. typedef boost::mpl::vector<obj1 , obj2 , obj3, BtNode_t> CacheableTypes ;


  63. #endif //CacheablesTypes.hpp


// CachePool.hpp

点击(此处)折叠或打开

  1. #ifndef CACHE_POOL_HPP__
  2. #define CACHE_POOL_HPP__

  3. #include "SharedPtr.hpp"
  4. #include <string>
  5. #include <map>

  6. template <typename T, typename Id = std::string>
  7. class CachePool
  8. {
  9. public :
  10.     typedef typename sharedptr<T>::type TPtr ;

  11.     TPtr get( const Id &inId )
  12.     {
  13.         TPtr result = mCachePool[inId] ;

  14.         if ( result )
  15.             result = TPtr( new T(*result)) ;
  16.         return result ;
  17.     }

  18.     const TPtr getConst ( const Id &inId )
  19.     {
  20.         return mCachePool[inId] ;
  21.     }

  22.     void add ( TPtr inPtr , const Id &inId )
  23.     {
  24.         TPtr copy( new T(*inPtr )) ;
  25.         // new T( object )
  26.         mCachePool[inId] = copy ;
  27.     }

  28.     void drop ()
  29.     {
  30.         mCachePool.clear() ;
  31.     }

  32.     void drop ( const Id &inId )
  33.     {
  34.         mCachePool[inId].reset() ;
  35.     }


  36. private :
  37.     typedef std::map<Id, TPtr> CachePoolCont ;
  38.     CachePoolCont mCachePool ;
  39. } ;
  40. #endif //CachePool.hpp

// Cache.hpp

点击(此处)折叠或打开

  1. #ifndef CACHE_HPP_
  2. #define CACHE_HPP_

  3. // mpl's transform
  4. #include <boost/mpl/transform.hpp>

  5. // fusion
  6. #include <boost/fusion/include/map.hpp>
  7. #include <boost/fusion/include/at_key.hpp>
  8. #include <boost/fusion/include/pair.hpp>

  9. // convert from MPL to fusion
  10. #include <boost/fusion/adapted/mpl.hpp>
  11. #include <boost/fusion/include/mpl.hpp>

  12. #include <string>
  13. #include <map>
  14. #include <iostream>

  15. #include "SharedPtr.hpp"
  16. #include "CachePool.hpp"


  17. template <typename TYPELIST>
  18. class Cache
  19. {
  20. public :
  21.     template <typename T>
  22.     typename sharedptr<T>::type get ( const std::string &inId ) ;

  23.     template <typename T>
  24.     const typename sharedptr<T>::type getConst ( const std::string &inId) ;

  25.     template <typename T>
  26.     void add ( typename sharedptr<T>::type inPtr , const std::string &inId) ;

  27.     template <typename T>
  28.     void drop()
  29.     {
  30.         typename sharedptr< CachePool<T> >::type cachePool = getCachePool<T> () ;
  31.         if ( cachePool )
  32.             cachePool->drop () ;
  33.     }

  34.     template <typename T>
  35.     void drop ( const std::string &inId )
  36.     {
  37.         typename sharedptr< CachePool<T> >::type cachePool = getCachePool<T> ()
  38.         if ( cachePool )
  39.             cachePool->drop(inId) ;
  40.     }
  41.     

  42.     template <typename T>
  43.     typename sharedptr<CachePool<T> >::type getCachePool ()
  44.     {
  45.         return boost::fusion::at_key<T>(mMap) ;
  46.     }

  47.     template <typename T>
  48.     void addCachePool ()
  49.     {
  50.         std::cout << " now add pool " << std::endl ;
  51.         boost::fusion::at_key<T>(mMap) = typename sharedptr<CachePool<T> >::type ( new CachePool<T> () ) ;
  52.     }

  53. private :
  54.     struct MakePair
  55.     {
  56.         template <typename T>
  57.         struct apply
  58.         {
  59.             typedef boost::fusion::pair<T,typename sharedptr<CachePool<T> >::type > type ;
  60.         } ;
  61.     } ;
  62.     
  63.     // generate pairs
  64.     typedef typename boost::mpl::transform<TYPELIST,MakePair>::type PairedCacheableTypes ;
  65.     typedef typename boost::fusion::result_of::as_map<PairedCacheableTypes>::type CacheMap_t ;

  66.     CacheMap_t mMap ;


  67. } ;


  68. template <typename TYPELIST>
  69. template <typename T>
  70. typename sharedptr<T>::type Cache<TYPELIST>::get ( const std::string &inId)
  71. {
  72.     typename sharedptr<CachePool<T> >::type cachePool = getCachePool<T>() ;

  73.     if ( !cachePool )
  74.         return typename sharedptr<T>::type() ;
  75.     
  76.     return cachePool->get(inId) ;
  77. }

  78. template <typename TYPELIST>
  79. template <typename T>
  80. const typename sharedptr<T>::type Cache<TYPELIST>::getConst( const std::string &inId )
  81. {
  82.     // first we get the specified type CachePool
  83.     typename sharedptr< CachePool<T> >::type cachePool = getCachePool<T> () ;

  84.     if ( ! cachePool ) // no cache pool with type of T in Cache
  85.         return sharedptr<T>::type () ;
  86.     return cachePool->getConst( inId ) ;
  87. }

  88.  
  89. template <typename TYPELIST>
  90. template <typename T>
  91. void Cache<TYPELIST>::add ( typename sharedptr<T>::type inPtr ,const std::string &inId )
  92. {
  93.     // first we get the cache pool object with the specified type of 'T'
  94.     sharedptr< CachePool <T> >::type cachePool = getCachePool<T> () ;

  95.     if ( !cachePool ) // if the pool is empty
  96.      addCachePool<T> () ; // we add a cache pool object into cache map
  97.     
  98.     cachePool = getCachePool<T> () ;
  99.     assert ( cachePool ) ;
  100.     cachePool->add ( inPtr , inId ) ;

  101. }
  102.  
  103. #endif // Cache.hpp

// Main.cpp

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <string>
  3. #include <cstdlib>
  4. #include <iostream>

  5. #include "SharedPtr.hpp"
  6. #include "CachePool.hpp"
  7. #include "Cache.hpp"
  8. #include "CacheableTypes.hpp"



  9. int main ()
  10. {
  11.     // here we test Cache
  12.     Cache<CacheableTypes> myCache ;

  13.     sharedptr<obj1>::type pTest ( new obj1("inuyasha") ) ;

  14.     myCache.add<obj1>( pTest, pTest->_name) ;
  15.     
  16.     std::cout <<"pTest " << std::endl ;
  17.     pTest->print() ;
  18.     pTest = sharedptr<obj1>::type () ;

  19.     pTest = myCache.get<obj1>("inuyasha") ;
  20.     
  21.     pTest->print() ;


  22.     // here i will test whether without add types into CacheableTYpes can insert it into the cache
  23.     
  24.     sharedptr<BtNode_t>::type pNode_test ( new BtNode_t(std::string ("nasume")) ) ;

  25.     myCache.add<BtNode_t>(pNode_test , pNode_test->name) ;
  26.     

  27.     system("pause") ;
  28.     return 0 ;
  29. }

运行结果是这样的:


end

既然已经达到可以使用的程度了,在后面打算创建一个 file class 来替代 obj1 ,obj2 等类对象,
实现写文件、读文件的缓冲区。

就是设定一个缓冲区的阈值,每次计算一下要写入硬盘中的(写入文件中的)全部缓冲区的大小,达到阈值的时候,
将缓冲区的数据一起写入到硬盘中(文件中) ,这样可以减少频繁写入、读取硬盘的次数,
从某些角度上来说,可以保护银盘,(理论上是这么想到,实际上-----> 然而却并没有什么卵用)

阅读(1852) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~