added Mpool::swap().
fixed a bug in HashList::rehash() when the memory pool is enabled. added LinkedList::reverse()
This commit is contained in:
parent
890097af66
commit
37792be000
@ -199,6 +199,11 @@ public:
|
||||
if (this->datum_list) this->free_datum_list ();
|
||||
}
|
||||
|
||||
Mpool& getMpool ()
|
||||
{
|
||||
return this->datum_list->getMpool ();
|
||||
}
|
||||
|
||||
SelfType& operator= (const SelfType& list)
|
||||
{
|
||||
this->clear ();
|
||||
@ -301,12 +306,12 @@ protected:
|
||||
|
||||
if (nodes[head] == QSE_NULL)
|
||||
{
|
||||
this->nodes[head] = this->datum_list->insertValue (QSE_NULL, datum);
|
||||
this->nodes[head] = this->datum_list->insert ((Node*)QSE_NULL, datum);
|
||||
this->nodes[tail] = this->nodes[head];
|
||||
}
|
||||
else
|
||||
{
|
||||
this->nodes[head] = datum_list->insertValue (this->nodes[head], datum);
|
||||
this->nodes[head] = datum_list->insert (this->nodes[head], datum);
|
||||
}
|
||||
|
||||
return this->nodes[head];
|
||||
@ -467,7 +472,13 @@ protected:
|
||||
// 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->getMmgr(), this->resizer(this->node_capacity), this->load_factor, this->datum_list->getMPBlockSize());
|
||||
Mpool& mpool = this->getMpool();
|
||||
|
||||
// Using the memory pool block size of 0 is OK because the nodes
|
||||
// to be inserted are yielded off the original list and inserted
|
||||
// without new allocation.
|
||||
//SelfType temp (this->getMmgr(), this->resizer(this->node_capacity), this->load_factor, mpool.getBlockSize());
|
||||
SelfType temp (this->getMmgr(), this->resizer(this->node_capacity), this->load_factor, 0);
|
||||
Node* p = this->datum_list->getHeadNode();
|
||||
while (p)
|
||||
{
|
||||
@ -491,7 +502,7 @@ protected:
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.nodes[head] = temp.datum_list->insertNode (QSE_NULL, pp);
|
||||
temp.nodes[head] = temp.datum_list->insertNode ((Node*)QSE_NULL, pp);
|
||||
temp.nodes[tail] = temp.nodes[head];
|
||||
}
|
||||
|
||||
@ -507,7 +518,13 @@ protected:
|
||||
this->nodes[i] = QSE_NULL;
|
||||
}
|
||||
|
||||
// swap the contents
|
||||
// swapping the memory pool is a critical thing to do
|
||||
// especially when the memory pooling is enabled. the datum node in
|
||||
// 'temp' is actual allocated inside 'mpool' not inside temp.getMpool().
|
||||
// it is because yield() has been used for insertion into 'temp'.
|
||||
mpool.swap (temp.getMpool());
|
||||
|
||||
// swap the actual contents
|
||||
qse_size_t temp_capa = temp.node_capacity;
|
||||
Node** temp_nodes = temp.nodes;
|
||||
DatumList* temp_datum_list = temp.datum_list;
|
||||
@ -539,12 +556,12 @@ protected:
|
||||
|
||||
if (new_nodes[head] == QSE_NULL)
|
||||
{
|
||||
new_nodes[head] = new_datum_list->insertValue (QSE_NULL, t);
|
||||
new_nodes[head] = new_datum_list->insert ((Node*)QSE_NULL, t);
|
||||
new_nodes[tail] = new_nodes[head];
|
||||
}
|
||||
else
|
||||
{
|
||||
new_nodes[head] = new_datum_list->insertValue (new_nodes[head], t);
|
||||
new_nodes[head] = new_datum_list->insert (new_nodes[head], t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,8 @@ public:
|
||||
T value; // you can use this variable or accessor functions below
|
||||
|
||||
protected:
|
||||
SelfType* next;
|
||||
SelfType* prev;
|
||||
SelfType* next;
|
||||
|
||||
public:
|
||||
T& getValue () { return this->value; }
|
||||
@ -126,13 +126,13 @@ public:
|
||||
return saved;
|
||||
}
|
||||
|
||||
int operator== (const SelfType& it) const
|
||||
bool operator== (const SelfType& it) const
|
||||
{
|
||||
QSE_ASSERT (this->current != QSE_NULL);
|
||||
return this->current == it.current;
|
||||
}
|
||||
|
||||
int operator!= (const SelfType& it) const
|
||||
bool operator!= (const SelfType& it) const
|
||||
{
|
||||
QSE_ASSERT (this->current != QSE_NULL);
|
||||
return this->current != it.current;
|
||||
@ -143,6 +143,23 @@ public:
|
||||
return this->current != QSE_NULL;
|
||||
}
|
||||
|
||||
T& operator* () // dereference
|
||||
{
|
||||
return this->current->getValue();
|
||||
}
|
||||
|
||||
const T& operator* () const // dereference
|
||||
{
|
||||
return this->current->getValue();
|
||||
}
|
||||
|
||||
#if 0
|
||||
T* operator-> ()
|
||||
{
|
||||
return &this->current->getValue();
|
||||
}
|
||||
#endif
|
||||
|
||||
T& getValue ()
|
||||
{
|
||||
QSE_ASSERT (this->current != QSE_NULL);
|
||||
@ -247,14 +264,9 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
qse_size_t getMPBlockSize() const
|
||||
Mpool& getMpool ()
|
||||
{
|
||||
return this->mp.getBlockSize();
|
||||
}
|
||||
|
||||
bool isMPEnabled () const
|
||||
{
|
||||
return this->mp.isEnabled();
|
||||
return this->mp;
|
||||
}
|
||||
|
||||
qse_size_t getSize () const
|
||||
@ -267,17 +279,15 @@ public:
|
||||
return this->node_count == 0;
|
||||
}
|
||||
|
||||
bool contains (const T& value) const
|
||||
{
|
||||
return this->findFirstNode(value) != QSE_NULL;
|
||||
}
|
||||
|
||||
// insert an externally created node.
|
||||
// may need to take extra care when using this method.
|
||||
/// The insertNode() function inserts an externally created \a node
|
||||
/// before the node at the given position \a pos. If \a pos is QSE_NULL,
|
||||
/// the \a node is inserted at the back of the list. You must take extra
|
||||
/// care when using this function.
|
||||
Node* insertNode (Node* pos, Node* node)
|
||||
{
|
||||
if (pos == QSE_NULL)
|
||||
{
|
||||
// add to the back
|
||||
if (this->node_count == 0)
|
||||
{
|
||||
QSE_ASSERT (head_node == QSE_NULL);
|
||||
@ -293,6 +303,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert 'node' before the node at the given position 'pos'.
|
||||
node->next = pos;
|
||||
node->prev = pos->prev;
|
||||
if (pos->prev) pos->prev->next = node;
|
||||
@ -305,59 +316,22 @@ public:
|
||||
}
|
||||
|
||||
// create a new node to hold the value and insert it.
|
||||
Node* insertValue (Node* pos, const T& value)
|
||||
Node* insert (Node* pos, const T& value)
|
||||
{
|
||||
Node* node = new(&this->mp) Node(value);
|
||||
return this->insertNode (pos, node);
|
||||
}
|
||||
|
||||
T& insert (Node* node, const T& value)
|
||||
Node* prepend (const T& value)
|
||||
{
|
||||
return this->insertValue(node, value)->value;
|
||||
}
|
||||
|
||||
T& insert (qse_size_t index, const T& value)
|
||||
{
|
||||
QSE_ASSERT (index <= node_count);
|
||||
|
||||
if (index >= node_count)
|
||||
{
|
||||
// insert it at the back
|
||||
return this->insert ((Node*)QSE_NULL, value);
|
||||
}
|
||||
|
||||
return this->insert (this->getNodeAt(index), value);
|
||||
}
|
||||
|
||||
T& prepend (const T& value)
|
||||
{
|
||||
// same as prependValue()
|
||||
return this->insert (this->head_node, value);
|
||||
}
|
||||
T& append (const T& value)
|
||||
|
||||
Node* append (const T& value)
|
||||
{
|
||||
// same as appendValue()
|
||||
return this->insert ((Node*)QSE_NULL, value);
|
||||
}
|
||||
|
||||
Node* prependNode (Node* node)
|
||||
{
|
||||
return this->insertNode (head_node, node);
|
||||
}
|
||||
Node* appendNode (Node* node)
|
||||
{
|
||||
return this->insertNode ((Node*)QSE_NULL, node);
|
||||
}
|
||||
|
||||
Node* prependValue (const T& value)
|
||||
{
|
||||
return this->insertValue (this->head_node, value);
|
||||
}
|
||||
Node* appendValue (const T& value)
|
||||
{
|
||||
return this->insertValue ((Node*)QSE_NULL, value);
|
||||
}
|
||||
|
||||
void prependAll (const SelfType& list)
|
||||
{
|
||||
Node* n = list.tail_node;
|
||||
@ -435,6 +409,7 @@ public:
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// remove a node from the list and free it.
|
||||
void remove (Node* node)
|
||||
{
|
||||
@ -446,20 +421,6 @@ public:
|
||||
::operator delete (node, &this->mp);
|
||||
}
|
||||
|
||||
void remove (qse_size_t index)
|
||||
{
|
||||
QSE_ASSERT (index < node_count);
|
||||
|
||||
Node* np = this->head_node;
|
||||
while (index > 0)
|
||||
{
|
||||
np = np->next;
|
||||
index--;
|
||||
}
|
||||
|
||||
this->remove (np);
|
||||
}
|
||||
|
||||
Node* yieldByValue (const T& value, bool clear_links = true)
|
||||
{
|
||||
Node* p = this->findFirstNode (value);
|
||||
@ -611,7 +572,7 @@ public:
|
||||
|
||||
qse_size_t findLastIndex (const T& value) const
|
||||
{
|
||||
qse_size_t index = node_count;
|
||||
qse_size_t index = this->node_count;
|
||||
for (Node* p = tail_node; p; p = p->prev)
|
||||
{
|
||||
index--;
|
||||
@ -647,10 +608,20 @@ public:
|
||||
this->mp.dispose ();
|
||||
}
|
||||
|
||||
//void reverse ()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
/// The reverse() function reverses the order of nodes.
|
||||
void reverse ()
|
||||
{
|
||||
if (this->node_count > 0)
|
||||
{
|
||||
Node* head = this->head_node;
|
||||
QSE_ASSERT (head != QSE_NULL);
|
||||
while (head->next)
|
||||
{
|
||||
Node* next_node = this->yield (head->next, false);
|
||||
this->insertNode (this->head_node, next_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef int (SelfType::*TraverseCallback) (Node* start, Node* cur);
|
||||
|
||||
@ -674,8 +645,16 @@ public:
|
||||
|
||||
Iterator getIterator (qse_size_t index = 0) const
|
||||
{
|
||||
if (this->node_count <= 0)
|
||||
{
|
||||
return Iterator (QSE_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index >= this->node_count) index = this->node_count - 1;
|
||||
return Iterator (this->getNodeAt(index));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
MPOOL mp;
|
||||
|
@ -56,30 +56,33 @@ public:
|
||||
void dispose (void* ptr);
|
||||
void dispose ();
|
||||
|
||||
inline bool isEnabled () const
|
||||
bool isEnabled () const
|
||||
{
|
||||
return this->datum_size > 0 && this->block_size > 0;
|
||||
}
|
||||
inline bool isDisabled () const
|
||||
|
||||
bool isDisabled () const
|
||||
{
|
||||
return this->datum_size <= 0 || this->block_size <= 0;
|
||||
}
|
||||
|
||||
inline qse_size_t getDatumSize () const
|
||||
qse_size_t getDatumSize () const
|
||||
{
|
||||
return this->datum_size;
|
||||
}
|
||||
|
||||
inline qse_size_t getBlockSize () const
|
||||
qse_size_t getBlockSize () const
|
||||
{
|
||||
return this->block_size;
|
||||
}
|
||||
|
||||
inline void setBlockSize (qse_size_t blockSize)
|
||||
void setBlockSize (qse_size_t blockSize)
|
||||
{
|
||||
this->block_size = blockSize;
|
||||
}
|
||||
|
||||
int swap (Mpool& mpool);
|
||||
|
||||
#if defined(QSE_DEBUG_MPOOL)
|
||||
qse_size_t nalloc;
|
||||
qse_size_t navail;
|
||||
@ -97,6 +100,8 @@ protected:
|
||||
Chain* next;
|
||||
};
|
||||
|
||||
// NOTE: whenever you add new member variables, make sure to
|
||||
// update the swap() function accordingly
|
||||
Block* mp_blocks;
|
||||
Chain* free_list;
|
||||
qse_size_t datum_size;
|
||||
|
@ -132,6 +132,50 @@ Mpool::Block* Mpool::add_block ()
|
||||
return block;
|
||||
}
|
||||
|
||||
int Mpool::swap (Mpool& mpool)
|
||||
{
|
||||
// this function is sensitive to member variables changes.
|
||||
// whenever you add new member variables, this function require
|
||||
// relevant changes.
|
||||
|
||||
if (this->getMmgr() != mpool.getMmgr())
|
||||
{
|
||||
// disallow to swap contents if memory managers are different.
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (this != &mpool)
|
||||
{
|
||||
#if defined(QSE_DEBUG_MPOOL)
|
||||
qse_size_t org_nalloc = this->nalloc;
|
||||
qse_size_t org_navail = this->navail;
|
||||
|
||||
this->nalloc = mpool.nalloc;
|
||||
this->navail = mpool.navail;
|
||||
|
||||
mpool.nalloc = org_nalloc;
|
||||
mpool.navail = org_navail;
|
||||
#endif
|
||||
|
||||
Block* org_mp_blocks = this->mp_blocks;
|
||||
Chain* org_free_list = this->free_list;
|
||||
qse_size_t org_datum_size = this->datum_size;
|
||||
qse_size_t org_block_size = this->block_size;
|
||||
|
||||
this->mp_blocks = mpool.mp_blocks;
|
||||
this->free_list = mpool.free_list;
|
||||
this->datum_size = mpool.datum_size;
|
||||
this->block_size = mpool.block_size;
|
||||
|
||||
mpool.mp_blocks = org_mp_blocks;
|
||||
mpool.free_list = org_free_list;
|
||||
mpool.datum_size = org_datum_size;
|
||||
mpool.block_size = org_block_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_END_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user