first commit
This commit is contained in:
161
include/platform/container/pair.h
Normal file
161
include/platform/container/pair.h
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __TMPL_PAIRLIST__
|
||||
#define __TMPL_PAIRLIST__
|
||||
|
||||
|
||||
#include "data/array_list.h"
|
||||
#include "platform_config.h"
|
||||
|
||||
|
||||
//
|
||||
template <class PAIR, class TYPE> class ntPairList;
|
||||
|
||||
|
||||
/*
|
||||
@short Pair item.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
template <class TYPE> class ntPairItem : public nArrayEntry
|
||||
{
|
||||
protected:
|
||||
|
||||
int hash;
|
||||
|
||||
public:
|
||||
|
||||
TYPE *a, *b; ///< Object pair.
|
||||
void *pair_data; ///< Pair associated data block.
|
||||
|
||||
/// Compute pair hash value.
|
||||
static int ComputeHash(TYPE *_a, TYPE *_b)
|
||||
{
|
||||
int hash = (((uintptr_t)_a) & 0xf0f0f0f0) | (((uintptr_t)_b) & 0x0f0f0f0f);
|
||||
hash = (hash + 0x7ed55d16) + (hash << 12);
|
||||
hash = (hash ^ 0xc761c23c) ^ (hash >> 19);
|
||||
hash = (hash + 0x165667b1) + (hash << 5);
|
||||
hash = (hash + 0xd3a2646c) ^ (hash << 9);
|
||||
hash = (hash + 0xfd7046c5) + (hash << 3);
|
||||
hash = (hash ^ 0xb55a4f09) ^ (hash >> 16);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/// Get pair hash.
|
||||
int Hash() const { return hash; }
|
||||
|
||||
ntPairItem(TYPE *_a, TYPE *_b)
|
||||
{
|
||||
a = _a; b = _b;
|
||||
hash = ComputeHash(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
struct ntPairListPool
|
||||
{
|
||||
uint bucket,
|
||||
entry;
|
||||
|
||||
void Reset()
|
||||
{ bucket = entry = 0; }
|
||||
|
||||
ntPairListPool()
|
||||
{ Reset(); }
|
||||
};
|
||||
|
||||
/*
|
||||
@short Pair list.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
template <class PAIR, class TYPE> class ntPairList
|
||||
{
|
||||
|
||||
#define PairListBucketCount 64
|
||||
#define OrderPairItems(_A_, _B_) { if (_A_ > _B_) { TYPE *t = _A_; _A_ = _B_; _B_ = t; } }
|
||||
|
||||
protected:
|
||||
|
||||
uint count;
|
||||
nArrayList bucket[PairListBucketCount];
|
||||
|
||||
public:
|
||||
|
||||
/// Get item count in list.
|
||||
uint GetCount() const
|
||||
{ return count; }
|
||||
|
||||
/// Pool list.
|
||||
PAIR *Pool(ntPairListPool &pool) const
|
||||
{
|
||||
while (pool.bucket < PairListBucketCount)
|
||||
{
|
||||
if (pool.entry < bucket[pool.bucket].GetCount())
|
||||
break;
|
||||
|
||||
pool.entry = 0;
|
||||
pool.bucket++;
|
||||
}
|
||||
if (pool.bucket == PairListBucketCount)
|
||||
return 0;
|
||||
return (PAIR *)bucket[pool.bucket][pool.entry++];
|
||||
}
|
||||
|
||||
/// Add a pair.
|
||||
PAIR *Add(TYPE *a, TYPE *b)
|
||||
{
|
||||
OrderPairItems(a, b);
|
||||
|
||||
PAIR *pair = new PAIR(a, b);
|
||||
if (pair && !bucket[pair->Hash() & (PairListBucketCount - 1)].Add(pair))
|
||||
_safe_delete(pair);
|
||||
else
|
||||
count++;
|
||||
return pair;
|
||||
}
|
||||
|
||||
/// Find a pair.
|
||||
PAIR *Find(TYPE *a, TYPE *b)
|
||||
{
|
||||
OrderPairItems(a, b);
|
||||
|
||||
int hash = PAIR::ComputeHash(a, b);
|
||||
nArrayList &h_bucket = bucket[hash & (PairListBucketCount - 1)];
|
||||
|
||||
for (uint n = 0; n < h_bucket.GetCount(); ++n)
|
||||
{
|
||||
PAIR *pair = (PAIR *)h_bucket[n];
|
||||
if ((pair->a == a) && (pair->b == b))
|
||||
return pair;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Remove pair.
|
||||
bool Remove(PAIR *pair)
|
||||
{
|
||||
if (bucket[pair->Hash() & (PairListBucketCount - 1)].Delete(pair))
|
||||
{
|
||||
count--;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Delete all pair.
|
||||
void DeleteAll(bool freedata = true)
|
||||
{
|
||||
for (int n = 0; n < PairListBucketCount; ++n)
|
||||
bucket[n].DeleteAll(freedata);
|
||||
count = 0;
|
||||
}
|
||||
|
||||
ntPairList()
|
||||
{ count = 0; }
|
||||
};
|
||||
|
||||
|
||||
#endif // __TMPL_PAIRLIST__
|
||||
Reference in New Issue
Block a user