把ACE的ACE_Hash_Map_ManagerEx改写了一下

在写dl engine的时候,一直不想依赖于其它库,但hash map这种常用的map肯定会经常用到,而stl的hash_map非线程安全,就打算自已把stl 的hash map或者ACE的hash map改写一下。因为最近一直在用ACE做项目,对ACE_Hash_Map_ManagerEx比较熟悉,就把它的源码看了几遍,发现ACE的hash map和stl的实现差不多,都是用桶开链法实现,不同点就在于ace的hash map好像没有在hash负载较高的时候,像stl那样会重新找一个接近元素数量的质数再重新分配(不知道我有没有看漏)。下面源码把只是把ace hash map常用的方法改写,不常用的干掉。只实现一部分功能。而类型萃取type_trait这些都没改写。因为我没用到,有用到的时候再写
/*
 * hash_map.hpp
 *
 *  Created on: 2012-7-27
 *      Author: QS
 */

#ifndef HASH_MAP_HPP_
#define HASH_MAP_HPP_
#include "hash_map_entry.hpp"
#include "hash_map_iterator_base.hpp"
#include "hash_map_algorithm.hpp"
#include "../lock/RWLock.h"
#include "../Util.h"
#include <strings.h>
#include <stdlib.h>
namespace DL
{

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
class hash_map
{

	friend class hash_map_iterator_base<Key, Value, Lock, Hash, Equal> ;
public:
	typedef Key key_type;
	typedef Value date_type;

	typedef hash_map_entry<Key, Value> value_type;
	typedef value_type &reference;
	typedef value_type const &const_reference;
	typedef value_type *pointer;
	typedef value_type const *const_pointer;
	typedef ptrdiff_t difference_type;
	typedef size_t size_type;

	typedef hash_map_iterator<Key, Value, Lock, Hash, Equal> iterator;
	typedef hash_map_const_iterator<Key, Value, Lock, Hash, Equal> const_iterator;

public:
	hash_map(int init_size);
	~hash_map();

	int bind(Key key, Value value);
	int unbind(Key key);
	int unbind_all(void);

	int find(const Key &key, Value &value);

	iterator begin(void);
	iterator end(void);
	const_iterator begin(void) const;
	const_iterator end(void) const;

	Lock &mutex(void);

protected:

	int __find_location(const Key &key, hash_map_entry<Key, Value> *&entry, int &loc);
	int __bind(Key key, Value value);
	int __unbind(Key key);
	int __unbind_all(void);
	int __find(const Key &key, Value &value);

	int hash(Key key);
	int equal(const Key &key_one, const Key &key_two);

