对象池


#ifndef OBJECT_POOL_H_
#define OBJECT_POOL_H_

#include "Thread_Mutex.h"
#include "Mutex_Guard.h"
#include "Lib_Log.h"
#include <list>
#include <string>
#include <algorithm>
#include <sstream>
#include <typeinfo>
#include "boost/unordered_map.hpp"

template <typename Obj, typename LOCK = Spin_Lock>
class Object_Pool {
public:
	struct ObjectNode
	{
		bool __is_in_used;
		void *__object;
	};
	typedef std::list<ObjectNode *> Obj_List;
	typedef boost::unordered_map<uint64_t, ObjectNode *> Obj_Map;

	const static int used_obj_list_bucket = 131073;

public:
	Object_Pool(void);

	virtual ~Object_Pool(void);

	virtual Obj *pop(void);

	virtual int push(Obj *obj);

	void clear(void);

	void dump_info(void);

    void dump_info_to_stream(std::ostringstream &stream);

	void dump_info_i(void);

	void debug_info(void);

	size_t sum_size(void);

	size_t free_obj_list_size(void);

	size_t used_obj_list_size(void);


protected:
	Obj_List free_obj_list_;
	size_t free_obj_list_size_;
	size_t used_obj_size_;
	size_t total_obj_size_;

	Obj_Map obj_map_; /// 使用hash_set防止push时std::list::remove操作的低效

	LOCK lock_;

	std::string type_name_;
};

template <typename Obj, typename LOCK>
Object_Pool<Obj, LOCK>::Object_Pool(void)
: free_obj_list_size_(0),
  used_obj_size_(0),
  total_obj_size_(0),
  obj_map_(used_obj_list_bucket)
{
	this->type_name_ = typeid(Obj).name();
}

template <typename Obj, typename LOCK>
Object_Pool<Obj, LOCK>::~Object_Pool(void) {
	this->clear();
}

template <typename Obj, typename LOCK>
void Object_Pool<Obj, LOCK>::dump_info(void) {
	GUARD(LOCK, mon, this->lock_);
	dump_info_i();
}

template <typename Obj, typename LOCK>
void Object_Pool<Obj, LOCK>::dump_info_to_stream(std::ostringstream &stream) {
    GUARD(LOCK, mon, this->lock_);
    stream << "free_obj_list_siz = " << free_obj_list_size_ << ", used_obj_size = " << used_obj_size_ << ", total_obj_size = " << total_obj_size_;
}

template <typename Obj, typename LOCK>
void Object_Pool<Obj, LOCK>::dump_info_i(void) {
	/*if (++dump_log_ > dump_log_interval_)*/ {
		LOG_DEBUG_INFO("free_obj_list_siz = %u, used_obj_list_size = %u", free_obj_list_size_, used_obj_size_);
//		dump_log_ = 0;
	}
}

template <typename Obj, typename LOCK>
void Object_Pool<Obj, LOCK>::debug_info(void) {
	LOG_DEBUG_INFO("free_obj_list_size_ = %u, free_obj_list_size_ = %u, used_size = %u",
			free_obj_list_size_, free_obj_list_.size(), used_obj_size_);
}

template <typename Obj, typename LOCK>
Obj * Object_Pool<Obj, LOCK>::pop(void) {
#ifdef NO_CACHE
	Obj *obj = new Obj;
#else
	GUARD(LOCK, mon, this->lock_);

	ObjectNode *node = 0;
	Obj *obj = 0;
	if (free_obj_list_size_ != 0) {
		node = this->free_obj_list_.front();
		free_obj_list_.pop_front();
		if (node->__is_in_used == true) {
			LOG_USER_TRACE("Object[%s] is used %x", this->type_name_.c_str(), node->__object);
		}
		obj = (Obj *)(node->__object);
		node->__is_in_used = true;
		--free_obj_list_size_;
		++used_obj_size_;
	} else {
		while (1) {
			if ((obj = new Obj) == 0) {
				LOG_USER_TRACE("new object[%s] return 0", this->type_name_.c_str());
				continue;
			} else {
				if ((node = new ObjectNode) == 0) {
					delete obj;
					obj = 0;
					LOG_USER_TRACE("new ObjectNode return 0");
					continue;
				}
				node->__object = obj;
				node->__is_in_used = true;
				++used_obj_size_;
				++total_obj_size_;
				if (obj_map_.insert(typename Obj_Map::value_type((uint64_t)(obj), node)).second == false)
				{
					LOG_USER_TRACE("insert obj map error %s %x", this->type_name_.c_str(), obj);
				}
				break;
			}
		}
	}
#endif
	return obj;
}

template <typename Obj, typename LOCK>
int Object_Pool<Obj, LOCK>::push(Obj *obj) {
#ifdef NO_CACHE
	delete obj;
	obj = 0;
#else
	GUARD(LOCK, mon, this->lock_);

	if (obj == 0)
		return -1;

    // modify 2013-06-04 {{{
	//typename Obj_Set::iterator used_obj_it = this->used_obj_list_.find(obj);
	//if (used_obj_it == this->used_obj_list_.end()) {
	//	LOG_USER_TRACE("***** Object_Pool<Obj, LOCK>::push(Obj *obj) can't find this Object Block %x!!!", obj);
	//	//LOG_ABORT();
	//	return -1;
	//}
	//this->used_obj_list_.erase(used_obj_it);
    //
	typename Obj_Map::iterator obj_iter = obj_map_.find((uint64_t)(obj));
	if (obj_iter == obj_map_.end())
    {
	    LOG_USER_TRACE("***** Object_Pool<Obj, LOCK>::push(Obj *obj) can't find this Object Block %x!!!", obj);
	    return -1;
    }
	ObjectNode *node = obj_iter->second;
	if (node->__object != (void *)obj)
	{
	    LOG_USER_TRACE("***** Object_Pool<Obj, LOCK>::push(Obj *obj) is inner error %x!!!", obj);
	    return -1;
	}
	if (node->__is_in_used == false)
	{
	    LOG_USER_TRACE("***** Object_Pool<Obj, LOCK>::push(Obj *obj) is no used %x!!!", obj);
	    return -1;
	}
    // }}}

	node->__is_in_used = false;
	this->free_obj_list_.push_back(node);
	++free_obj_list_size_;
	--used_obj_size_;
#endif
	return 0;
}

template <typename Obj, typename LOCK>
void Object_Pool<Obj, LOCK>::clear(void) {
	GUARD(LOCK, mon, this->lock_);

	for (typename Obj_List::iterator it = this->free_obj_list_.begin();
			it != this->free_obj_list_.end(); ++it) {
		if ((*it)->__object != 0)
			delete ((Obj *)((*it)->__object));
		delete *it;
	}
	//for (typename Obj_Set::iterator it = this->used_obj_list_.begin();
	//		it != this->used_obj_list_.end(); ++it) {
	//	delete *it;
	//}

	this->total_obj_size_ = 0;
	this->used_obj_size_ = 0;
	this->free_obj_list_size_ = 0;
	this->free_obj_list_.clear();
	this->obj_map_.clear();
}

template <typename Obj, typename LOCK>
size_t Object_Pool<Obj, LOCK>::sum_size(void) {
	GUARD(LOCK, mon, this->lock_);

	return total_obj_size_;
}

template <typename Obj, typename LOCK>
size_t Object_Pool<Obj, LOCK>::free_obj_list_size(void) {
	return free_obj_list_size_;
}

template <typename Obj, typename LOCK>
size_t Object_Pool<Obj, LOCK>::used_obj_list_size(void) {
	return used_obj_size_;
}

#endif /* OBJECT_POOL_H_ */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值