added to StrBase a special constructor that doesn't allocation a buffer.

added PtrString classes
added removeNode to HashList and HashTable.
added findNode to HashTable
This commit is contained in:
hyung-hwan 2017-08-30 13:50:02 +00:00
parent 211f5b014e
commit 559f965aa5
4 changed files with 226 additions and 48 deletions

View File

@ -581,31 +581,44 @@ public:
Node* np = this->heterofind_node<MT,MEQUALER> (datum, hc); Node* np = this->heterofind_node<MT,MEQUALER> (datum, hc);
if (np) if (np)
{ {
qse_size_t head, tail; this->remove_node (np, hc);
head = hc << 1; tail = head + 1;
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; return 0;
} }
return -1; return -1;
} }
void removeNode (Node* np)
{
T& datum = np->value;
qse_size_t hc = this->_hasher(datum) % this->node_capacity;
this->remove_node (np, hc);
}
private:
void remove_node (Node* np, qse_size_t hc)
{
qse_size_t head, tail;
head = hc << 1; tail = head + 1;
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);
}
public:
void clear (bool clear_mpool = false) void clear (bool clear_mpool = false)
{ {
for (qse_size_t i = 0; i < (this->node_capacity << 1); i++) for (qse_size_t i = 0; i < (this->node_capacity << 1); i++)

View File

@ -290,6 +290,16 @@ public:
return this->pair_list.clear (clear_mpool); return this->pair_list.clear (clear_mpool);
} }
void removeNode (PairNode* node)
{
this->pair_list.removeNode (node);
}
PairNode* findNode (const K& key)
{
return this->pair_list.findNode (key);
}
Iterator getIterator (qse_size_t index = 0) Iterator getIterator (qse_size_t index = 0)
{ {
return this->pair_list.getIterator (index); return this->pair_list.getIterator (index);

View File

@ -27,7 +27,6 @@
#ifndef _QSE_CMN_STRBASE_HPP_ #ifndef _QSE_CMN_STRBASE_HPP_
#define _QSE_CMN_STRBASE_HPP_ #define _QSE_CMN_STRBASE_HPP_
#include <qse/Hashable.hpp> #include <qse/Hashable.hpp>
#include <qse/Growable.hpp> #include <qse/Growable.hpp>
#include <qse/RefCounted.hpp> #include <qse/RefCounted.hpp>
@ -182,6 +181,42 @@ public:
this->ref_item (); this->ref_item ();
} }
StrBase (int capacity): Mmged(QSE_NULL)
{
if (capacity <= -1)
{
// this is a special constructor to instanatiate a string with no buffer.
// it is intended to be followed by truncate() for actual buffer allocation.
// all other functions except the destructor and the truncation() function
// are not aware of this special condition.
//
// String x(0);
// try { x.truncate(10); } catch (...) { return -1; }
// x.append ("xxx");
//
this->_item = QSE_NULL;
}
else
{
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(capacity), (const CHAR_TYPE*)QSE_NULL, 0);
this->ref_item ();
}
}
StrBase (Mmgr* mmgr, int capacity): Mmged(mmgr)
{
if (capacity <= -1)
{
// this is a special constructor to instanatiate a string with no buffer.
// it is intended to be followed by truncate() for actual buffer allocation.
this->_item = QSE_NULL;
}
else
{
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(capacity), (const CHAR_TYPE*)QSE_NULL, 0);
this->ref_item ();
}
}
StrBase (qse_size_t capacity): Mmged(QSE_NULL) StrBase (qse_size_t capacity): Mmged(QSE_NULL)
{ {
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(capacity), (const CHAR_TYPE*)QSE_NULL, 0); this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(capacity), (const CHAR_TYPE*)QSE_NULL, 0);
@ -240,7 +275,7 @@ public:
~StrBase () ~StrBase ()
{ {
this->deref_item (); if (this->_item) this->deref_item ();
} }
SelfType& operator= (const SelfType& str) SelfType& operator= (const SelfType& str)
@ -360,9 +395,14 @@ public:
return this->_item->buffer; return this->_item->buffer;
} }
const CHAR_TYPE* getData() const
{
return this->_item->buffer;
}
qse_size_t getHashCode () const qse_size_t getHashCode () const
{ {
// keep this in sync with getHashCode of BasePtrString<CHAR_TYPE> // keep this in sync with getHashCode() of PtrStrBase<CHAR_TYPE>
return Hashable::getHashCode ( return Hashable::getHashCode (
this->_item->buffer, this->_item->size * QSE_SIZEOF(CHAR_TYPE)); this->_item->buffer, this->_item->size * QSE_SIZEOF(CHAR_TYPE));
} }
@ -439,33 +479,45 @@ public:
// you can call truncate twice. for instance, // you can call truncate twice. for instance,
// str.truncate (1000). // str.truncate (1000).
// str.truncate (100). // str.truncate (100).
if (this->_item)
StringItem* old_item = QSE_NULL;
if (this->_item->isShared())
{ {
StringItem* t; StringItem* old_item = QSE_NULL;
if (new_size > this->_item->capacity) if (this->_item->isShared())
t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size)); {
else StringItem* t;
t = this->_item->copy (this->getMmgr());
old_item = this->_item; if (new_size > this->_item->capacity)
this->_item = t; t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size));
else
t = this->_item->copy (this->getMmgr());
old_item = this->_item;
this->_item = t;
this->ref_item ();
}
else if (new_size > this->_item->capacity)
{
StringItem* t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size));
old_item = this->_item;
this->_item = t;
this->ref_item ();;
}
this->_item->buffer[new_size] = NULL_CHAR;
this->_item->size = new_size;
if (old_item) this->deref_item (old_item);
}
else
{
// this is the only function that supports some use-cases
// of a string object created with no buffer at all.
// read comments in the special constructor
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(new_size), (const CHAR_TYPE*)QSE_NULL, 0);
this->ref_item (); this->ref_item ();
this->_item->buffer[new_size] = NULL_CHAR;
this->_item->size = new_size;
} }
else if (new_size > this->_item->capacity)
{
StringItem* t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size));
old_item = this->_item;
this->_item = t;
this->ref_item ();;
}
this->_item->buffer[new_size] = NULL_CHAR;
this->_item->size = new_size;
if (old_item) this->deref_item (old_item);
} }
// //
@ -992,7 +1044,6 @@ protected:
OPSET _opset; OPSET _opset;
RESIZER _resizer; RESIZER _resizer;
private: private:
qse_size_t adjust_desired_capacity (qse_size_t new_desired_capacity) qse_size_t adjust_desired_capacity (qse_size_t new_desired_capacity)
{ {
@ -1003,6 +1054,76 @@ private:
}; };
template <typename CHAR_TYPE, CHAR_TYPE NULL_CHAR, typename OPSET, typename RESIZER = StrBaseResizer>
class PtrStrBase
{
public:
typedef PtrStrBase<CHAR_TYPE,NULL_CHAR,OPSET,RESIZER> ThisType;
typedef StrBase<CHAR_TYPE,NULL_CHAR,OPSET,RESIZER> StringType;
PtrStrBase (): ptr (QSE_NULL), len (0) {}
PtrStrBase (const CHAR_TYPE* ptr): ptr (ptr)
{
this->len = this->_opset.getLength (ptr);
}
PtrStrBase (const CHAR_TYPE* ptr, qse_size_t len): ptr (ptr), len (len)
{
// do nothing
}
qse_size_t getHashCode () const
{
// keep this in sync with hashCode of StringType(StrBase)
return Hashable::getHashCode (this->ptr, this->len * QSE_SIZEOF(CHAR_TYPE));
}
bool operator== (const ThisType& ps) const
{
if (this->len != ps.len) return false;
return this->_opset.compare (this->ptr, ps.ptr, this->len) == 0;
}
bool operator!= (const ThisType& ps) const
{
return !this->operator== (ps);
}
bool operator== (const StringType& s) const
{
if (this->len != s.getLength()) return false;
return this->_opset.compare (this->ptr, s.getBuffer(), this->len) == 0;
}
bool operator!= (const StringType& s) const
{
return !this->operator== (s);
}
operator const CHAR_TYPE* () const
{
return this->ptr;
}
const CHAR_TYPE* getData() const
{
return this->ptr;
}
qse_size_t getLength() const
{
return this->len;
}
protected:
const CHAR_TYPE* ptr;
qse_size_t len;
OPSET _opset;
};
///////////////////////////////// /////////////////////////////////
QSE_END_NAMESPACE(QSE) QSE_END_NAMESPACE(QSE)
///////////////////////////////// /////////////////////////////////

