Add Map/SetNode::copy_from.
This commit is contained in:
parent
983cc2c45c
commit
77ccc13181
@ -14,13 +14,13 @@
|
||||
|
||||
namespace td {
|
||||
template <class KeyT, class ValueT, class HashT = std::hash<KeyT>, class EqT = std::equal_to<KeyT>>
|
||||
//using FlatHashMap = FlatHashMapImpl<KeyT, ValueT, HashT, EqT>;
|
||||
using FlatHashMap = FlatHashMapChunks<KeyT, ValueT, HashT, EqT>;
|
||||
using FlatHashMap = FlatHashMapImpl<KeyT, ValueT, HashT, EqT>;
|
||||
//using FlatHashMap = FlatHashMapChunks<KeyT, ValueT, HashT, EqT>;
|
||||
//using FlatHashMap = std::unordered_map<KeyT, ValueT, HashT, EqT>;
|
||||
|
||||
template <class KeyT, class HashT = std::hash<KeyT>, class EqT = std::equal_to<KeyT>>
|
||||
//using FlatHashSet = FlatHashSetImpl<KeyT, HashT, EqT>;
|
||||
using FlatHashSet = FlatHashSetChunks<KeyT, HashT, EqT>;
|
||||
using FlatHashSet = FlatHashSetImpl<KeyT, HashT, EqT>;
|
||||
//using FlatHashSet = FlatHashSetChunks<KeyT, HashT, EqT>;
|
||||
//using FlatHashSet = std::unordered_set<KeyT, HashT, EqT>;
|
||||
|
||||
} // namespace td
|
||||
|
@ -71,6 +71,13 @@ struct MapNode {
|
||||
}
|
||||
}
|
||||
|
||||
void copy_from(const MapNode &other) {
|
||||
DCHECK(empty());
|
||||
DCHECK(!other.empty());
|
||||
first = other.first;
|
||||
new (&second) ValueT(other.second);
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return is_key_empty(key());
|
||||
}
|
||||
@ -97,7 +104,9 @@ struct SetNode {
|
||||
using key_type = KeyT;
|
||||
using public_type = KeyT;
|
||||
using value_type = KeyT;
|
||||
|
||||
KeyT first{};
|
||||
|
||||
const auto &key() const {
|
||||
return first;
|
||||
}
|
||||
@ -125,6 +134,12 @@ struct SetNode {
|
||||
}
|
||||
~SetNode() = default;
|
||||
|
||||
void copy_from(const SetNode &other) {
|
||||
DCHECK(empty());
|
||||
DCHECK(!other.empty());
|
||||
first = other.first;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return is_key_empty(key());
|
||||
}
|
||||
@ -236,27 +251,33 @@ class FlatHashTable {
|
||||
using const_iterator = ConstIterator;
|
||||
|
||||
FlatHashTable() = default;
|
||||
FlatHashTable(const FlatHashTable &other) : FlatHashTable(other.begin(), other.end()) {
|
||||
FlatHashTable(const FlatHashTable &other) {
|
||||
assign(other);
|
||||
}
|
||||
FlatHashTable &operator=(const FlatHashTable &other) {
|
||||
assign(other.begin(), other.end());
|
||||
clear();
|
||||
assign(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FlatHashTable(std::initializer_list<Node> nodes) {
|
||||
if (nodes.size() == 0) {
|
||||
return;
|
||||
}
|
||||
reserve(nodes.size());
|
||||
for (auto &new_node : nodes) {
|
||||
CHECK(!new_node.empty());
|
||||
auto bucket = calc_bucket(new_node.first);
|
||||
auto bucket = calc_bucket(new_node.key());
|
||||
while (true) {
|
||||
auto &node = nodes_[bucket];
|
||||
if (node.key() == new_node.first) {
|
||||
node.second = new_node.second;
|
||||
if (node.empty()) {
|
||||
node.copy_from(new_node);
|
||||
used_nodes_++;
|
||||
break;
|
||||
}
|
||||
if (node.empty()) {
|
||||
node.emplace(new_node.first, new_node.second);
|
||||
used_nodes_++;
|
||||
if (EqT()(node.key(), new_node.key())) {
|
||||
node.clear();
|
||||
node.copy_from(new_node);
|
||||
break;
|
||||
}
|
||||
next_bucket(bucket);
|
||||
@ -280,11 +301,6 @@ class FlatHashTable {
|
||||
}
|
||||
~FlatHashTable() = default;
|
||||
|
||||
template <class ItT>
|
||||
FlatHashTable(ItT begin, ItT end) {
|
||||
assign(begin, end);
|
||||
}
|
||||
|
||||
size_t bucket_count() const {
|
||||
return nodes_.size();
|
||||
}
|
||||
@ -434,12 +450,20 @@ class FlatHashTable {
|
||||
fixed_vector<Node> nodes_;
|
||||
size_t used_nodes_{};
|
||||
|
||||
template <class ItT>
|
||||
void assign(ItT begin, ItT end) {
|
||||
resize(std::distance(begin, end)); // TODO: should be conditional
|
||||
for (; begin != end; ++begin) {
|
||||
emplace(begin->first, begin->second);
|
||||
void assign(const FlatHashTable &other) {
|
||||
resize(other.size());
|
||||
for (const auto &new_node : other) {
|
||||
auto bucket = calc_bucket(new_node.key());
|
||||
while (true) {
|
||||
auto &node = nodes_[bucket];
|
||||
if (node.empty()) {
|
||||
node.copy_from(new_node);
|
||||
break;
|
||||
}
|
||||
next_bucket(bucket);
|
||||
}
|
||||
}
|
||||
used_nodes_ = other.size();
|
||||
}
|
||||
|
||||
void try_grow() {
|
||||
|
@ -129,7 +129,10 @@ TEST(FlatHashMap, basic) {
|
||||
{ ASSERT_EQ(Data{}, extract_kv(KV())); }
|
||||
|
||||
{
|
||||
KV kv(data.begin(), data.end());
|
||||
KV kv;
|
||||
for (auto &pair : data) {
|
||||
kv.emplace(pair.first, pair.second);
|
||||
}
|
||||
ASSERT_EQ(data, extract_kv(kv));
|
||||
|
||||
KV copied_kv(kv);
|
||||
@ -153,7 +156,10 @@ TEST(FlatHashMap, basic) {
|
||||
ASSERT_TRUE(kv.empty());
|
||||
kv = std::move(assign_moved_kv);
|
||||
|
||||
KV it_copy_kv(kv.begin(), kv.end());
|
||||
KV it_copy_kv;
|
||||
for (auto &pair : kv) {
|
||||
it_copy_kv.emplace(pair.first, pair.second);
|
||||
}
|
||||
ASSERT_EQ(data, extract_kv(it_copy_kv));
|
||||
}
|
||||
|
||||
@ -161,7 +167,9 @@ TEST(FlatHashMap, basic) {
|
||||
KV kv;
|
||||
ASSERT_TRUE(kv.empty());
|
||||
ASSERT_EQ(0u, kv.size());
|
||||
kv = KV(data.begin(), data.end());
|
||||
for (auto &pair : data) {
|
||||
kv.emplace(pair.first, pair.second);
|
||||
}
|
||||
ASSERT_TRUE(!kv.empty());
|
||||
ASSERT_EQ(2u, kv.size());
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user