added HashList::inject() and HashTable::inject().
improved HashTable::upsert(). added HashList::ensert() and HashTable::ensert(). started porting rbt to RedBlackTree
This commit is contained in:
parent
06dbccbc06
commit
14f5a8a9b3
@ -44,7 +44,7 @@ struct HashListHasher
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct HashListComparator
|
struct HashListEqualer
|
||||||
{
|
{
|
||||||
bool operator() (const T& v1, const T& v2) const
|
bool operator() (const T& v1, const T& v2) const
|
||||||
{
|
{
|
||||||
@ -76,18 +76,18 @@ struct HashListResizer
|
|||||||
/// For a hash value of hc, this->nodes[hc * 2] points to the first node and
|
/// For a hash value of hc, this->nodes[hc * 2] points to the first node and
|
||||||
/// this->nodes[hc * 2 + 1] ponits to the last node.
|
/// this->nodes[hc * 2 + 1] ponits to the last node.
|
||||||
|
|
||||||
template <typename T, typename HASHER = HashListHasher<T>, typename COMPARATOR = HashListComparator<T>, typename RESIZER = HashListResizer >
|
template <typename T, typename HASHER = HashListHasher<T>, typename EQUALER = HashListEqualer<T>, typename RESIZER = HashListResizer >
|
||||||
class HashList: public Mmged
|
class HashList: public Mmged
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef LinkedList<T,COMPARATOR> DatumList;
|
typedef LinkedList<T,EQUALER> DatumList;
|
||||||
typedef typename DatumList::Node Node;
|
typedef typename DatumList::Node Node;
|
||||||
typedef typename DatumList::Iterator Iterator;
|
typedef typename DatumList::Iterator Iterator;
|
||||||
typedef typename DatumList::ConstIterator ConstIterator;
|
typedef typename DatumList::ConstIterator ConstIterator;
|
||||||
typedef HashList<T,HASHER,COMPARATOR,RESIZER> SelfType;
|
typedef HashList<T,HASHER,EQUALER,RESIZER> SelfType;
|
||||||
|
|
||||||
typedef HashListHasher<T> DefaultHasher;
|
typedef HashListHasher<T> DefaultHasher;
|
||||||
typedef HashListComparator<T> DefaultComparator;
|
typedef HashListEqualer<T> DefaultEqualer;
|
||||||
typedef HashListResizer DefaultResizer;
|
typedef HashListResizer DefaultResizer;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -304,7 +304,7 @@ protected:
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
T& t = np->value;
|
T& t = np->value;
|
||||||
if (this->comparator(datum, t)) return np;
|
if (this->equaler(datum, t)) return np;
|
||||||
if (np == this->nodes[tail]) break;
|
if (np == this->nodes[tail]) break;
|
||||||
np = np->getNextNode ();
|
np = np->getNextNode ();
|
||||||
}
|
}
|
||||||
@ -314,10 +314,10 @@ protected:
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MT, typename MCOMPARATOR>
|
template <typename MT, typename MEQUALER>
|
||||||
Node* heterofind_node (const MT& datum, qse_size_t hc) const
|
Node* heterofind_node (const MT& datum, qse_size_t hc) const
|
||||||
{
|
{
|
||||||
MCOMPARATOR is_equal;
|
MEQUALER m_Equaler;
|
||||||
|
|
||||||
qse_size_t head, tail;
|
qse_size_t head, tail;
|
||||||
Node* np;
|
Node* np;
|
||||||
@ -330,7 +330,7 @@ protected:
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
T& t = np->value;
|
T& t = np->value;
|
||||||
if (is_equal(datum, t)) return np;
|
if (m_Equaler(datum, t)) return np;
|
||||||
if (np == this->nodes[tail]) break;
|
if (np == this->nodes[tail]) break;
|
||||||
np = np->getNextNode ();
|
np = np->getNextNode ();
|
||||||
}
|
}
|
||||||
@ -340,53 +340,6 @@ protected:
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
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->insert ((Node*)QSE_NULL, datum);
|
|
||||||
this->nodes[tail] = this->nodes[head];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->nodes[head] = this->datum_list->insert (this->nodes[head], datum);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->nodes[head];
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Node* findNode (const T& datum)
|
Node* findNode (const T& datum)
|
||||||
{
|
{
|
||||||
@ -412,34 +365,34 @@ public:
|
|||||||
return &b->value;
|
return &b->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||||
Node* heterofindNode (const MT& datum)
|
Node* heterofindNode (const MT& datum)
|
||||||
{
|
{
|
||||||
MHASHER hash;
|
MHASHER hash;
|
||||||
return this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||||
const Node* heterofindNode (const MT& datum) const
|
const Node* heterofindNode (const MT& datum) const
|
||||||
{
|
{
|
||||||
MHASHER hash;
|
MHASHER hash;
|
||||||
return this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||||
T* heterofindValue(const MT& datum)
|
T* heterofindValue(const MT& datum)
|
||||||
{
|
{
|
||||||
MHASHER hash;
|
MHASHER hash;
|
||||||
Node* b = this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
Node* b = this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||||
if (!b) return QSE_NULL;
|
if (!b) return QSE_NULL;
|
||||||
return &b->value;
|
return &b->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||||
const T* heterofindValue(const MT& datum) const
|
const T* heterofindValue(const MT& datum) const
|
||||||
{
|
{
|
||||||
MHASHER hash;
|
MHASHER hash;
|
||||||
Node* b = this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
Node* b = this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||||
if (!b) return QSE_NULL;
|
if (!b) return QSE_NULL;
|
||||||
return &b->value;
|
return &b->value;
|
||||||
}
|
}
|
||||||
@ -460,23 +413,82 @@ public:
|
|||||||
return this->find_node (datum);
|
return this->find_node (datum);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||||
Node* heterosearch (const MT& datum)
|
Node* heterosearch (const MT& datum)
|
||||||
{
|
{
|
||||||
MHASHER hash;
|
MHASHER hash;
|
||||||
return this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||||
const Node* heterosearch (const MT& datum) const
|
const Node* heterosearch (const MT& datum) const
|
||||||
{
|
{
|
||||||
MHASHER hash;
|
MHASHER hash;
|
||||||
return this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* inject (const T& datum, int mode, bool* injected = QSE_NULL)
|
||||||
|
{
|
||||||
|
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->equaler(datum, t))
|
||||||
|
{
|
||||||
|
if (injected) *injected = false;
|
||||||
|
if (mode <= -1) return QSE_NULL; // failure
|
||||||
|
if (mode >= 1) t = datum; // overwrite
|
||||||
|
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->insert ((Node*)QSE_NULL, datum);
|
||||||
|
this->nodes[tail] = this->nodes[head];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->nodes[head] = this->datum_list->insert (this->nodes[head], datum);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (injected) *injected = true;
|
||||||
|
return this->nodes[head];
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* insert (const T& datum)
|
Node* insert (const T& datum)
|
||||||
{
|
{
|
||||||
return this->insert_value (datum, false);
|
return this->inject (datum, -1, QSE_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* ensert (const T& datum)
|
||||||
|
{
|
||||||
|
return this->inject (datum, 0, QSE_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* upsert (const T& datum)
|
||||||
|
{
|
||||||
|
return this->inject (datum, 1, QSE_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* update (const T& datum)
|
Node* update (const T& datum)
|
||||||
@ -486,11 +498,6 @@ public:
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* upsert (const T& datum)
|
|
||||||
{
|
|
||||||
return this->insert_value (datum, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int remove (const T& datum)
|
int remove (const T& datum)
|
||||||
{
|
{
|
||||||
qse_size_t hc, head, tail;
|
qse_size_t hc, head, tail;
|
||||||
@ -505,7 +512,7 @@ public:
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
T& t = np->value;
|
T& t = np->value;
|
||||||
if (this->comparator(datum, t))
|
if (this->equaler(datum, t))
|
||||||
{
|
{
|
||||||
if (this->nodes[head] == this->nodes[tail])
|
if (this->nodes[head] == this->nodes[tail])
|
||||||
{
|
{
|
||||||
@ -534,13 +541,13 @@ public:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||||
int heteroremove (const MT& datum)
|
int heteroremove (const MT& datum)
|
||||||
{
|
{
|
||||||
MHASHER hash;
|
MHASHER hash;
|
||||||
qse_size_t hc = hash(datum) % this->node_capacity;
|
qse_size_t hc = hash(datum) % this->node_capacity;
|
||||||
|
|
||||||
Node* np = this->heterofind_node<MT,MCOMPARATOR> (datum, hc);
|
Node* np = this->heterofind_node<MT,MEQUALER> (datum, hc);
|
||||||
if (np)
|
if (np)
|
||||||
{
|
{
|
||||||
qse_size_t head, tail;
|
qse_size_t head, tail;
|
||||||
@ -614,7 +621,7 @@ protected:
|
|||||||
mutable qse_size_t threshold;
|
mutable qse_size_t threshold;
|
||||||
qse_size_t load_factor;
|
qse_size_t load_factor;
|
||||||
HASHER hasher;
|
HASHER hasher;
|
||||||
COMPARATOR comparator;
|
EQUALER equaler;
|
||||||
RESIZER resizer;
|
RESIZER resizer;
|
||||||
|
|
||||||
void rehash ()
|
void rehash ()
|
||||||
|
@ -44,7 +44,7 @@ struct HashTableHasher
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct HashTableComparator
|
struct HashTableEqualer
|
||||||
{
|
{
|
||||||
// it must return true if two values are equal
|
// it must return true if two values are equal
|
||||||
bool operator() (const T& v1, const T& v2) const
|
bool operator() (const T& v1, const T& v2) const
|
||||||
@ -55,15 +55,15 @@ struct HashTableComparator
|
|||||||
|
|
||||||
typedef HashListResizer HashTableResizer;
|
typedef HashListResizer HashTableResizer;
|
||||||
|
|
||||||
template <typename K, typename V, typename HASHER = HashTableHasher<K>, typename COMPARATOR = HashTableComparator<K>, typename RESIZER = HashTableResizer>
|
template <typename K, typename V, typename HASHER = HashTableHasher<K>, typename EQUALER = HashTableEqualer<K>, typename RESIZER = HashTableResizer>
|
||||||
class HashTable: public Mmged
|
class HashTable: public Mmged
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Association<K,V> Pair;
|
typedef Association<K,V> Pair;
|
||||||
typedef HashTable<K,V,HASHER,COMPARATOR,RESIZER> SelfType;
|
typedef HashTable<K,V,HASHER,EQUALER,RESIZER> SelfType;
|
||||||
|
|
||||||
typedef HashTableHasher<K> DefaultHasher;
|
typedef HashTableHasher<K> DefaultHasher;
|
||||||
typedef HashTableComparator<K> DefaultComparator;
|
typedef HashTableEqualer<K> DefaultEqualer;
|
||||||
typedef HashTableResizer DefaultResizer;
|
typedef HashTableResizer DefaultResizer;
|
||||||
|
|
||||||
struct PairHasher
|
struct PairHasher
|
||||||
@ -75,35 +75,35 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PairComparator
|
struct PairEqualer
|
||||||
{
|
{
|
||||||
qse_size_t operator() (const Pair& p1, const Pair& p2) const
|
qse_size_t operator() (const Pair& p1, const Pair& p2) const
|
||||||
{
|
{
|
||||||
COMPARATOR comparator;
|
EQUALER equaler;
|
||||||
return comparator (p1.key, p2.key);
|
return equaler (p1.key, p2.key);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PairHeteroComparator
|
struct PairHeteroEqualer
|
||||||
{
|
{
|
||||||
qse_size_t operator() (const K& p1, const Pair& p2) const
|
qse_size_t operator() (const K& p1, const Pair& p2) const
|
||||||
{
|
{
|
||||||
COMPARATOR is_equal;
|
EQUALER equaler;
|
||||||
return is_equal (p1, p2.key);
|
return equaler (p1, p2.key);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename MK, typename MCOMPARATOR>
|
template <typename MK, typename MEQUALER>
|
||||||
struct MHeteroComparator
|
struct MHeteroEqualer
|
||||||
{
|
{
|
||||||
qse_size_t operator() (const MK& p1, const Pair& p2) const
|
qse_size_t operator() (const MK& p1, const Pair& p2) const
|
||||||
{
|
{
|
||||||
MCOMPARATOR is_equal;
|
MEQUALER mequaler;
|
||||||
return is_equal (p1, p2.key);
|
return mequaler (p1, p2.key);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef HashList<Pair,PairHasher,PairComparator,RESIZER> PairList;
|
typedef HashList<Pair,PairHasher,PairEqualer,RESIZER> PairList;
|
||||||
typedef typename PairList::Node PairNode;
|
typedef typename PairList::Node PairNode;
|
||||||
typedef typename PairList::Iterator Iterator;
|
typedef typename PairList::Iterator Iterator;
|
||||||
typedef typename PairList::ConstIterator ConstIterator;
|
typedef typename PairList::ConstIterator ConstIterator;
|
||||||
@ -180,6 +180,13 @@ public:
|
|||||||
return this->pair_list.getTailNode ();
|
return this->pair_list.getTailNode ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pair* inject (const K& key, const V& value, int mode, bool* injected = QSE_NULL)
|
||||||
|
{
|
||||||
|
PairNode* node = this->pair_list.inject (Pair(key, value), mode, injected);
|
||||||
|
if (!node) return QSE_NULL;
|
||||||
|
return &node->value;
|
||||||
|
}
|
||||||
|
|
||||||
Pair* insert (const K& key, const V& value)
|
Pair* insert (const K& key, const V& value)
|
||||||
{
|
{
|
||||||
PairNode* node = this->pair_list.insert (Pair(key, value));
|
PairNode* node = this->pair_list.insert (Pair(key, value));
|
||||||
@ -187,20 +194,38 @@ public:
|
|||||||
return &node->value;
|
return &node->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair* upsert (const K& key, const V& value)
|
Pair* ensert (const K& key, const V& value)
|
||||||
{
|
{
|
||||||
PairNode* node = this->pair_list.upsert (Pair(key, value));
|
PairNode* node = this->pair_list.ensert (Pair(key, value));
|
||||||
if (!node) return QSE_NULL;
|
if (!node) return QSE_NULL;
|
||||||
return &node->value;
|
return &node->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pair* upsert (const K& key, const V& value)
|
||||||
|
{
|
||||||
|
//PairNode* node = this->pair_list.upsert (Pair(key, value));
|
||||||
|
//if (!node) return QSE_NULL;
|
||||||
|
//return &node->value;
|
||||||
|
|
||||||
|
// Don't call pair_list.upsert() to make sure that the 'key' object
|
||||||
|
// itself remains identical after potential update operation.
|
||||||
|
// pair_list.upsert() changes the Pair object as a whole. so this
|
||||||
|
// trick is required.
|
||||||
|
bool injected;
|
||||||
|
PairNode* node = this->pair_list.inject (Pair(key, value), 0, &injected);
|
||||||
|
QSE_ASSERT (node != QSE_NULL);
|
||||||
|
Pair& pair = node->value;
|
||||||
|
if (injected) pair.value = value;
|
||||||
|
return &pair;
|
||||||
|
}
|
||||||
|
|
||||||
Pair* update (const K& key, const V& value)
|
Pair* update (const K& key, const V& value)
|
||||||
{
|
{
|
||||||
//PairNode* node = this->pair_list.update (Pair(key, value));
|
//PairNode* node = this->pair_list.update (Pair(key, value));
|
||||||
//if (!node) return QSE_NULL;
|
//if (!node) return QSE_NULL;
|
||||||
//return &node->value;
|
//return &node->value;
|
||||||
|
|
||||||
PairNode* node = this->pair_list.template heterofindNode<K,HASHER,PairHeteroComparator> (key);
|
PairNode* node = this->pair_list.template heterofindNode<K,HASHER,PairHeteroEqualer> (key);
|
||||||
if (!node) return QSE_NULL;
|
if (!node) return QSE_NULL;
|
||||||
Pair& pair = node->value;
|
Pair& pair = node->value;
|
||||||
pair.value = value;
|
pair.value = value;
|
||||||
@ -210,7 +235,7 @@ public:
|
|||||||
Pair* search (const K& key)
|
Pair* search (const K& key)
|
||||||
{
|
{
|
||||||
//PairNode* node = this->pair_list.update (Pair(key));
|
//PairNode* node = this->pair_list.update (Pair(key));
|
||||||
PairNode* node = this->pair_list.template heterofindNode<K,HASHER,PairHeteroComparator> (key);
|
PairNode* node = this->pair_list.template heterofindNode<K,HASHER,PairHeteroEqualer> (key);
|
||||||
if (!node) return QSE_NULL;
|
if (!node) return QSE_NULL;
|
||||||
return &node->value;
|
return &node->value;
|
||||||
}
|
}
|
||||||
@ -218,32 +243,32 @@ public:
|
|||||||
int remove (const K& key)
|
int remove (const K& key)
|
||||||
{
|
{
|
||||||
//return this->pair_list.remove (Pair(key));
|
//return this->pair_list.remove (Pair(key));
|
||||||
return this->pair_list.template heteroremove<K,HASHER,PairHeteroComparator> (key);
|
return this->pair_list.template heteroremove<K,HASHER,PairHeteroEqualer> (key);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MK, typename MHASHER, typename MCOMPARATOR>
|
template <typename MK, typename MHASHER, typename MEQUALER>
|
||||||
Pair* heterosearch (const MK& key)
|
Pair* heterosearch (const MK& key)
|
||||||
{
|
{
|
||||||
typedef MHeteroComparator<MK,MCOMPARATOR> MComparator;
|
typedef MHeteroEqualer<MK,MEQUALER> MEqualer;
|
||||||
PairNode* node = this->pair_list.template heterosearch<MK,MHASHER,MComparator> (key);
|
PairNode* node = this->pair_list.template heterosearch<MK,MHASHER,MEqualer> (key);
|
||||||
if (!node) return QSE_NULL;
|
if (!node) return QSE_NULL;
|
||||||
return &node->value;
|
return &node->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MK, typename MHASHER, typename MCOMPARATOR>
|
template <typename MK, typename MHASHER, typename MEQUALER>
|
||||||
const Pair* heterosearch (const MK& key) const
|
const Pair* heterosearch (const MK& key) const
|
||||||
{
|
{
|
||||||
typedef MHeteroComparator<MK,MCOMPARATOR> MComparator;
|
typedef MHeteroEqualer<MK,MEQUALER> MEqualer;
|
||||||
PairNode* node = this->pair_list.template heterosearch<MK,MHASHER,MComparator> (key);
|
PairNode* node = this->pair_list.template heterosearch<MK,MHASHER,MEqualer> (key);
|
||||||
if (!node) return QSE_NULL;
|
if (!node) return QSE_NULL;
|
||||||
return &node->value;
|
return &node->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MK, typename MHASHER, typename MCOMPARATOR>
|
template <typename MK, typename MHASHER, typename MEQUALER>
|
||||||
int heteroremove (const MK& key)
|
int heteroremove (const MK& key)
|
||||||
{
|
{
|
||||||
typedef MHeteroComparator<MK,MCOMPARATOR> MComparator;
|
typedef MHeteroEqualer<MK,MEQUALER> MEqualer;
|
||||||
return this->pair_list.template heteroremove<MK,MHASHER,MComparator> (key);
|
return this->pair_list.template heteroremove<MK,MHASHER,MEqualer> (key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear (bool clear_mpool = false)
|
void clear (bool clear_mpool = false)
|
||||||
|
@ -34,14 +34,14 @@
|
|||||||
QSE_BEGIN_NAMESPACE(QSE)
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
template <typename T, typename COMPARATOR> class LinkedList;
|
template <typename T, typename EQUALER> class LinkedList;
|
||||||
|
|
||||||
template <typename T, typename COMPARATOR>
|
template <typename T, typename EQUALER>
|
||||||
class LinkedListNode
|
class LinkedListNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
friend class LinkedList<T,COMPARATOR>;
|
friend class LinkedList<T,EQUALER>;
|
||||||
typedef LinkedListNode<T,COMPARATOR> SelfType;
|
typedef LinkedListNode<T,EQUALER> SelfType;
|
||||||
|
|
||||||
T value; // you can use this variable or accessor functions below
|
T value; // you can use this variable or accessor functions below
|
||||||
|
|
||||||
@ -79,12 +79,12 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename COMPARATOR, typename NODE, typename GET_T>
|
template <typename T, typename EQUALER, typename NODE, typename GET_T>
|
||||||
class LinkedListIterator {
|
class LinkedListIterator {
|
||||||
public:
|
public:
|
||||||
friend class LinkedList<T,COMPARATOR>;
|
friend class LinkedList<T,EQUALER>;
|
||||||
typedef NODE Node;
|
typedef NODE Node;
|
||||||
typedef LinkedListIterator<T,COMPARATOR,NODE,GET_T> SelfType;
|
typedef LinkedListIterator<T,EQUALER,NODE,GET_T> SelfType;
|
||||||
|
|
||||||
LinkedListIterator (): current(QSE_NULL) {}
|
LinkedListIterator (): current(QSE_NULL) {}
|
||||||
LinkedListIterator (Node* node): current(node) {}
|
LinkedListIterator (Node* node): current(node) {}
|
||||||
@ -178,7 +178,7 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct LinkedListComparator
|
struct LinkedListEqualer
|
||||||
{
|
{
|
||||||
// it must return true if two values are equal
|
// it must return true if two values are equal
|
||||||
bool operator() (const T& v1, const T& v2) const
|
bool operator() (const T& v1, const T& v2) const
|
||||||
@ -188,17 +188,17 @@ struct LinkedListComparator
|
|||||||
};
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The LinkedList<T,COMPARATOR> class provides a template for a doubly-linked list.
|
/// The LinkedList<T,EQUALER> class provides a template for a doubly-linked list.
|
||||||
///
|
///
|
||||||
template <typename T, typename COMPARATOR = LinkedListComparator<T> > class LinkedList: public Mmged
|
template <typename T, typename EQUALER = LinkedListEqualer<T> > class LinkedList: public Mmged
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef LinkedList<T,COMPARATOR> SelfType;
|
typedef LinkedList<T,EQUALER> SelfType;
|
||||||
typedef LinkedListNode<T,COMPARATOR> Node;
|
typedef LinkedListNode<T,EQUALER> Node;
|
||||||
typedef LinkedListIterator<T,COMPARATOR,Node,T> Iterator;
|
typedef LinkedListIterator<T,EQUALER,Node,T> Iterator;
|
||||||
typedef LinkedListIterator<T,COMPARATOR,const Node,const T> ConstIterator;
|
typedef LinkedListIterator<T,EQUALER,const Node,const T> ConstIterator;
|
||||||
|
|
||||||
typedef LinkedListComparator<T> DefaultComparator;
|
typedef LinkedListEqualer<T> DefaultEqualer;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -270,7 +270,7 @@ public:
|
|||||||
|
|
||||||
bool isEmpty () const
|
bool isEmpty () const
|
||||||
{
|
{
|
||||||
return this->node_count == 0;
|
return this->node_count <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The insertNode() function inserts an externally created \a node
|
/// The insertNode() function inserts an externally created \a node
|
||||||
@ -576,7 +576,7 @@ public:
|
|||||||
{
|
{
|
||||||
for (Node* p = this->head_node; p; p = p->next)
|
for (Node* p = this->head_node; p; p = p->next)
|
||||||
{
|
{
|
||||||
if (this->comparator (value, p->value)) return p;
|
if (this->equaler (value, p->value)) return p;
|
||||||
}
|
}
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -585,7 +585,7 @@ public:
|
|||||||
{
|
{
|
||||||
for (Node* p = tail_node; p; p = p->prev)
|
for (Node* p = tail_node; p; p = p->prev)
|
||||||
{
|
{
|
||||||
if (this->comparator (value, p->value)) return p;
|
if (this->equaler (value, p->value)) return p;
|
||||||
}
|
}
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -594,7 +594,7 @@ public:
|
|||||||
{
|
{
|
||||||
for (Node* p = head; p; p = p->next)
|
for (Node* p = head; p; p = p->next)
|
||||||
{
|
{
|
||||||
if (this->comparator (value, p->value)) return p;
|
if (this->equaler (value, p->value)) return p;
|
||||||
}
|
}
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -603,7 +603,7 @@ public:
|
|||||||
{
|
{
|
||||||
for (Node* p = tail; p; p = p->prev)
|
for (Node* p = tail; p; p = p->prev)
|
||||||
{
|
{
|
||||||
if (this->comparator (value, p->value)) return p;
|
if (this->equaler (value, p->value)) return p;
|
||||||
}
|
}
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -613,7 +613,7 @@ public:
|
|||||||
qse_size_t index = 0;
|
qse_size_t index = 0;
|
||||||
for (Node* p = this->head_node; p; p = p->next)
|
for (Node* p = this->head_node; p; p = p->next)
|
||||||
{
|
{
|
||||||
if (this->comparator (value, p->value)) return index;
|
if (this->equaler (value, p->value)) return index;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
@ -625,7 +625,7 @@ public:
|
|||||||
for (Node* p = tail_node; p; p = p->prev)
|
for (Node* p = tail_node; p; p = p->prev)
|
||||||
{
|
{
|
||||||
index--;
|
index--;
|
||||||
if (this->comparator (value, p->value)) return index;
|
if (this->equaler (value, p->value)) return index;
|
||||||
}
|
}
|
||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
}
|
}
|
||||||
@ -696,7 +696,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
Mpool mp;
|
Mpool mp;
|
||||||
COMPARATOR comparator;
|
EQUALER equaler;
|
||||||
Node* head_node;
|
Node* head_node;
|
||||||
Node* tail_node;
|
Node* tail_node;
|
||||||
qse_size_t node_count;
|
qse_size_t node_count;
|
||||||
|
@ -52,6 +52,7 @@ pkginclude_HEADERS = \
|
|||||||
if ENABLE_CXX
|
if ENABLE_CXX
|
||||||
pkginclude_HEADERS += \
|
pkginclude_HEADERS += \
|
||||||
Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
||||||
Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp
|
Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp \
|
||||||
|
RedBlackTree.hpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -52,7 +52,8 @@ 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 HeapMmgr.hpp Mmged.hpp \
|
@ENABLE_CXX_TRUE@ Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
||||||
@ENABLE_CXX_TRUE@ Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp
|
@ENABLE_CXX_TRUE@ Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp \
|
||||||
|
@ENABLE_CXX_TRUE@ RedBlackTree.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 \
|
||||||
@ -92,7 +93,7 @@ am__pkginclude_HEADERS_DIST = alg.h chr.h cp949.h cp950.h dir.h dll.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 HeapMmgr.hpp Mmged.hpp \
|
utf8.h xma.h Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
||||||
Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp \
|
Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp \
|
||||||
HashTable.hpp
|
HashTable.hpp RedBlackTree.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/||"`;; \
|
||||||
|
166
qse/include/qse/cmn/RedBlackTree.hpp
Normal file
166
qse/include/qse/cmn/RedBlackTree.hpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* $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_REDBLACKTREE_HPP_
|
||||||
|
#define _QSE_CMN_REDBLACKTREE_HPP_
|
||||||
|
|
||||||
|
#include <qse/Types.hpp>
|
||||||
|
#include <qse/cmn/Mpool.hpp>
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class RedBlackTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
friend class RedBlackTree<T>;
|
||||||
|
typedef RedBlackTreeNode<T> SelfType;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RED,
|
||||||
|
BLACK
|
||||||
|
};
|
||||||
|
|
||||||
|
T value; // you can use this variable or accessor functions below
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SelfType* parent;
|
||||||
|
SelfType* child[2]; // left and right
|
||||||
|
|
||||||
|
public:
|
||||||
|
T& getValue () { return this->value; }
|
||||||
|
const T& getValue () const { return this->value; }
|
||||||
|
void setValue (const T& v) { this->value = v; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct RedBlackTreeComparator
|
||||||
|
{
|
||||||
|
int operator() (const T& v1, const T& v2) const
|
||||||
|
{
|
||||||
|
return (v1 > v2)? 1:
|
||||||
|
(v1 < v2)? -1: 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename COMPARATOR = RedBlackTreeComparator<T> >
|
||||||
|
class RedBlackTree: public Mmged
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef RedBlackTree<T,COMPARATOR> SelfType;
|
||||||
|
|
||||||
|
typedef RedBlackTreeHasher<T> DefaultHasher;
|
||||||
|
typedef RedBlackTreeComparator<T> DefaultComparator;
|
||||||
|
|
||||||
|
RedBlackTree
|
||||||
|
Mmgr* mmgr = QSE_NULL,
|
||||||
|
qse_size_t mpb_size = 0): Mmged(mmgr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RedBlackTree (const RedBlackTree& rbt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~RedBlackTree ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RedBlackTree& operator= (const RedBlackTree& rbt)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mpool& getMpool ()
|
||||||
|
{
|
||||||
|
return this->mp;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Mpool& getMpool () const
|
||||||
|
{
|
||||||
|
return this->mp;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t getSize () const
|
||||||
|
{
|
||||||
|
return this->node_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEmpty () const
|
||||||
|
{
|
||||||
|
return this->node_count <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Node* inject (const T& datum, int mode, bool* injected = QSE_NULL)
|
||||||
|
{
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* insert (const T& datum)
|
||||||
|
{
|
||||||
|
return this->inject (datum, -1, QSE_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* ensert (const T& datum)
|
||||||
|
{
|
||||||
|
return this->inject (datum, 0, QSE_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* upsert (const T& datum)
|
||||||
|
{
|
||||||
|
return this->inject (datum, 1, QSE_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
Node* update (const T& datum)
|
||||||
|
{
|
||||||
|
Node* node = this->find_node (datum);
|
||||||
|
if (node) node->value = datum;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Mpool mp;
|
||||||
|
COMPARATOR comparator;
|
||||||
|
|
||||||
|
Node xnil; // internal node to present nil
|
||||||
|
Node* root; // root node.
|
||||||
|
qse_size_t node_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_END_NAMESPACE(QSE)
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user