View File

@ -181,11 +181,14 @@ struct MbStringOpset
class WcString: public StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset> class WcString: public StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset>
{ {
public: private:
typedef StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset> ParentType; typedef StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset> ParentType;
public:
WcString (): ParentType() {} WcString (): ParentType() {}
WcString (Mmgr* mmgr): ParentType(mmgr) {} WcString (Mmgr* mmgr): ParentType(mmgr) {}
WcString (int capacity): ParentType(capacity) {}
WcString (Mmgr* mmgr, int capacity): ParentType(mmgr, capacity) {}
WcString (qse_size_t capacity): ParentType(capacity) {} WcString (qse_size_t capacity): ParentType(capacity) {}
WcString (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {} WcString (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {}
WcString (const qse_wchar_t* str): ParentType(str) {} WcString (const qse_wchar_t* str): ParentType(str) {}
@ -207,11 +210,14 @@ public:
class MbString: public StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> class MbString: public StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset>
{ {
public: private:
typedef StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> ParentType; typedef StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> ParentType;
public:
MbString (): ParentType() {} MbString (): ParentType() {}
MbString (Mmgr* mmgr): ParentType(mmgr) {} MbString (Mmgr* mmgr): ParentType(mmgr) {}
MbString (int capacity): ParentType(capacity) {}
MbString (Mmgr* mmgr, int capacity): ParentType(mmgr, capacity) {}
MbString (qse_size_t capacity): ParentType(capacity) {} MbString (qse_size_t capacity): ParentType(capacity) {}
MbString (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {} MbString (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {}
MbString (const qse_mchar_t* str): ParentType(str) {} MbString (const qse_mchar_t* str): ParentType(str) {}
@ -231,10 +237,38 @@ public:
int formatv (const qse_mchar_t* fmt, va_list ap); int formatv (const qse_mchar_t* fmt, va_list ap);
}; };
class WcPtrString: public PtrStrBase<qse_wchar_t, QSE_MT('\0'), WcStringOpset>
{
private:
typedef PtrStrBase<qse_wchar_t, QSE_MT('\0'), WcStringOpset> ParentType;
public:
WcPtrString () {}
WcPtrString (const qse_wchar_t* ptr): ParentType(ptr) {}
WcPtrString (const qse_wchar_t* ptr, qse_size_t len): ParentType(ptr, len) {}
};
class MbPtrString: public PtrStrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset>
{
private:
typedef PtrStrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> ParentType;
public:
MbPtrString () {}
MbPtrString (const qse_mchar_t* ptr): ParentType(ptr) {}
MbPtrString (const qse_mchar_t* ptr, qse_size_t len): ParentType(ptr, len) {}
};
#if defined(QSE_CHAR_IS_MCHAR) #if defined(QSE_CHAR_IS_MCHAR)
typedef MbString String; typedef MbString String;
typedef MbPtrString PtrString;
#else #else
typedef WcString String; typedef WcString String;
typedef WcPtrString PtrString;
#endif #endif
///////////////////////////////// /////////////////////////////////