osrm-backend/include/util/concurrent_id_map.hpp

81 lines
2.1 KiB
C++
Raw Normal View History

#ifndef CONCURRENT_ID_MAP_HPP
#define CONCURRENT_ID_MAP_HPP
#include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <unordered_map>
namespace osrm
{
namespace util
{
/**
* This is a special purpose map for caching incrementing IDs
*/
template <typename KeyType, typename ValueType, typename HashType = std::hash<KeyType>>
struct ConcurrentIDMap
{
static_assert(std::is_unsigned<ValueType>::value, "Only unsigned integer types are supported.");
using UpgradableMutex = boost::interprocess::interprocess_upgradable_mutex;
using ScopedReaderLock = boost::interprocess::sharable_lock<UpgradableMutex>;
using ScopedWriterLock = boost::interprocess::scoped_lock<UpgradableMutex>;
std::unordered_map<KeyType, ValueType, HashType> data;
mutable UpgradableMutex mutex;
2017-06-16 08:35:04 -04:00
ConcurrentIDMap() = default;
ConcurrentIDMap(ConcurrentIDMap &&other)
{
2017-06-23 06:36:23 -04:00
if (this != &other)
{
ScopedWriterLock other_lock{other.mutex};
ScopedWriterLock lock{mutex};
2017-06-16 08:35:04 -04:00
2017-06-23 06:36:23 -04:00
data = std::move(other.data);
}
2017-06-16 08:35:04 -04:00
}
2017-06-19 09:27:46 -04:00
ConcurrentIDMap &operator=(ConcurrentIDMap &&other)
2017-06-16 08:35:04 -04:00
{
2017-06-23 06:36:23 -04:00
if (this != &other)
{
ScopedWriterLock other_lock{other.mutex};
ScopedWriterLock lock{mutex};
2017-06-16 08:35:04 -04:00
2017-06-23 06:36:23 -04:00
data = std::move(other.data);
}
2017-06-16 08:35:04 -04:00
return *this;
}
const ValueType ConcurrentFindOrAdd(const KeyType &key)
{
{
ScopedReaderLock sentry{mutex};
const auto result = data.find(key);
if (result != data.end())
{
return result->second;
}
}
{
ScopedWriterLock sentry{mutex};
const auto result = data.find(key);
if (result != data.end())
{
return result->second;
}
const auto id = static_cast<ValueType>(data.size());
data[key] = id;
return id;
}
}
};
} // namespace util
} // namespace osrm
2017-06-16 08:35:04 -04:00
#endif // CONCURRENT_ID_MAP_HPP