2014-11-28 06:13:18 -05:00
|
|
|
#ifndef XOR_FAST_HASH_STORAGE_HPP
|
|
|
|
#define XOR_FAST_HASH_STORAGE_HPP
|
2012-07-10 05:50:41 -04:00
|
|
|
|
2016-01-02 11:13:44 -05:00
|
|
|
#include "util/xor_fast_hash.hpp"
|
2013-06-26 19:48:22 -04:00
|
|
|
|
2014-05-07 12:39:16 -04:00
|
|
|
#include <limits>
|
2012-07-10 05:50:41 -04:00
|
|
|
#include <vector>
|
|
|
|
|
2016-01-05 10:51:13 -05:00
|
|
|
namespace osrm
|
|
|
|
{
|
|
|
|
namespace util
|
|
|
|
{
|
|
|
|
|
2016-01-22 04:48:14 -05:00
|
|
|
template <typename NodeID, typename Key, std::size_t MaxNumElements = (1u << 16u)>
|
|
|
|
class XORFastHashStorage
|
2014-05-07 12:39:16 -04:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
struct HashCell
|
|
|
|
{
|
2012-07-10 05:50:41 -04:00
|
|
|
unsigned time;
|
2015-01-14 11:26:59 -05:00
|
|
|
NodeID id;
|
|
|
|
Key key;
|
2014-05-07 12:39:16 -04:00
|
|
|
HashCell()
|
2015-01-14 11:26:59 -05:00
|
|
|
: time(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()),
|
|
|
|
key(std::numeric_limits<unsigned>::max())
|
2014-05-07 12:39:16 -04:00
|
|
|
{
|
|
|
|
}
|
2012-07-10 05:50:41 -04:00
|
|
|
|
2015-01-14 12:14:55 -05:00
|
|
|
HashCell(const HashCell &other) : time(other.key), id(other.id), key(other.time) {}
|
2014-10-03 03:59:04 -04:00
|
|
|
operator Key() const { return key; }
|
2015-01-14 11:26:59 -05:00
|
|
|
void operator=(const Key key_to_insert) { key = key_to_insert; }
|
2012-07-10 05:50:41 -04:00
|
|
|
};
|
|
|
|
|
2016-01-22 04:48:14 -05:00
|
|
|
explicit XORFastHashStorage(size_t) : positions(MaxNumElements), current_timestamp{0u} {}
|
2012-07-10 05:50:41 -04:00
|
|
|
|
2014-10-03 03:59:04 -04:00
|
|
|
HashCell &operator[](const NodeID node)
|
2014-05-07 12:39:16 -04:00
|
|
|
{
|
2016-01-21 10:30:46 -05:00
|
|
|
std::uint16_t position = fast_hasher(node);
|
2014-05-07 12:39:16 -04:00
|
|
|
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
|
|
|
|
{
|
2016-01-22 04:48:14 -05:00
|
|
|
++position %= MaxNumElements;
|
2012-07-10 05:50:41 -04:00
|
|
|
}
|
|
|
|
|
2014-05-07 12:39:16 -04:00
|
|
|
positions[position].time = current_timestamp;
|
2015-01-14 11:26:59 -05:00
|
|
|
positions[position].id = node;
|
2016-01-21 10:30:46 -05:00
|
|
|
|
|
|
|
BOOST_ASSERT(position < positions.size());
|
|
|
|
|
2012-07-10 05:50:41 -04:00
|
|
|
return positions[position];
|
|
|
|
}
|
|
|
|
|
2015-01-14 11:26:59 -05:00
|
|
|
// peek into table, get key for node, think of it as a read-only operator[]
|
|
|
|
Key peek_index(const NodeID node) const
|
|
|
|
{
|
2016-01-21 10:30:46 -05:00
|
|
|
std::uint16_t position = fast_hasher(node);
|
2015-01-14 11:26:59 -05:00
|
|
|
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
|
|
|
|
{
|
2016-01-22 04:48:14 -05:00
|
|
|
++position %= MaxNumElements;
|
2015-01-14 11:26:59 -05:00
|
|
|
}
|
2016-01-21 10:30:46 -05:00
|
|
|
|
|
|
|
BOOST_ASSERT(position < positions.size());
|
|
|
|
|
2015-01-14 11:26:59 -05:00
|
|
|
return positions[position].key;
|
|
|
|
}
|
|
|
|
|
2014-10-03 03:59:04 -04:00
|
|
|
void Clear()
|
2014-05-07 12:39:16 -04:00
|
|
|
{
|
|
|
|
++current_timestamp;
|
|
|
|
if (std::numeric_limits<unsigned>::max() == current_timestamp)
|
|
|
|
{
|
2012-07-10 05:50:41 -04:00
|
|
|
positions.clear();
|
2016-01-22 04:48:14 -05:00
|
|
|
positions.resize(MaxNumElements);
|
2012-07-10 05:50:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-07 12:39:16 -04:00
|
|
|
private:
|
2012-07-10 05:50:41 -04:00
|
|
|
std::vector<HashCell> positions;
|
2016-01-22 04:48:14 -05:00
|
|
|
XORFastHash<MaxNumElements> fast_hasher;
|
2014-05-07 12:39:16 -04:00
|
|
|
unsigned current_timestamp;
|
2012-07-10 05:50:41 -04:00
|
|
|
};
|
2016-01-05 10:51:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-28 06:13:18 -05:00
|
|
|
#endif // XOR_FAST_HASH_STORAGE_HPP
|