Remove value_type from SetNode.

This commit is contained in:
levlam 2022-02-21 02:22:01 +03:00
parent 9e8b2489bd
commit f0a2ccd0fb
4 changed files with 50 additions and 56 deletions

View File

@ -125,17 +125,16 @@ class FlatHashTableChunks {
using NodeIterator = typename fixed_vector<Node>::iterator;
using ConstNodeIterator = typename fixed_vector<Node>::const_iterator;
using KeyT = typename Node::key_type;
using key_type = typename Node::key_type;
using public_type = typename Node::public_type;
using KeyT = typename Node::public_key_type;
using key_type = typename Node::public_key_type;
using value_type = typename Node::public_type;
struct Iterator {
using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = public_type;
using pointer = public_type *;
using reference = public_type &;
using value_type = FlatHashTableChunks::value_type;
using pointer = value_type *;
using reference = value_type &;
friend class FlatHashTableChunks;
Iterator &operator++() {
@ -177,7 +176,7 @@ class FlatHashTableChunks {
struct ConstIterator {
using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = public_type;
using value_type = FlatHashTableChunks::value_type;
using pointer = const value_type *;
using reference = const value_type &;
@ -214,21 +213,25 @@ class FlatHashTableChunks {
using const_iterator = ConstIterator;
FlatHashTableChunks() = default;
FlatHashTableChunks(const FlatHashTableChunks &other) : FlatHashTableChunks(other.begin(), other.end()) {
FlatHashTableChunks(const FlatHashTableChunks &other) {
assign(other);
}
FlatHashTableChunks &operator=(const FlatHashTableChunks &other) {
assign(other.begin(), other.end());
clear();
assign(other);
return *this;
}
FlatHashTableChunks(std::initializer_list<Node> nodes) {
reserve(nodes.size());
for (auto &node : nodes) {
CHECK(!node.empty());
if (count(node.key()) > 0) {
for (auto &new_node : nodes) {
CHECK(!new_node.empty());
if (count(new_node.key()) > 0) {
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;
template <class ItT>
FlatHashTableChunks(ItT begin, ItT end) {
assign(begin, end);
}
size_t bucket_count() const {
return nodes_.size();
}
@ -270,7 +268,7 @@ class FlatHashTableChunks {
auto mask_it = MaskHelper::equal_mask(chunk.ctrl, hash.small_hash);
for (auto pos : mask_it) {
auto it = chunk_begin + pos;
if (likely(EqT()(it->first, key))) {
if (likely(EqT()(it->key(), key))) {
return Iterator{it, this};
}
}
@ -367,8 +365,9 @@ class FlatHashTableChunks {
}
}
typename Node::value_type &operator[](const KeyT &key) {
return emplace(key).first->value();
template <class T = typename Node::second_type>
T &operator[](const KeyT &key) {
return emplace(key).first->second;
}
size_t erase(const KeyT &key) {
@ -419,12 +418,12 @@ class FlatHashTableChunks {
fixed_vector<Chunk> chunks_;
size_t used_nodes_{};
template <class ItT>
void assign(ItT begin, ItT end) {
clear();
reserve(std::distance(begin, end));
for (; begin != end; ++begin) {
emplace(begin->first, begin->second);
void assign(const FlatHashTableChunks &other) {
reserve(other.size());
for (const auto &new_node : other) {
Node node;
node.copy_from(new_node);
emplace_node(std::move(node));
}
}
@ -508,7 +507,7 @@ class FlatHashTableChunks {
void emplace_node(Node &&node) {
DCHECK(!node.empty());
auto hash = calc_hash(node.first);
auto hash = calc_hash(node.key());
auto chunk_it = get_chunk_it(hash.chunk_i);
while (true) {
auto chunk_i = chunk_it.pos();
@ -543,7 +542,7 @@ class FlatHashTableChunks {
size_t empty_i = it - nodes_.begin();
DCHECK(0 <= empty_i && empty_i < nodes_.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);
while (true) {
auto chunk_i = chunk_it.pos();

View File

@ -28,20 +28,19 @@ template <class KeyT, class ValueT>
struct MapNode {
using first_type = KeyT;
using second_type = ValueT;
using key_type = KeyT;
using public_type = MapNode<KeyT, ValueT>;
using value_type = ValueT;
using public_key_type = KeyT;
using public_type = MapNode;
KeyT first{};
union {
ValueT second;
};
const auto &key() const {
const KeyT &key() const {
return first;
}
auto &value() {
return second;
}
auto &get_public() {
MapNode &get_public() {
return *this;
}
@ -100,23 +99,19 @@ struct MapNode {
template <class KeyT>
struct SetNode {
using first_type = KeyT;
using key_type = KeyT;
using public_key_type = KeyT;
using public_type = KeyT;
using value_type = KeyT;
KeyT first{};
const auto &key() const {
return first;
}
const auto &value() const {
const KeyT &key() const {
return first;
}
auto &get_public() {
KeyT &get_public() {
return first;
}
SetNode() = default;
explicit SetNode(KeyT key) : first(std::move(key)) {
}
@ -162,17 +157,16 @@ class FlatHashTable {
using NodeIterator = typename fixed_vector<Node>::iterator;
using ConstNodeIterator = typename fixed_vector<Node>::const_iterator;
using KeyT = typename Node::key_type;
using key_type = typename Node::key_type;
using public_type = typename Node::public_type;
using KeyT = typename Node::public_key_type;
using key_type = typename Node::public_key_type;
using value_type = typename Node::public_type;
struct Iterator {
using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = public_type;
using pointer = public_type *;
using reference = public_type &;
using value_type = FlatHashTable::value_type;
using pointer = value_type *;
using reference = value_type &;
friend class FlatHashTable;
Iterator &operator++() {
@ -214,7 +208,7 @@ class FlatHashTable {
struct ConstIterator {
using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = public_type;
using value_type = FlatHashTable::value_type;
using pointer = const value_type *;
using reference = const value_type &;
@ -391,8 +385,9 @@ class FlatHashTable {
}
}
typename Node::value_type &operator[](const KeyT &key) {
return emplace(key).first->value();
template <class T = typename Node::second_type>
T &operator[](const KeyT &key) {
return emplace(key).first->second;
}
size_t erase(const KeyT &key) {

View File

@ -176,7 +176,6 @@ TEST(FlatHashMap, basic) {
ASSERT_EQ("a", kv.find("a")->first);
ASSERT_EQ("b", kv.find("a")->second);
ASSERT_EQ("a", kv.find("a")->key());
ASSERT_EQ("b", kv.find("a")->value());
kv.find("a")->second = "c";
ASSERT_EQ("c", kv.find("a")->second);
ASSERT_EQ("c", kv["a"]);

View File

@ -190,13 +190,14 @@ static void BM_Get(benchmark::State &state) {
td::vector<KeyValue> data;
td::vector<Key> keys;
TableT table;
for (std::size_t i = 0; i < n; i++) {
auto key = rnd();
auto value = rnd();
data.emplace_back(key, value);
table.emplace(key, value);
keys.push_back(key);
}
TableT table(data.begin(), data.end());
std::size_t key_i = 0;
td::random_shuffle(td::as_mutable_span(keys), rnd);