added the HashList class
This commit is contained in:
		
							
								
								
									
										507
									
								
								qse/include/qse/cmn/HashList.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										507
									
								
								qse/include/qse/cmn/HashList.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,507 @@ | |||||||
|  | /* | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  |     Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved. | ||||||
|  |  | ||||||
|  |     Redistribution and use in source and binary forms, with or without | ||||||
|  |     modification, are permitted provided that the following conditions | ||||||
|  |     are met: | ||||||
|  |     1. Redistributions of source code must retain the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer. | ||||||
|  |     2. Redistributions in binary form must reproduce the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer in the | ||||||
|  |        documentation and/or other materials provided with the distribution. | ||||||
|  |  | ||||||
|  |     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||||||
|  |     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||||
|  |     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||||
|  |     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  |     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||||
|  |     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||||
|  |     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||||
|  |     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||||
|  |     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||||
|  |     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef _QSE_CMN_HASHLIST_CLASS_ | ||||||
|  | #define _QSE_CMN_HASHLIST_CLASS_ | ||||||
|  |  | ||||||
|  | #include <qse/Hashable.hpp> | ||||||
|  | #include <qse/cmn/LinkedList.hpp> | ||||||
|  |  | ||||||
|  | ///////////////////////////////// | ||||||
|  | QSE_BEGIN_NAMESPACE(QSE) | ||||||
|  | ///////////////////////////////// | ||||||
|  |  | ||||||
|  | template<typename T> | ||||||
|  | struct HashListHasher | ||||||
|  | { | ||||||
|  | 	qse_size_t operator() (const T& v) const | ||||||
|  | 	{ | ||||||
|  | 		return v.hashCode(); | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template<typename T> | ||||||
|  | struct HashListComparator | ||||||
|  | { | ||||||
|  | 	bool operator() (const T& v1, const T& v2) const | ||||||
|  | 	{ | ||||||
|  | 		return v1 == v2; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // TODO: use MPOLL for nodes??? | ||||||
|  |  | ||||||
|  | template <typename T, typename MPOOL = Mpool, typename HASHER = HashListHasher<T>, typename COMPARATOR = HashListComparator<T> > | ||||||
|  | class HashList | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	typedef LinkedList<T,MPOOL> DatumList; | ||||||
|  | 	typedef typename DatumList::Node Node; | ||||||
|  | 	typedef HashList<T,MPOOL,HASHER,COMPARATOR> SelfType; | ||||||
|  |  | ||||||
|  | 	HashList ( | ||||||
|  | 		qse_size_t node_capacity = 10,  | ||||||
|  | 		qse_size_t load_factor = 75,  | ||||||
|  | 		qse_size_t mpb_size = 0)/*: datum_list (mpb_size)*/ | ||||||
|  | 	{ | ||||||
|  | 		this->nodes = QSE_NULL; | ||||||
|  | 		this->node_capacity = 0; | ||||||
|  | 		this->datum_list = QSE_NULL; | ||||||
|  |  | ||||||
|  | 		try  | ||||||
|  | 		{ | ||||||
|  | 			this->nodes = new Node*[node_capacity << 1]; | ||||||
|  |  | ||||||
|  | 			this->node_capacity = node_capacity; | ||||||
|  | 			for (qse_size_t i = 0; i < (node_capacity << 1); i++)  | ||||||
|  | 			{ | ||||||
|  | 				this->nodes[i] = QSE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			this->datum_list = new DatumList (mpb_size); | ||||||
|  | 		} | ||||||
|  | 		catch (...)  | ||||||
|  | 		{ | ||||||
|  | 			if (this->nodes)  | ||||||
|  | 			{ | ||||||
|  | 				delete[] this->nodes; | ||||||
|  | 				this->node_capacity = 0; | ||||||
|  | 				this->nodes = QSE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (this->datum_list)  | ||||||
|  | 			{ | ||||||
|  | 				delete this->datum_list; | ||||||
|  | 				this->datum_list = QSE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			throw; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		this->load_factor = load_factor; | ||||||
|  | 		this->threshold   = node_capacity * load_factor / 100; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	HashList (const SelfType& list)/*: datum_list (list.datum_list.getMPBlockSize()) */ | ||||||
|  | 	{ | ||||||
|  | 		this->nodes = QSE_NULL; | ||||||
|  | 		this->node_capacity = 0; | ||||||
|  | 		this->datum_list = QSE_NULL; | ||||||
|  |  | ||||||
|  | 		try  | ||||||
|  | 		{ | ||||||
|  | 			this->nodes = new Node*[list.node_capacity << 1]; | ||||||
|  | 			this->node_capacity = list.node_capacity; | ||||||
|  | 			for (qse_size_t i = 0; i < list.node_capacity << 1; i++) | ||||||
|  | 			{ | ||||||
|  | 				this->nodes[i] = QSE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			this->datum_list = new DatumList (list.datum_list->getMPBlockSize()); | ||||||
|  | 		} | ||||||
|  | 		catch (...)  | ||||||
|  | 		{ | ||||||
|  | 			if (this->nodes) | ||||||
|  | 			{ | ||||||
|  | 				delete[] this->nodes; | ||||||
|  | 				this->node_capacity = 0; | ||||||
|  | 				this->nodes = QSE_NULL; | ||||||
|  | 			} | ||||||
|  | 			if (this->datum_list) | ||||||
|  | 			{ | ||||||
|  | 				delete this->datum_list; | ||||||
|  | 				this->datum_list = QSE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			throw; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		this->load_factor = list.load_factor; | ||||||
|  | 		this->threshold   = list.threshold; | ||||||
|  |  | ||||||
|  | 		for (qse_size_t i = 0; i < list.node_capacity; i++)  | ||||||
|  | 		{ | ||||||
|  | 			qse_size_t head = i << 1; | ||||||
|  | 			qse_size_t tail = head + 1; | ||||||
|  |  | ||||||
|  | 			Node* np = list.nodes[head]; | ||||||
|  | 			if (!np) continue; | ||||||
|  | 			 | ||||||
|  | 			do  | ||||||
|  | 			{ | ||||||
|  | 				copy_datum (np, this->node_capacity, this->nodes, this->datum_list); | ||||||
|  | 				if (np == list.nodes[tail]) break; | ||||||
|  | 				np = np->getNextNode (); | ||||||
|  | 			}  | ||||||
|  | 			while (1); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	~HashList () | ||||||
|  | 	{ | ||||||
|  | 		this->clear (); | ||||||
|  | 		if (this->nodes) delete[] this->nodes; | ||||||
|  | 		if (this->datum_list) delete this->datum_list; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	SelfType& operator= (const SelfType& list) | ||||||
|  | 	{ | ||||||
|  | 		this->clear (); | ||||||
|  |  | ||||||
|  | 		for (qse_size_t i = 0; i < list.node_capacity; i++) | ||||||
|  | 		{ | ||||||
|  | 			qse_size_t head = i << 1; | ||||||
|  | 			qse_size_t tail = head + 1; | ||||||
|  |  | ||||||
|  | 			Node* np = list.nodes[head]; | ||||||
|  | 			if (np == QSE_NULL) continue; | ||||||
|  | 			 | ||||||
|  | 			do  | ||||||
|  | 			{ | ||||||
|  | 				copy_datum (np, this->node_capacity, this->nodes, this->datum_list); | ||||||
|  | 				if (np == list.nodes[tail]) break; | ||||||
|  | 				np = np->getNextNode (); | ||||||
|  | 			}  | ||||||
|  | 			while (1); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return *this; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  | 	Node* insert_value (const T& datum, bool overwrite = true) | ||||||
|  | 	{ | ||||||
|  | 		qse_size_t hc, head, tail; | ||||||
|  | 		Node* np; | ||||||
|  |  | ||||||
|  | 		hc = this->hasher(datum) % this->node_capacity; | ||||||
|  | 		head = hc << 1; tail = head + 1; | ||||||
|  |  | ||||||
|  | 		np = this->nodes[head]; | ||||||
|  | 		if (np)  | ||||||
|  | 		{ | ||||||
|  | 			do  | ||||||
|  | 			{ | ||||||
|  | 				T& t = np->value; | ||||||
|  | 				if (this->comparator(datum, t))  | ||||||
|  | 				{ | ||||||
|  | 					if (!overwrite) return QSE_NULL; | ||||||
|  | 					t = datum; | ||||||
|  | 					return np; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				if (np == this->nodes[tail]) break; | ||||||
|  | 				np = np->getNextNode (); | ||||||
|  | 			} | ||||||
|  | 			while (1);  | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (datum_list->getSize() >= threshold)  | ||||||
|  | 		{ | ||||||
|  | 			this->rehash (); | ||||||
|  | 			hc = this->hasher(datum) % this->node_capacity; | ||||||
|  | 			head = hc << 1; tail = head + 1; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (nodes[head] == QSE_NULL)  | ||||||
|  | 		{ | ||||||
|  | 			this->nodes[head] = this->datum_list->insertValue (QSE_NULL, datum); | ||||||
|  | 			this->nodes[tail] = this->nodes[head]; | ||||||
|  | 		} | ||||||
|  | 		else  | ||||||
|  | 		{ | ||||||
|  | 			this->nodes[head] = datum_list->insertValue (this->nodes[head], datum); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return this->nodes[head]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | public: | ||||||
|  | 	Node* insert (const T& datum) | ||||||
|  | 	{ | ||||||
|  | 		return this->insert_value (datum, false); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Node* upsert (const T& datum) | ||||||
|  | 	{ | ||||||
|  | 		return this->insert_value (datum, true); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  | 	const Node* find_node (const T& datum) const | ||||||
|  | 	{ | ||||||
|  | 		qse_size_t hc, head, tail; | ||||||
|  | 		Node* np; | ||||||
|  |  | ||||||
|  | 		hc = this->hasher(datum) % this->node_capacity; | ||||||
|  | 		head = hc << 1; tail = head + 1; | ||||||
|  |  | ||||||
|  | 		np = this->nodes[head]; | ||||||
|  | 		if (np)  | ||||||
|  | 		{ | ||||||
|  | 			do  | ||||||
|  | 			{ | ||||||
|  | 				T& t = np->value; | ||||||
|  | 				if (datum == t) return np; | ||||||
|  | 				if (np == this->nodes[tail]) break; | ||||||
|  | 				np = np->getNextNode (); | ||||||
|  | 			} | ||||||
|  | 			while (1); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return QSE_NULL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | public: | ||||||
|  | 	Node* findNode (const T& datum) | ||||||
|  | 	{ | ||||||
|  | 		return (Node*)this->find_node (datum); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	const Node* findNode (const T& datum) const | ||||||
|  | 	{ | ||||||
|  | 		return this->find_node (datum); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	T* findValue (const T& datum) | ||||||
|  | 	{ | ||||||
|  | 		Node* b = this->findNode (datum); | ||||||
|  | 		if (!b) return QSE_NULL; | ||||||
|  | 		return &b->value; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	const T* findValue (const T& datum) const | ||||||
|  | 	{ | ||||||
|  | 		const Node* b = this->findNode (datum); | ||||||
|  | 		if (!b) return QSE_NULL; | ||||||
|  | 		return &b->value; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool isEmpty () const  | ||||||
|  | 	{ | ||||||
|  | 		return this->datum_list->isEmpty(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool contains (const T& datum) const | ||||||
|  | 	{ | ||||||
|  | 		return this->findNode (datum) != QSE_NULL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	int remove (const T& datum) | ||||||
|  | 	{ | ||||||
|  | 		qse_size_t hc, head, tail; | ||||||
|  | 		Node* np; | ||||||
|  |  | ||||||
|  | 		hc = this->hasher(datum) % this->node_capacity; | ||||||
|  | 		head = hc << 1; tail = head + 1; | ||||||
|  |  | ||||||
|  | 		np = this->nodes[head]; | ||||||
|  | 		if (np)  | ||||||
|  | 		{ | ||||||
|  | 			do  | ||||||
|  | 			{ | ||||||
|  | 				T& t = np->value; | ||||||
|  | 				if (this->comparator(datum, t))  | ||||||
|  | 				{ | ||||||
|  | 					if (this->nodes[head] == this->nodes[tail]) | ||||||
|  | 					{ | ||||||
|  | 						QSE_ASSERT (np == this->nodes[head]); | ||||||
|  | 						this->nodes[head] = this->nodes[tail] = QSE_NULL; | ||||||
|  | 					} | ||||||
|  | 					else if (np == this->nodes[head]) | ||||||
|  | 					{ | ||||||
|  | 						this->nodes[head] = np->getNextNode(); | ||||||
|  | 					} | ||||||
|  | 					else if (np == this->nodes[tail]) | ||||||
|  | 					{  | ||||||
|  | 						this->nodes[tail] = np->getPrevNode(); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					this->datum_list->remove (np); | ||||||
|  | 					return 0; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				if (np == this->nodes[tail]) break; | ||||||
|  | 				np = np->getNextNode (); | ||||||
|  | 			}  | ||||||
|  | 			while (1); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void clear () | ||||||
|  | 	{ | ||||||
|  | 		for (qse_size_t i = 0; i < (this->node_capacity << 1); i++)  | ||||||
|  | 		{ | ||||||
|  | 			this->nodes[i] = QSE_NULL; | ||||||
|  | 		} | ||||||
|  | 		if (this->datum_list) this->datum_list->clear (); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Node* getHeadNode () const | ||||||
|  | 	{ | ||||||
|  | 		return datum_list->getHeadNode(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Node* getTaileNode () const | ||||||
|  | 	{ | ||||||
|  | 		return datum_list->getTailNode(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	typedef int (SelfType::*TraverseCallback) (Node* start, Node* cur); | ||||||
|  |  | ||||||
|  | 	void traverse (TraverseCallback callback, Node* start) | ||||||
|  | 	{ | ||||||
|  | 		Node* cur, *prev, * next; | ||||||
|  |  | ||||||
|  | 		cur = start; | ||||||
|  | 		while (cur)  | ||||||
|  | 		{ | ||||||
|  | 			prev = cur->getPrevNode (); | ||||||
|  | 			next = cur->getNextNode (); | ||||||
|  |  | ||||||
|  | 			int n = (this->*callback) (start, cur); | ||||||
|  |  | ||||||
|  | 			if (n > 0) cur = next; | ||||||
|  | 			else if (n < 0) cur = prev; | ||||||
|  | 			else break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	qse_size_t getCapacity() const | ||||||
|  | 	{ | ||||||
|  | 		return this->node_capacity; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	qse_size_t getSize () const | ||||||
|  | 	{ | ||||||
|  | 		return this->datum_list->getSize(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  | 	mutable qse_size_t node_capacity; | ||||||
|  | 	mutable Node** nodes; | ||||||
|  | 	mutable DatumList* datum_list; | ||||||
|  | 	mutable qse_size_t threshold; | ||||||
|  | 	qse_size_t load_factor; | ||||||
|  | 	HASHER hasher; | ||||||
|  | 	COMPARATOR comparator; | ||||||
|  |  | ||||||
|  | 	void rehash ()  | ||||||
|  | 	{ | ||||||
|  | 		// Move nodes around instead of values to prevent | ||||||
|  | 		// existing values from being copied over and destroyed. | ||||||
|  | 		// this incurs less number of memory allocations also. | ||||||
|  | 		SelfType temp (this->node_capacity << 1, this->load_factor, this->datum_list->getMPBlockSize()); | ||||||
|  | 		Node* p = this->datum_list->getHeadNode(); | ||||||
|  | 		while (p) | ||||||
|  | 		{ | ||||||
|  | 			Node* next = p->getNextNode(); | ||||||
|  |  | ||||||
|  | 			// p->value must be a unique value in the existing hashed list. | ||||||
|  | 			// i can safely skip checking existing values. | ||||||
|  |  | ||||||
|  | 			// detach the existing node. | ||||||
|  | 			Node* pp = this->datum_list->yield (p, true); | ||||||
|  |  | ||||||
|  | 			// get the hash code using the new capacity | ||||||
|  | 			qse_size_t hc, head, tail; | ||||||
|  | 			hc = this->hasher(pp->value) % temp.node_capacity; | ||||||
|  | 			head = hc << 1; tail = head + 1; | ||||||
|  |  | ||||||
|  | 			// insert the detached node to the new temporary list | ||||||
|  | 			if (temp.nodes[head])  | ||||||
|  | 			{ | ||||||
|  | 				temp.nodes[head] = temp.datum_list->insertNode (temp.nodes[head], pp); | ||||||
|  | 			} | ||||||
|  | 			else  | ||||||
|  | 			{ | ||||||
|  | 				temp.nodes[head] = temp.datum_list->insertNode (QSE_NULL, pp); | ||||||
|  | 				temp.nodes[tail] = temp.nodes[head]; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			p = next; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// all nodes must have been popped out. | ||||||
|  | 		QSE_ASSERT (this->datum_list->getSize() <= 0); | ||||||
|  |  | ||||||
|  | 		// clear the node pointers by force as no nodes exist in the old list. | ||||||
|  | 		for (qse_size_t i = 0; i < (this->node_capacity << 1); i++)  | ||||||
|  | 		{ | ||||||
|  | 			this->nodes[i] = QSE_NULL; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// swap the contents | ||||||
|  | 		qse_size_t temp_capa = temp.node_capacity; | ||||||
|  | 		Node** temp_nodes = temp.nodes; | ||||||
|  | 		DatumList* temp_datum_list = temp.datum_list; | ||||||
|  | 		qse_size_t temp_threshold = temp.threshold; | ||||||
|  | 		qse_size_t temp_load_factor = temp.load_factor; | ||||||
|  |  | ||||||
|  | 		temp.node_capacity = this->node_capacity; | ||||||
|  | 		temp.nodes = this->nodes; | ||||||
|  | 		temp.datum_list = this->datum_list; | ||||||
|  | 		temp.threshold = this->threshold; | ||||||
|  | 		temp.load_factor = this->load_factor; | ||||||
|  |  | ||||||
|  | 		this->node_capacity = temp_capa; | ||||||
|  | 		this->nodes = temp_nodes; | ||||||
|  | 		this->datum_list = temp_datum_list; | ||||||
|  | 		this->threshold = temp_threshold; | ||||||
|  | 		this->load_factor = temp_load_factor; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void copy_datum ( | ||||||
|  | 		Node* np, qse_size_t new_node_capa, | ||||||
|  | 		Node** new_nodes, DatumList* new_datum_list) const | ||||||
|  | 	{ | ||||||
|  | 		T& t = np->value; | ||||||
|  |  | ||||||
|  | 		qse_size_t hc = this->hasher(t) % new_node_capa; | ||||||
|  | 		qse_size_t head = hc << 1; | ||||||
|  | 		qse_size_t tail = head + 1; | ||||||
|  |  | ||||||
|  | 		if (new_nodes[head] == QSE_NULL)  | ||||||
|  | 		{ | ||||||
|  | 			new_nodes[head] = new_datum_list->insertValue (QSE_NULL, t); | ||||||
|  | 			new_nodes[tail] = new_nodes[head]; | ||||||
|  | 		} | ||||||
|  | 		else  | ||||||
|  | 		{ | ||||||
|  | 			new_nodes[head] = new_datum_list->insertValue (new_nodes[head], t); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ///////////////////////////////// | ||||||
|  | QSE_END_NAMESPACE(QSE) | ||||||
|  | ///////////////////////////////// | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @ -141,7 +141,7 @@ public: | |||||||
|  |  | ||||||
| 	qse_size_t getMPBlockSize() const | 	qse_size_t getMPBlockSize() const | ||||||
| 	{ | 	{ | ||||||
| 		return this->mp.blockSize(); | 		return this->mp.getBlockSize(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool isMPEnabled () const | 	bool isMPEnabled () const | ||||||
| @ -280,7 +280,7 @@ public: | |||||||
| 		QSE_ASSERT (this->node_count > 0); | 		QSE_ASSERT (this->node_count > 0); | ||||||
|  |  | ||||||
| 		if (node->next) | 		if (node->next) | ||||||
| 			node->next->prev = node->next; | 			node->next->prev = node->prev; | ||||||
| 		else | 		else | ||||||
| 			this->tail_node = node->prev; | 			this->tail_node = node->prev; | ||||||
|  |  | ||||||
|  | |||||||
| @ -52,6 +52,6 @@ pkginclude_HEADERS = \ | |||||||
| if ENABLE_CXX | if ENABLE_CXX | ||||||
| pkginclude_HEADERS += \ | pkginclude_HEADERS += \ | ||||||
| 	Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \ | 	Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \ | ||||||
| 	LinkedList.hpp | 	LinkedList.hpp HashList.hpp | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | |||||||
| @ -52,7 +52,7 @@ build_triplet = @build@ | |||||||
| host_triplet = @host@ | host_triplet = @host@ | ||||||
| @ENABLE_CXX_TRUE@am__append_1 = \ | @ENABLE_CXX_TRUE@am__append_1 = \ | ||||||
| @ENABLE_CXX_TRUE@	Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \ | @ENABLE_CXX_TRUE@	Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \ | ||||||
| @ENABLE_CXX_TRUE@	LinkedList.hpp | @ENABLE_CXX_TRUE@	LinkedList.hpp HashList.hpp | ||||||
|  |  | ||||||
| subdir = include/qse/cmn | subdir = include/qse/cmn | ||||||
| DIST_COMMON = $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \ | DIST_COMMON = $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \ | ||||||
| @ -91,7 +91,7 @@ am__pkginclude_HEADERS_DIST = alg.h chr.h cp949.h cp950.h dir.h dll.h \ | |||||||
| 	nwio.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h sck.h sio.h \ | 	nwio.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h sck.h sio.h \ | ||||||
| 	sll.h slmb.h str.h task.h time.h tio.h tmr.h tre.h uni.h uri.h \ | 	sll.h slmb.h str.h task.h time.h tio.h tmr.h tre.h uni.h uri.h \ | ||||||
| 	utf8.h xma.h Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp \ | 	utf8.h xma.h Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp \ | ||||||
| 	Mpool.hpp Mpoolable.hpp LinkedList.hpp | 	Mpool.hpp Mpoolable.hpp LinkedList.hpp HashList.hpp | ||||||
| am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; | am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; | ||||||
| am__vpath_adj = case $$p in \ | am__vpath_adj = case $$p in \ | ||||||
|     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ |     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user