BigList

//
// 功能:T类型必须实现‘=’操作符
//
// must one-writer and maybe multi-readers
//
template <typename T>
class TSCOMMON_EXPORT CBigList
{
private:
	struct Node 
	{
		T			data;
		Node*		prev;
		Node*		next;
	};

public:
	explicit CBigList(int size=DEFAULT_ARRAY_SIZE)
		: size_(size > 0 ? size : DEFAULT_ARRAY_SIZE)
		, buffer_(new Node[size_])
		, head_(NULL)
		, tail_(NULL)
		, tail_prev_(NULL)
	{
		memset(buffer_, 0, sizeof(Node)*size_);
	}

	virtual ~CBigList()
	{
		if (buffer_)
		{
			delete buffer_;
		}
	}

	// Don't call this function in multi-threads.
	void push_back(T* pData)
	{
		if (pData) 
		{
			tail_prev_ = tail_;	

			mutex_.lock();
			if (tail_) 
			{
				Node*	pCur	= tail_+1;
				tail_->next		= pCur;
				pCur->prev		= tail_;
				pCur->data		= *pData;
				pCur->next		= NULL;
				tail_			= pCur;
#ifdef WIN32
				assert (tail_ != head_);
#endif
			}
			else 
			{
				tail_			= buffer_;
				tail_->data		= *pData;
				tail_->prev		= NULL;
				tail_->next		= NULL;
				head_			= buffer_;
			}
			mutex_.unlock();
		}
		else
		{
			return ;
		}
	}

	void push_front(T* pData)
	{
		if (pData) 
		{
			tail_prev_		= tail_;ddd

			mutex_.lock();
			Node*	pCur	= getHeadPrev();
			if (head_)
			{
				pCur->data		= *pData;
				pCur->next		= head_;
				head_->prev		= pCur;
				pCur->prev		= NULL;
				head_			= pCur;
#ifdef WIN32
				assert(tail_ != head_);
#endif
			}
			else
			{
				pCur->data		= *pData;
				pCur->next		= tail_;
				pCur->prev		= head_;
				head_			= pCur;
				tail_			= pCur;
			}
			mutex_.unlock();
		}
		else
		{
			return ;
		}
	}

	T* get_current_ptr()
	{
		bool bRet = mutex_.tryLock();

		if (bRet)	// At this moment,neither is updating the current node.
		{
			if (tail_)
			{
				T* data = &tail_->data;
				mutex_.unlock();
				return data;
			}
			else
			{
				mutex_.unlock();
				return NULL;
			}
		}
		else		// now other thread is updating the current node(tail_), in order to get the newest node, we get the current node previous.
		{
			Node* pNode = tail_prev_;
			if (pNode)
			{
				T* data = &pNode->data;
				//mutex_.unlock();	// zl 2013/08/08 when tryLock() return 0, mutex_ is not locked.so, don't lock here.
				return data;
			}
			else
			{
				//mutex_.unlock();	
				return NULL;
			}
		}
	}

	T* get_data()	// loop from the start position
	{
		//current_mutex_.lock();
		/* 2013/08/10 add TLS start */
#ifdef WIN32
		static __declspec(thread) Node* pCurrent = NULL;
#elif defined __GNUG__
		static __thread Node*	pCurrent	= NULL;
#endif
		/* 2013/08/10 add TLS end */
		bool			bRet		= false;

		if (pCurrent)
		{
			mutex_.lock();
			pCurrent				= pCurrent->next;
			if (pCurrent)
			{
				T*	data = &pCurrent->data;
				//current_mutex_.unlock();
				mutex_.unlock();
				return data;
			}
			else
			{
				mutex_.unlock();
				return NULL;
			}
		}
		else	// first time
		{
			if (head_)
			{
				mutex_.lock();
				pCurrent			= head_;
				mutex_.unlock();
				T*	data = &pCurrent->data;
				//current_mutex_.unlock();
				return data;
			}
			else
			{
				//current_mutex_.unlock();
				return NULL;
			}
		}
	}

private:
	// judge the data whether in the range.
	bool assertInRange(Node* data)
	{
		if (head_ && tail_)	// the list has member
		{
			if (&head_ >= &tail_)	// head is previous the tail
			{
				if ((data >= buffer_ && data <= &tail_)
					|| (data >= &head_ && data <= buffer_+size_-1)) 
				{
					return true;
				} 
				else 
				{
#if WIN32
					assert(0);
#endif
					return false;
				}
			}
			else	// tail is previous the head
			{
				if (data >= &head_ && data <= &tail_) 
				{
					return true;
				} 
				else 
				{
#if WIN32
					assert(0);
#endif
					return false;
				}
			}
		}
		else if (!head_ || !tail_) // the list has not any member
		{
#if WIN32
			assert(1);
#endif
			return false;
		}
	}

	Node* getHeadPrev()
	{
		Node*		pCur = NULL;

		if (head_) 
		{
			if (head_ != buffer_) {
				pCur = head_-1;
#ifdef WIN32
				assert(pCur != tail_);
#endif
			} else {
				pCur = buffer_+size_-1;
			}
		} 
		else 
		{
			pCur = buffer_;
		}

		return pCur;
	}
private:
	CBigList(const CBigList&);
	CBigList& operator=(const CBigList &);

private:
	int								size_;
	Node* const						buffer_;
	Node*							head_;
	Node*							tail_;
	Node*							tail_prev_;
	Mutex							mutex_;
	/* 2013/08/10 comment. add TLS, so there is no need to use lock start */
	//Mutex							current_mutex_;
	/* 2013/08/10 comment. add TLS, so there is no need to use lock end */
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值