Bug 1698098 - Add nsBaseHashtable::Clone methods. r=xpcom-reviewers,nika

Differential Revision: https://phabricator.services.mozilla.com/D106883
This commit is contained in:
Simon Giesecke 2021-03-19 09:01:46 +00:00
parent 02a4432e92
commit e0393699f5
3 changed files with 72 additions and 0 deletions

View File

@ -878,6 +878,26 @@ class nsBaseHashtable
}
using nsTHashtable<EntryType>::MarkImmutable;
/**
* Makes a clone of this hashtable by copying all entries. This requires
* KeyType and DataType to be copy-constructible.
*/
nsBaseHashtable Clone() const { return CloneAs<nsBaseHashtable>(); }
protected:
template <typename T>
T CloneAs() const {
static_assert(std::is_base_of_v<nsBaseHashtable, T>);
// XXX This can probably be optimized, see Bug 1694368.
T result(Count());
for (const auto& srcEntry : *this) {
result.WithEntryHandle(srcEntry.GetKey(), [&](auto&& dstEntry) {
dstEntry.Insert(srcEntry.GetData());
});
}
return result;
}
};
//

View File

@ -89,6 +89,10 @@ class nsRefCountedHashtable
* @return true if an entry for aKey was found (and removed)
*/
inline bool Remove(KeyType aKey, RawPointerType* aData = nullptr);
nsRefCountedHashtable Clone() const {
return this->template CloneAs<nsRefCountedHashtable>();
}
};
template <typename K, typename T>

View File

@ -1531,3 +1531,51 @@ TEST(Hashtables, RefPtrHashtable)
}
ASSERT_EQ(count, uint32_t(0));
}
TEST(Hashtables, RefPtrHashtable_Clone)
{
// check a RefPtr-hashtable
nsRefPtrHashtable<nsCStringHashKey, TestUniCharRefCounted> EntToUniClass(
ENTITY_COUNT);
for (auto& entity : gEntities) {
EntToUniClass.InsertOrUpdate(
nsDependentCString(entity.mStr),
MakeRefPtr<TestUniCharRefCounted>(entity.mUnicode));
}
auto clone = EntToUniClass.Clone();
static_assert(std::is_same_v<decltype(clone), decltype(EntToUniClass)>);
EXPECT_EQ(clone.Count(), EntToUniClass.Count());
for (const auto& entry : EntToUniClass) {
auto cloneEntry = clone.Lookup(entry.GetKey());
EXPECT_TRUE(cloneEntry);
EXPECT_EQ(cloneEntry.Data(), entry.GetWeak());
}
}
TEST(Hashtables, Clone)
{
static constexpr uint64_t count = 10;
nsTHashMap<nsUint64HashKey, uint64_t> table;
for (uint64_t i = 0; i < count; i++) {
table.InsertOrUpdate(42 + i, i);
}
auto clone = table.Clone();
static_assert(std::is_same_v<decltype(clone), decltype(table)>);
EXPECT_EQ(clone.Count(), table.Count());
for (const auto& entry : table) {
auto cloneEntry = clone.Lookup(entry.GetKey());
EXPECT_TRUE(cloneEntry);
EXPECT_EQ(cloneEntry.Data(), entry.GetData());
}
}