My version of a concurrent undordered map
namespace concurrency
{
template
class unordered_bucket: private std::unordered_map
{
mutable std::recursive_mutex m_mutex;
public:
T1 &operator [](T a)
{
std::lock_guard l(m_mutex);
return std::unordered_map::operator [](a);
}
size_t size() const noexcept {
std::lock_guard l(m_mutex);
return std::unordered_map::size();
}
vector> toVector() const
{
std::lock_guard l(m_mutex);
vector> ret;
for(const pair &p:*this)
{
ret.push_back(p);
}
return ret;
}
bool find(const T &t) const
{
std::lock_guard l(m_mutex);
if(this->std::unordered_map::find(t) == this->end())
return false; //not found
return true;
}
void erase()
{
std::lock_guard l(m_mutex);
this->unordered_map::erase(this->begin(),this->end());
}
void erase(const T &t)
{
std::lock_guard l(m_mutex);
this->unordered_map::erase(t);
}
};
#define BUCKETCOUNT 10
template
class ConcurrentMap
{
std::vector> m_v;
public:
ConcurrentMap():m_v(BUCKETCOUNT){} //using 10 buckets
T1 &operator [](T a)
{
std::hash h;
return m_v[h(a)%BUCKETCOUNT][a];
}
size_t size() const noexcept {
size_t cnt=0;
for(const unordered_bucket &ub:m_v)
cnt=cnt+ub.size();
return cnt;
}
vector> toVector() const
{
vector> ret;
for(const unordered_bucket &u:m_v)
{
const vector> &data=u.toVector();
ret.insert(ret.end(),data.begin(),data.end());
}
return ret;
}
bool find(const T &t) const
{
for(const unordered_bucket &u:m_v)
if(true == u.find(t))
return true;
return false;
}
void erase()
{
for(unordered_bucket &u:m_v)
u.erase();
}
void erase(const T &t)
{
std::hash h;
unordered_bucket &ub = m_v[h(t)%BUCKETCOUNT];
ub.erase(t);
}
};
}