	int create_bucket(int size);
private:
	int __total_size;
	int __cur_size;
	Lock __lock;
	Hash __hash;
	Equal __compare;
	DL::hash_map_entry<Key, Value> *__table;
};

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
hash_map<Key, Value, Lock, Hash, Equal>::hash_map(int init_size) :
	__total_size(0), __cur_size(0)
{
	this->create_bucket(init_size);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
hash_map<Key, Value, Lock, Hash, Equal>::~hash_map()
{
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::create_bucket(int size)
{
	int bytes = size * sizeof(hash_map_entry<Key, Value> );
	this->__table = (hash_map_entry<Key, Value>*) malloc(bytes);
	this->__total_size = size;

	for (int i = 0; i < this->__total_size; i++)
	{
		new (&__table[i]) hash_map_entry<Key, Value> (&__table[i], &__table[i]);
	}
	return 0;
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::bind(Key key, Value value)
{
	//lock
	WriteGurad<Lock> lock(this->__lock);
	return this->__bind(key, value);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::unbind(Key key)
{
	//lock
	WriteGurad<Lock> lock(this->__lock);
	return this->__unbind(key);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::unbind_all(void)
{
	//lock
	WriteGurad<Lock> lock(this->__lock);
	return this->__unbind_all();
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::find(const Key &key, Value &value)
{
	//lock
	ReadGurad<Lock> lock(this->__lock);
	return this->__find(key, value);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
typename hash_map<Key, Value, Lock, Hash, Equal>::iterator hash_map<Key, Value, Lock, Hash, Equal>::begin(void)
{
	return iterator(*this);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
typename hash_map<Key, Value, Lock, Hash, Equal>::iterator hash_map<Key, Value, Lock, Hash, Equal>::end(void)
{
	return iterator(*this, 1);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
typename hash_map<Key, Value, Lock, Hash, Equal>::const_iterator hash_map<Key, Value, Lock, Hash, Equal>::begin(void) const
{
	return const_iterator(*this);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
typename hash_map<Key, Value, Lock, Hash, Equal>::const_iterator hash_map<Key, Value, Lock, Hash, Equal>::end(void) const
{
	return const_iterator(*this, 1);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::__find_location(const Key &key, hash_map_entry<Key, Value> *&entry, int &loc)
{
	JUDGE_RETURN(this->__total_size != 0,-1);
	loc = this->hash(key) % this->__total_size;

	hash_map_entry<Key, Value> *temp = this->__table[loc].__next;
	while (temp != &this->__table[loc] && this->equal(temp->__key, key) == 0)
	{
		temp = temp->__next;
	}

	if (temp == &this->__table[loc])
	{
		return -1;
	}
	else
	{
		entry = temp;
		return 0;
	}

	return 1;
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::__bind(Key key, Value value)
{
	int loc = 0;
	hash_map_entry<Key, Value> *entry = NULL;
	if (this->__find_location(key, entry, loc) == -1)
	{
		void *ptr = malloc(sizeof(hash_map_entry<Key, Value> ));
		bzero(ptr, sizeof(hash_map_entry<Key, Value> ));

		entry = new (ptr) hash_map_entry<Key, Value> (this->__table[loc].__next, &this->__table[loc]);
		entry->init(key, value);
		this->__table[loc].__next = entry;
		entry->__next->__prev = entry;
		this->__cur_size++;
		return 0;
	}
	return 1;
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::__unbind(Key key)
{
	hash_map_entry<Key, Value> *entry = NULL;
	int loc = 0;
	if (this->__find_location(key, entry, loc) == -1)
	{
		return -1;
	}
	entry->__next->__prev = entry->__prev;
	entry->__prev->__next = entry->__next;
	entry->~hash_map_entry<Key, Value> ();
	free(entry);
	this->__cur_size--;
	return 0;
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::__unbind_all(void)
{
	for (size_t i = 0; i < this->__total_size; i++)
	{
		hash_map_entry<Key, Value> *ptr = this->__table[i].__next;
		for (; ptr != &this->__table[i];)
		{
			hash_map_entry<Key, Value> *slot_ptr = ptr;
			ptr = ptr->__next;

			slot_ptr->~hash_map_entry<Key, Value> ();
			free(slot_ptr);
		}

		this->__table[i].__next_ = &this->__table[i];
		this->__table[i].__prev = &this->__table[i];
	}
	return 0;
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::__find(const Key &key, Value &value)
{
	hash_map_entry<Key, Value> *entry = 0;
	int loc = 0;
	if (this->__find_location(key, entry, loc) == -1)
	{
		return -1;
	}
	else
	{
		value = entry->__value;
		return 0;
	}
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::hash(Key key)
{
	return this->__hash(key);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
int hash_map<Key, Value, Lock, Hash, Equal>::equal(const Key &key_one, const Key &key_two)
{
	return this->__compare(key_one, key_two);
}

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
Lock &hash_map<Key, Value, Lock, Hash, Equal>::mutex(void)
{
	return this->__lock;
}

}
;
#endif /* HASH_MAP_HPP_ */
/*
 * hash_map_entry.hpp
 *
 *  Created on: 2012-7-27
 *      Author: QS
 */

#ifndef HASH_MAP_ENTRY_HPP_
#define HASH_MAP_ENTRY_HPP_

namespace DL
{
template<typename Key, typename Value>
class hash_map_entry
{
public:
	hash_map_entry(hash_map_entry<Key, Value> *next, hash_map_entry<Key, Value> *prev)
	{
		this->__next = next;
		this->__prev = prev;
	}
	virtual ~hash_map_entry()
	{

	}

	int init(Key key, Value value)
	{
		this->__key = key;
		this->__value = value;
		return 0;
	}

public:
	hash_map_entry<Key, Value> *__next;
	hash_map_entry<Key, Value> *__prev;
	Key __key;
	Value __value;

};
}
#endif /* HASH_MAP_ENTRY_HPP_ */

/*
 * hash_map_iterator_base.hpp
 *
 *  Created on: 2012-7-27
 *      Author: QS
 */

#ifndef HASH_MAP_ITERATOR_BASE_HPP_
#define HASH_MAP_ITERATOR_BASE_HPP_

namespace DL
{
template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
class hash_map;

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
class hash_map_iterator_base
{
public:
	typedef hash_map<Key, Value, Lock, Hash, Equal> container_type;
	typedef typename hash_map<Key, Value, Lock, Hash, Equal>::value_type value_type;
	typedef typename hash_map<Key, Value, Lock, Hash, Equal>::reference reference;
	typedef typename hash_map<Key, Value, Lock, Hash, Equal>::pointer pointer;
	typedef typename hash_map<Key, Value, Lock, Hash, Equal>::difference_type difference_type;

	hash_map_iterator_base(hash_map<Key, Value, Lock, Hash, Equal> &hash_map, bool head)
	{
		this->__hash_map = &hash_map;
		this->__index = head ? -1 : hash_map.__total_size;
		this->__next = &hash_map.__table[head ? 0 : hash_map.__total_size - 1];

	}
	hash_map_iterator_base(hash_map<Key, Value, Lock, Hash, Equal> &hash_map, hash_map_entry<Key, Value> *entry, int index);

	int next(hash_map_entry<Key, Value> *&entry) const
	{
		if (this->__hash_map->__table != 0 && this->__index < this->__hash_map->__total_size && this->__index >= 0 && this->__next
				!= &this->__hash_map->__table[this->__index])
		{
			entry = this->__next;
			return 1;
		}
		else
			return 0;
	}

	int done(void) const
	{
		return 0;
	}

	hash_map_entry<Key, Value> &operator*(void) const
	{
		hash_map_entry<Key, Value> *retv = 0;
		this->next(retv);
		return *retv;
	}
	hash_map_entry<Key, Value> *operator->(void) const
	{
		hash_map_entry<Key, Value> *retv = 0;
		this->next(retv);
		return retv;
	}

protected:
	int forward(void)
	{
		if (this->__hash_map == 0)
			return -1;
		else if (this->__index == -1)
		{
			this->__index++;
			return this->forward();
		}
		else if (this->__index >= this->__hash_map->__total_size)
			return 0;

		this->__next = this->__next->__next;
		if (this->__next == &this->__hash_map->__table[this->__index])
		{
			while (++this->__index < this->__hash_map->__total_size)
			{
				this->__next = this->__hash_map->__table[this->__index].__next;
				if (this->__next != &this->__hash_map->__table[this->__index])
					break;
			}
		}
		return this->__index < this->__hash_map->__total_size;
	}

	int reverse(void)
	{

		return 0;
	}

protected:
	hash_map<Key, Value, Lock, Hash, Equal> *__hash_map;
	int __index;
	hash_map_entry<Key, Value> *__next;
};

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
class hash_map_const_iterator_base
{
public:

	typedef hash_map<Key, Value, Lock, Hash, Equal> contianer_type;
	typedef typename contianer_type::value_type value_type;
	typedef typename contianer_type::reference reference;
	typedef typename contianer_type::pointer pointer;
	typedef typename contianer_type::difference_type difference_type;

	hash_map_const_iterator_base(contianer_type &hash_map, bool head)
	{

	}
	hash_map_const_iterator_base(contianer_type &hash_map, hash_map_entry<Key, Value> *entry, int index)
	{

	}

	int next(hash_map_entry<Key, Value> *&entry) const
	{
		return 0;
	}

	int done(void) const;

	hash_map_entry<Key, Value> &operator*(void) const;
	hash_map_entry<Key, Value> *operator->(void) const;
};

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
class hash_map_iterator: public hash_map_iterator_base<Key, Value, Lock, Hash, Equal>
{
public:
	typedef hash_map_iterator<Key, Value, Lock, Hash, Equal> self_type;
	typedef hash_map_iterator_base<Key, Value, Lock, Hash, Equal> super;
	typedef typename super::container_type container_type;

public:
	hash_map_iterator(container_type &container, int tail = 0) :
		super(container, tail == 0 ? 1 : 0)
	{
		if (tail == 0)
		{
			this->forward();
		}
	}

	self_type &operator++(void)
	{
		this->forward();
		return *this;
	}
	self_type operator++(int)
	{
		self_type retv(*this);
		++*this;
		return retv;
	}
	self_type &operator--(void)
	{
		this->reverse();
		return *this;
	}
	self_type operator--(int)
	{
		self_type retv(*this);
		--*this;
		return retv;
	}
};

template<typename Key, typename Value, typename Lock, typename Hash, typename Equal>
class hash_map_const_iterator: public hash_map_const_iterator_base<Key, Value, Lock, Hash, Equal>
{
public:
	typedef hash_map_const_iterator<Key, Value, Lock, Hash, Equal> self_type;
	typedef hash_map_const_iterator_base<Key, Value, Lock, Hash, Equal> super;
	typedef typename super::container_type container_type;

public:
	hash_map_const_iterator(container_type &container, int tail = 0) :
		super(container, tail == 0 ? 1 : 0)
	{
		if (tail == 0)
		{
			this->forward();
		}
	}
};
}
;
#endif /* HASH_MAP_ITERATOR_BASE_HPP_ */

/*
 * hash_map_algorithm.hpp
 *
 *  Created on: 2012-8-7
 *      Author: QS
 */

#ifndef HASH_MAP_ALGORITHM_HPP_
#define HASH_MAP_ALGORITHM_HPP_

namespace DL
{
template<typename T>
class hash
{
public:
	int operator ()(const T &t) const
	{
		return static_cast<int> (t);
	}
};

template<typename T>
class equal
{
public:
	bool operator ()(const T &lhs, const T &rhs) const
	{
		return lhs == rhs;
	}
};

}
;

#endif /* HASH_MAP_ALGORITHM_HPP_ */


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值