Remove value_type from SetNode.
This commit is contained in:
parent
9e8b2489bd
commit
f0a2ccd0fb
@ -125,17 +125,16 @@ class FlatHashTableChunks {
|
|||||||
using NodeIterator = typename fixed_vector<Node>::iterator;
|
using NodeIterator = typename fixed_vector<Node>::iterator;
|
||||||
using ConstNodeIterator = typename fixed_vector<Node>::const_iterator;
|
using ConstNodeIterator = typename fixed_vector<Node>::const_iterator;
|
||||||
|
|
||||||
using KeyT = typename Node::key_type;
|
using KeyT = typename Node::public_key_type;
|
||||||
using key_type = typename Node::key_type;
|
using key_type = typename Node::public_key_type;
|
||||||
using public_type = typename Node::public_type;
|
|
||||||
using value_type = typename Node::public_type;
|
using value_type = typename Node::public_type;
|
||||||
|
|
||||||
struct Iterator {
|
struct Iterator {
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using value_type = public_type;
|
using value_type = FlatHashTableChunks::value_type;
|
||||||
using pointer = public_type *;
|
using pointer = value_type *;
|
||||||
using reference = public_type &;
|
using reference = value_type &;
|
||||||
|
|
||||||
friend class FlatHashTableChunks;
|
friend class FlatHashTableChunks;
|
||||||
Iterator &operator++() {
|
Iterator &operator++() {
|
||||||
@ -177,7 +176,7 @@ class FlatHashTableChunks {
|
|||||||
struct ConstIterator {
|
struct ConstIterator {
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using value_type = public_type;
|
using value_type = FlatHashTableChunks::value_type;
|
||||||
using pointer = const value_type *;
|
using pointer = const value_type *;
|
||||||
using reference = const value_type &;
|
using reference = const value_type &;
|
||||||
|
|
||||||
@ -214,21 +213,25 @@ class FlatHashTableChunks {
|
|||||||
using const_iterator = ConstIterator;
|
using const_iterator = ConstIterator;
|
||||||
|
|
||||||
FlatHashTableChunks() = default;
|
FlatHashTableChunks() = default;
|
||||||
FlatHashTableChunks(const FlatHashTableChunks &other) : FlatHashTableChunks(other.begin(), other.end()) {
|
FlatHashTableChunks(const FlatHashTableChunks &other) {
|
||||||
|
assign(other);
|
||||||
}
|
}
|
||||||
FlatHashTableChunks &operator=(const FlatHashTableChunks &other) {
|
FlatHashTableChunks &operator=(const FlatHashTableChunks &other) {
|
||||||
assign(other.begin(), other.end());
|
clear();
|
||||||
|
assign(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlatHashTableChunks(std::initializer_list<Node> nodes) {
|
FlatHashTableChunks(std::initializer_list<Node> nodes) {
|
||||||
reserve(nodes.size());
|
reserve(nodes.size());
|
||||||
for (auto &node : nodes) {
|
for (auto &new_node : nodes) {
|
||||||
CHECK(!node.empty());
|
CHECK(!new_node.empty());
|
||||||
if (count(node.key()) > 0) {
|
if (count(new_node.key()) > 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
emplace_node(Node{node.first, node.second});
|
Node node;
|
||||||
|
node.copy_from(new_node);
|
||||||
|
emplace_node(std::move(node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,11 +250,6 @@ class FlatHashTableChunks {
|
|||||||
}
|
}
|
||||||
~FlatHashTableChunks() = default;
|
~FlatHashTableChunks() = default;
|
||||||
|
|
||||||
template <class ItT>
|
|
||||||
FlatHashTableChunks(ItT begin, ItT end) {
|
|
||||||
assign(begin, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t bucket_count() const {
|
size_t bucket_count() const {
|
||||||
return nodes_.size();
|
return nodes_.size();
|
||||||
}
|
}
|
||||||
@ -270,7 +268,7 @@ class FlatHashTableChunks {
|
|||||||
auto mask_it = MaskHelper::equal_mask(chunk.ctrl, hash.small_hash);
|
auto mask_it = MaskHelper::equal_mask(chunk.ctrl, hash.small_hash);
|
||||||
for (auto pos : mask_it) {
|
for (auto pos : mask_it) {
|
||||||
auto it = chunk_begin + pos;
|
auto it = chunk_begin + pos;
|
||||||
if (likely(EqT()(it->first, key))) {
|
if (likely(EqT()(it->key(), key))) {
|
||||||
return Iterator{it, this};
|
return Iterator{it, this};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,8 +365,9 @@ class FlatHashTableChunks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typename Node::value_type &operator[](const KeyT &key) {
|
template <class T = typename Node::second_type>
|
||||||
return emplace(key).first->value();
|
T &operator[](const KeyT &key) {
|
||||||
|
return emplace(key).first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t erase(const KeyT &key) {
|
size_t erase(const KeyT &key) {
|
||||||
@ -419,12 +418,12 @@ class FlatHashTableChunks {
|
|||||||
fixed_vector<Chunk> chunks_;
|
fixed_vector<Chunk> chunks_;
|
||||||
size_t used_nodes_{};
|
size_t used_nodes_{};
|
||||||
|
|
||||||
template <class ItT>
|
void assign(const FlatHashTableChunks &other) {
|
||||||
void assign(ItT begin, ItT end) {
|
reserve(other.size());
|
||||||
clear();
|
for (const auto &new_node : other) {
|
||||||
reserve(std::distance(begin, end));
|
Node node;
|
||||||
for (; begin != end; ++begin) {
|
node.copy_from(new_node);
|
||||||
emplace(begin->first, begin->second);
|
emplace_node(std::move(node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,7 +507,7 @@ class FlatHashTableChunks {
|
|||||||
|
|
||||||
void emplace_node(Node &&node) {
|
void emplace_node(Node &&node) {
|
||||||
DCHECK(!node.empty());
|
DCHECK(!node.empty());
|
||||||
auto hash = calc_hash(node.first);
|
auto hash = calc_hash(node.key());
|
||||||
auto chunk_it = get_chunk_it(hash.chunk_i);
|
auto chunk_it = get_chunk_it(hash.chunk_i);
|
||||||
while (true) {
|
while (true) {
|
||||||
auto chunk_i = chunk_it.pos();
|
auto chunk_i = chunk_it.pos();
|
||||||
@ -543,7 +542,7 @@ class FlatHashTableChunks {
|
|||||||
size_t empty_i = it - nodes_.begin();
|
size_t empty_i = it - nodes_.begin();
|
||||||
DCHECK(0 <= empty_i && empty_i < nodes_.size());
|
DCHECK(0 <= empty_i && empty_i < nodes_.size());
|
||||||
auto empty_chunk_i = empty_i / Chunk::CHUNK_SIZE;
|
auto empty_chunk_i = empty_i / Chunk::CHUNK_SIZE;
|
||||||
auto hash = calc_hash(it->first);
|
auto hash = calc_hash(it->key());
|
||||||
auto chunk_it = get_chunk_it(hash.chunk_i);
|
auto chunk_it = get_chunk_it(hash.chunk_i);
|
||||||
while (true) {
|
while (true) {
|
||||||
auto chunk_i = chunk_it.pos();
|
auto chunk_i = chunk_it.pos();
|
||||||
|
@ -28,20 +28,19 @@ template <class KeyT, class ValueT>
|
|||||||
struct MapNode {
|
struct MapNode {
|
||||||
using first_type = KeyT;
|
using first_type = KeyT;
|
||||||
using second_type = ValueT;
|
using second_type = ValueT;
|
||||||
using key_type = KeyT;
|
using public_key_type = KeyT;
|
||||||
using public_type = MapNode<KeyT, ValueT>;
|
using public_type = MapNode;
|
||||||
using value_type = ValueT;
|
|
||||||
KeyT first{};
|
KeyT first{};
|
||||||
union {
|
union {
|
||||||
ValueT second;
|
ValueT second;
|
||||||
};
|
};
|
||||||
const auto &key() const {
|
|
||||||
|
const KeyT &key() const {
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
auto &value() {
|
|
||||||
return second;
|
MapNode &get_public() {
|
||||||
}
|
|
||||||
auto &get_public() {
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,23 +99,19 @@ struct MapNode {
|
|||||||
|
|
||||||
template <class KeyT>
|
template <class KeyT>
|
||||||
struct SetNode {
|
struct SetNode {
|
||||||
using first_type = KeyT;
|
using public_key_type = KeyT;
|
||||||
using key_type = KeyT;
|
|
||||||
using public_type = KeyT;
|
using public_type = KeyT;
|
||||||
using value_type = KeyT;
|
|
||||||
|
|
||||||
KeyT first{};
|
KeyT first{};
|
||||||
|
|
||||||
const auto &key() const {
|
const KeyT &key() const {
|
||||||
return first;
|
|
||||||
}
|
|
||||||
const auto &value() const {
|
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &get_public() {
|
KeyT &get_public() {
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetNode() = default;
|
SetNode() = default;
|
||||||
explicit SetNode(KeyT key) : first(std::move(key)) {
|
explicit SetNode(KeyT key) : first(std::move(key)) {
|
||||||
}
|
}
|
||||||
@ -162,17 +157,16 @@ class FlatHashTable {
|
|||||||
using NodeIterator = typename fixed_vector<Node>::iterator;
|
using NodeIterator = typename fixed_vector<Node>::iterator;
|
||||||
using ConstNodeIterator = typename fixed_vector<Node>::const_iterator;
|
using ConstNodeIterator = typename fixed_vector<Node>::const_iterator;
|
||||||
|
|
||||||
using KeyT = typename Node::key_type;
|
using KeyT = typename Node::public_key_type;
|
||||||
using key_type = typename Node::key_type;
|
using key_type = typename Node::public_key_type;
|
||||||
using public_type = typename Node::public_type;
|
|
||||||
using value_type = typename Node::public_type;
|
using value_type = typename Node::public_type;
|
||||||
|
|
||||||
struct Iterator {
|
struct Iterator {
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using value_type = public_type;
|
using value_type = FlatHashTable::value_type;
|
||||||
using pointer = public_type *;
|
using pointer = value_type *;
|
||||||
using reference = public_type &;
|
using reference = value_type &;
|
||||||
|
|
||||||
friend class FlatHashTable;
|
friend class FlatHashTable;
|
||||||
Iterator &operator++() {
|
Iterator &operator++() {
|
||||||
@ -214,7 +208,7 @@ class FlatHashTable {
|
|||||||
struct ConstIterator {
|
struct ConstIterator {
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using value_type = public_type;
|
using value_type = FlatHashTable::value_type;
|
||||||
using pointer = const value_type *;
|
using pointer = const value_type *;
|
||||||
using reference = const value_type &;
|
using reference = const value_type &;
|
||||||
|
|
||||||
@ -391,8 +385,9 @@ class FlatHashTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typename Node::value_type &operator[](const KeyT &key) {
|
template <class T = typename Node::second_type>
|
||||||
return emplace(key).first->value();
|
T &operator[](const KeyT &key) {
|
||||||
|
return emplace(key).first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t erase(const KeyT &key) {
|
size_t erase(const KeyT &key) {
|
||||||
|
@ -176,7 +176,6 @@ TEST(FlatHashMap, basic) {
|
|||||||
ASSERT_EQ("a", kv.find("a")->first);
|
ASSERT_EQ("a", kv.find("a")->first);
|
||||||
ASSERT_EQ("b", kv.find("a")->second);
|
ASSERT_EQ("b", kv.find("a")->second);
|
||||||
ASSERT_EQ("a", kv.find("a")->key());
|
ASSERT_EQ("a", kv.find("a")->key());
|
||||||
ASSERT_EQ("b", kv.find("a")->value());
|
|
||||||
kv.find("a")->second = "c";
|
kv.find("a")->second = "c";
|
||||||
ASSERT_EQ("c", kv.find("a")->second);
|
ASSERT_EQ("c", kv.find("a")->second);
|
||||||
ASSERT_EQ("c", kv["a"]);
|
ASSERT_EQ("c", kv["a"]);
|
||||||
|
@ -190,13 +190,14 @@ static void BM_Get(benchmark::State &state) {
|
|||||||
td::vector<KeyValue> data;
|
td::vector<KeyValue> data;
|
||||||
td::vector<Key> keys;
|
td::vector<Key> keys;
|
||||||
|
|
||||||
|
TableT table;
|
||||||
for (std::size_t i = 0; i < n; i++) {
|
for (std::size_t i = 0; i < n; i++) {
|
||||||
auto key = rnd();
|
auto key = rnd();
|
||||||
auto value = rnd();
|
auto value = rnd();
|
||||||
data.emplace_back(key, value);
|
data.emplace_back(key, value);
|
||||||
|
table.emplace(key, value);
|
||||||
keys.push_back(key);
|
keys.push_back(key);
|
||||||
}
|
}
|
||||||
TableT table(data.begin(), data.end());
|
|
||||||
|
|
||||||
std::size_t key_i = 0;
|
std::size_t key_i = 0;
|
||||||
td::random_shuffle(td::as_mutable_span(keys), rnd);
|
td::random_shuffle(td::as_mutable_span(keys), rnd);
|
||||||
|
Loading…
Reference in New Issue
Block a user