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>
|
|
|
|
|
2014-05-07 12:39:16 -04:00
|
|
|
template <typename NodeID, typename Key> class XORFastHashStorage
|
|
|
|
{
|
|
|
|
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) {}
|
2012-07-10 05:50:41 -04:00
|
|
|
|
2014-10-03 03:59:04 -04:00
|
|
|
operator Key() const { return key; }
|
2012-07-10 05:50:41 -04:00
|
|
|
|
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
|
|
|
};
|
|
|
|
|
2015-01-14 12:14:55 -05:00
|
|
|
XORFastHashStorage() = delete;
|
|
|
|
|
2014-05-07 12:39:16 -04:00
|
|
|
explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {}
|
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
|
|
|
{
|
|
|
|
unsigned short position = fast_hasher(node);
|
|
|
|
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
|
|
|
|
{
|
|
|
|
++position %= (2 << 16);
|
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;
|
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
|
|
|
|
{
|
|
|
|
unsigned short position = fast_hasher(node);
|
|
|
|
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
|
|
|
|
{
|
|
|
|
++position %= (2 << 16);
|
|
|
|
}
|
|
|
|
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();
|
2015-01-14 12:14:55 -05:00
|
|
|
positions.resize(2 << 16);
|
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;
|
2014-05-07 12:39:16 -04:00
|
|
|
XORFastHash fast_hasher;
|
|
|
|
unsigned current_timestamp;
|
2012-07-10 05:50:41 -04:00
|
|
|
};
|
|
|
|
|
2014-11-28 06:13:18 -05:00
|
|
|
#endif // XOR_FAST_HASH_STORAGE_HPP
|