bsl_sample_alloc.h 4.6 KB
Newer Older
W
wangguibao 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
/***************************************************************************
 * 
 * Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved
 * $Id: bsl_sample_alloc.h,v 1.5 2009/04/07 06:35:53 xiaowei Exp $ 
 * 
 **************************************************************************/
 
/**
 * @file bsl_sample_alloc.h
 * @author xiaowei(com@baidu.com)
 * @date 2008/07/12 14:24:41  / 2010/10/18 modified by zhujianwei
 * @version $Revision: 1.5 $ 
 * @brief 
 *  
 **/

/*
 *
 * 用来优化分定长块
 *
 */


#ifndef  __BSL_SAMPLE_ALLOC_H_
#define  __BSL_SAMPLE_ALLOC_H_

#include <bsl/utils/bsl_utils.h>

namespace bsl
{
/*
 * 这个是容器内部,如果需要优化大块内存分配
 * 可以调用这个模版重新获取内存
 * 属于容器内部数据
 * 链表和hash可能用得到
 *
 */

/**
 * 只能管理内存
 */

template <class _Alloc, size_t _Items>
class bsl_sample_alloc
{
public:
	typedef _Alloc _Base;
	typedef typename _Base::pool_type pool_type;
	typedef typename _Base::size_type size_type;
	typedef typename _Base::difference_type difference_type;
	typedef typename _Base::pointer pointer;
	typedef typename _Base::const_pointer const_pointer;
	typedef typename _Base::reference reference;
	typedef typename _Base::const_reference const_reference;
	typedef typename _Base::value_type value_type;	
	typedef bsl_sample_alloc<_Alloc, _Items> self;
	
	union node_type
	{
		char value[sizeof(value_type)];
		node_type *next;
	};

	struct large_type
	{
		large_type *next;
		node_type data[_Items];
	};

	typedef  typename _Base::template rebind<large_type>::other large_alloc;
	template <typename _Tp1>
	struct rebind {
	private:
		typedef typename _Base::template rebind<_Tp1>::other other_alloc;
	public:
		typedef bsl_sample_alloc<other_alloc, _Items> other;
	};

	static const bool recycle_space;// = true;
	static const bool thread_safe;// = false;

public:

	bsl_sample_alloc() { 
        create(); 
    }

	bsl_sample_alloc(const bsl_sample_alloc<_Alloc, _Items> & ) { 
        create(); 
    }

	~bsl_sample_alloc() { 
		destroy();
	}

	inline pointer allocate(size_type, void * = 0) {
		//if (__n < 2) {
			if (_freelst) {
				node_type *tmp = _freelst;
				_freelst = _freelst->next;
				return (pointer)tmp->value;
			}
			if (_blknum == 0 || _lg == 0) {
				large_type *lg = _alloc.allocate(1);
				if (lg == 0) return 0;
				_blknum = _Items;
				lg->next = _lg;
				_lg = lg;
			}
			return (pointer)_lg->data[--_blknum].value;	
		//} 
		//return _pool.allocate(__n, ptr);
		return 0;
	}

	inline void deallocate(pointer ptr, size_type ) {
		//if (__n < 2) {
			((node_type *)ptr)->next = _freelst;
			_freelst = (node_type *)ptr;
		//} else {
		//	_pool.deallocate(ptr, __n);
		//}
	}

private:
	large_alloc _alloc;
	//pool_type _pool;
	large_type * _lg;
	node_type *_freelst;
	size_type _blknum;

public:
	void swap(self & __other) {
		_alloc.swap(__other._alloc);
		std::swap(_lg, __other._lg);
		std::swap(_freelst, __other._freelst);
		std::swap(_blknum, __other._blknum);
	}

	void merge( self & __other){
		node_type *tmp = (node_type*)&_freelst;
		while(tmp->next)
			tmp = tmp->next;
		if(__other._lg)
		{
			for(size_type i = 0; i < __other._blknum; i++)
			{
				tmp->next = &(__other._lg->data[i]);
				tmp = tmp->next;
			}
			large_type *lg = (large_type*)&_lg;
			while(lg->next)
				lg = lg->next;
			lg->next = __other._lg;
		}
		tmp->next = __other._freelst;
		__other._lg = 0;
		__other._blknum = 0;
		__other._freelst = 0;		
	}

	int create() {
		_lg = 0;
		_freelst = 0;
		_blknum = 0;
		_alloc.create();
		//_pool.create();
        return 0;
	}

	int destroy() {
		large_type *ptr = _lg;
		while (_lg) {
			_lg = _lg->next;
			free (ptr);
			ptr = _lg;
		}
		_alloc.destroy();
		//_pool.destroy();
		return 0;
	}

	value_type * getp(pointer __p) const { return __p; }
};

template <class _Alloc, size_t _Items>
inline bool operator == (const bsl_sample_alloc < _Alloc, _Items > &, 
		const bsl_sample_alloc < _Alloc, _Items > &) {
	return false;
}
template <class _Alloc, size_t _Items, class _Alloc2>
inline bool operator == (const bsl_sample_alloc <_Alloc, _Items> &, const _Alloc2 &) {
	return false;
}

template < typename _Alloc, size_t _Items >
inline bool operator != (const bsl_sample_alloc < _Alloc, _Items > &, 
		const bsl_sample_alloc < _Alloc, _Items > &) {
	return true;
}

template <class _Alloc, size_t _Items, class _Alloc2>
inline bool operator != (const bsl_sample_alloc <_Alloc, _Items> &, const _Alloc2 &) {
	return true;
}

template <class _Alloc, size_t _Items>
const bool bsl_sample_alloc<_Alloc, _Items>::recycle_space = true;
template <class _Alloc, size_t _Items>
const bool bsl_sample_alloc<_Alloc, _Items>::thread_safe = false;

}

#endif  //__BSL_SAMPLE_ALLOC_H_

/* vim: set ts=4 sw=4 sts=4 tw=100 */