156 lines
3.6 KiB
C++
156 lines
3.6 KiB
C++
|
// File: crn_hash_map.cpp
|
||
|
// See Copyright Notice and license at the end of inc/crnlib.h
|
||
|
#include "crn_core.h"
|
||
|
#include "crn_hash_map.h"
|
||
|
#include "crn_rand.h"
|
||
|
|
||
|
namespace crnlib
|
||
|
{
|
||
|
#if 0
|
||
|
class counted_obj
|
||
|
{
|
||
|
public:
|
||
|
counted_obj(uint v = 0) :
|
||
|
m_val(v)
|
||
|
{
|
||
|
m_count++;
|
||
|
}
|
||
|
|
||
|
counted_obj(const counted_obj& obj) :
|
||
|
m_val(obj.m_val)
|
||
|
{
|
||
|
m_count++;
|
||
|
}
|
||
|
|
||
|
~counted_obj()
|
||
|
{
|
||
|
CRNLIB_ASSERT(m_count > 0);
|
||
|
m_count--;
|
||
|
}
|
||
|
|
||
|
static uint m_count;
|
||
|
|
||
|
uint m_val;
|
||
|
|
||
|
operator size_t() const { return m_val; }
|
||
|
|
||
|
bool operator== (const counted_obj& rhs) const { return m_val == rhs.m_val; }
|
||
|
bool operator== (const uint rhs) const { return m_val == rhs; }
|
||
|
|
||
|
};
|
||
|
|
||
|
uint counted_obj::m_count;
|
||
|
|
||
|
void hash_map_test()
|
||
|
{
|
||
|
random r0, r1;
|
||
|
|
||
|
uint seed = 0;
|
||
|
for ( ; ; )
|
||
|
{
|
||
|
seed++;
|
||
|
|
||
|
typedef crnlib::hash_map<counted_obj, counted_obj> my_hash_map;
|
||
|
my_hash_map m;
|
||
|
|
||
|
const uint n = r0.irand(1, 100000);
|
||
|
|
||
|
printf("%u\n", n);
|
||
|
|
||
|
r1.seed(seed);
|
||
|
|
||
|
crnlib::vector<int> q;
|
||
|
|
||
|
uint count = 0;
|
||
|
for (uint i = 0; i < n; i++)
|
||
|
{
|
||
|
uint v = r1.urand32() & 0x7FFFFFFF;
|
||
|
my_hash_map::insert_result res = m.insert(counted_obj(v), counted_obj(v ^ 0xdeadbeef));
|
||
|
if (res.second)
|
||
|
{
|
||
|
count++;
|
||
|
q.push_back(v);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CRNLIB_VERIFY(m.size() == count);
|
||
|
|
||
|
r1.seed(seed);
|
||
|
|
||
|
my_hash_map cm(m);
|
||
|
m.clear();
|
||
|
m = cm;
|
||
|
cm.reset();
|
||
|
|
||
|
for (uint i = 0; i < n; i++)
|
||
|
{
|
||
|
uint v = r1.urand32() & 0x7FFFFFFF;
|
||
|
my_hash_map::const_iterator it = m.find(counted_obj(v));
|
||
|
CRNLIB_VERIFY(it != m.end());
|
||
|
CRNLIB_VERIFY(it->first == v);
|
||
|
CRNLIB_VERIFY(it->second == (v ^ 0xdeadbeef));
|
||
|
}
|
||
|
|
||
|
for (uint t = 0; t < 2; t++)
|
||
|
{
|
||
|
const uint nd = r0.irand(1, q.size() + 1);
|
||
|
for (uint i = 0; i < nd; i++)
|
||
|
{
|
||
|
uint p = r0.irand(0, q.size());
|
||
|
|
||
|
int k = q[p];
|
||
|
if (k >= 0)
|
||
|
{
|
||
|
q[p] = -k - 1;
|
||
|
|
||
|
bool s = m.erase(counted_obj(k));
|
||
|
CRNLIB_VERIFY(s);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
typedef crnlib::hash_map<uint, empty_type> uint_hash_set;
|
||
|
uint_hash_set s;
|
||
|
|
||
|
for (uint i = 0; i < q.size(); i++)
|
||
|
{
|
||
|
int v = q[i];
|
||
|
|
||
|
if (v >= 0)
|
||
|
{
|
||
|
my_hash_map::const_iterator it = m.find(counted_obj(v));
|
||
|
CRNLIB_VERIFY(it != m.end());
|
||
|
CRNLIB_VERIFY(it->first == (uint)v);
|
||
|
CRNLIB_VERIFY(it->second == ((uint)v ^ 0xdeadbeef));
|
||
|
|
||
|
s.insert(v);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
my_hash_map::const_iterator it = m.find(counted_obj(-v - 1));
|
||
|
CRNLIB_VERIFY(it == m.end());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint found_count = 0;
|
||
|
for (my_hash_map::const_iterator it = m.begin(); it != m.end(); ++it)
|
||
|
{
|
||
|
CRNLIB_VERIFY(it->second == ((uint)it->first ^ 0xdeadbeef));
|
||
|
|
||
|
uint_hash_set::const_iterator fit(s.find((uint)it->first));
|
||
|
CRNLIB_VERIFY(fit != s.end());
|
||
|
|
||
|
CRNLIB_VERIFY(fit->first == it->first);
|
||
|
|
||
|
found_count++;
|
||
|
}
|
||
|
|
||
|
CRNLIB_VERIFY(found_count == s.size());
|
||
|
}
|
||
|
|
||
|
CRNLIB_VERIFY(counted_obj::m_count == m.size() * 2);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
} // namespace crnlib
|