Commit 4835f0e5 authored by Nathan Bronson's avatar Nathan Bronson Committed by Facebook Github Bot

support for unequal allocators

Summary:
The move constructor and move assignment operator for
allocator-aware containers is supposed to allocate new memory and
move values across when the underlying allocators are not equal.
Previously F14 just checked that this wasn't the case.  This diff
implements this feature.  This allows F14 tables to be moved into and
out of allocator-managed memory segments, such as arenas or shared
memory extents.

Reviewed By: yfeldblum

Differential Revision: D8022286

fbshipit-source-id: ff0b220450bb76822cc68cebad079a7ef43e2429
parent d1fdba5f
......@@ -136,9 +136,8 @@ class F14BasicMap {
using allocator_type = typename Policy::Alloc;
using reference = value_type&;
using const_reference = value_type const&;
using pointer = typename std::allocator_traits<allocator_type>::pointer;
using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
using pointer = typename Policy::AllocTraits::pointer;
using const_pointer = typename Policy::AllocTraits::const_pointer;
using iterator = typename Policy::Iter;
using const_iterator = typename Policy::ConstIter;
......@@ -148,7 +147,7 @@ class F14BasicMap {
public:
//// PUBLIC - Member functions
F14BasicMap() noexcept(F14Table<Policy>::kDefaultConstructIsNoexcept)
F14BasicMap() noexcept(Policy::kDefaultConstructIsNoexcept)
: F14BasicMap(0) {}
explicit F14BasicMap(
......@@ -210,7 +209,7 @@ class F14BasicMap {
F14BasicMap(F14BasicMap&& rhs) = default;
F14BasicMap(F14BasicMap&& rhs, allocator_type const& alloc) noexcept(
F14Table<Policy>::kAllocIsAlwaysEqual)
Policy::kAllocIsAlwaysEqual)
: table_{std::move(rhs.table_), alloc} {}
F14BasicMap(
......@@ -834,14 +833,11 @@ class F14ValueMap
using Super = f14::detail::F14BasicMap<Policy>;
public:
F14ValueMap() noexcept(
f14::detail::F14Table<Policy>::kDefaultConstructIsNoexcept)
: Super{} {}
F14ValueMap() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {}
using Super::Super;
void swap(F14ValueMap& rhs) noexcept(
f14::detail::F14Table<Policy>::kSwapIsNoexcept) {
void swap(F14ValueMap& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_);
}
};
......@@ -884,14 +880,11 @@ class F14NodeMap
using Super = f14::detail::F14BasicMap<Policy>;
public:
F14NodeMap() noexcept(
f14::detail::F14Table<Policy>::kDefaultConstructIsNoexcept)
: Super{} {}
F14NodeMap() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {}
using Super::Super;
void swap(F14NodeMap& rhs) noexcept(
f14::detail::F14Table<Policy>::kSwapIsNoexcept) {
void swap(F14NodeMap& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_);
}
......@@ -942,15 +935,12 @@ class F14VectorMap
using reverse_iterator = typename Policy::ReverseIter;
using const_reverse_iterator = typename Policy::ConstReverseIter;
F14VectorMap() noexcept(
f14::detail::F14Table<Policy>::kDefaultConstructIsNoexcept)
: Super{} {}
F14VectorMap() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {}
// inherit constructors
using Super::Super;
void swap(F14VectorMap& rhs) noexcept(
f14::detail::F14Table<Policy>::kSwapIsNoexcept) {
void swap(F14VectorMap& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_);
}
......@@ -1040,7 +1030,7 @@ class F14VectorMap
// The item still needs to be hashable during this call, so we must destroy
// the value _afterwards_.
this->table_.erase(underlying);
std::allocator_traits<Alloc>::destroy(a, std::addressof(values[index]));
Policy::AllocTraits::destroy(a, std::addressof(values[index]));
// move the last element in values_ down and fix up the inbound index
auto tailIndex = this->size();
......
......@@ -131,9 +131,8 @@ class F14BasicSet {
using allocator_type = typename Policy::Alloc;
using reference = value_type&;
using const_reference = value_type const&;
using pointer = typename std::allocator_traits<allocator_type>::pointer;
using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
using pointer = typename Policy::AllocTraits::pointer;
using const_pointer = typename Policy::AllocTraits::const_pointer;
using iterator = typename Policy::Iter;
using const_iterator = iterator;
......@@ -143,7 +142,7 @@ class F14BasicSet {
public:
//// PUBLIC - Member functions
F14BasicSet() noexcept(F14Table<Policy>::kDefaultConstructIsNoexcept)
F14BasicSet() noexcept(Policy::kDefaultConstructIsNoexcept)
: F14BasicSet(0) {}
explicit F14BasicSet(
......@@ -205,7 +204,7 @@ class F14BasicSet {
F14BasicSet(F14BasicSet&& rhs) = default;
F14BasicSet(F14BasicSet&& rhs, allocator_type const& alloc) noexcept(
F14Table<Policy>::kAllocIsAlwaysEqual)
Policy::kAllocIsAlwaysEqual)
: table_{std::move(rhs.table_), alloc} {}
F14BasicSet(
......@@ -657,14 +656,11 @@ class F14ValueSet
using Super = f14::detail::F14BasicSet<Policy>;
public:
F14ValueSet() noexcept(
f14::detail::F14Table<Policy>::kDefaultConstructIsNoexcept)
: Super{} {}
F14ValueSet() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {}
using Super::Super;
void swap(F14ValueSet& rhs) noexcept(
f14::detail::F14Table<Policy>::kSwapIsNoexcept) {
void swap(F14ValueSet& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_);
}
};
......@@ -700,14 +696,11 @@ class F14NodeSet
using Super = f14::detail::F14BasicSet<Policy>;
public:
F14NodeSet() noexcept(
f14::detail::F14Table<Policy>::kDefaultConstructIsNoexcept)
: Super{} {}
F14NodeSet() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {}
using Super::Super;
void swap(F14NodeSet& rhs) noexcept(
f14::detail::F14Table<Policy>::kSwapIsNoexcept) {
void swap(F14NodeSet& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_);
}
};
......@@ -750,15 +743,12 @@ class F14VectorSet
using reverse_iterator = typename Policy::ReverseIter;
using const_reverse_iterator = typename Policy::ConstReverseIter;
F14VectorSet() noexcept(
f14::detail::F14Table<Policy>::kDefaultConstructIsNoexcept)
: Super{} {}
F14VectorSet() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {}
// inherit constructors
using Super::Super;
void swap(F14VectorSet& rhs) noexcept(
f14::detail::F14Table<Policy>::kSwapIsNoexcept) {
void swap(F14VectorSet& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_);
}
......@@ -849,7 +839,7 @@ class F14VectorSet
// destroy the value and remove the ptr from the base table
auto index = underlying.item();
this->table_.eraseInto(underlying, beforeDestroy);
std::allocator_traits<Alloc>::destroy(a, std::addressof(values[index]));
Policy::AllocTraits::destroy(a, std::addressof(values[index]));
// move the last element in values_ down and fix up the inbound index
auto tailIndex = this->size();
......
This diff is collapsed.
This diff is collapsed.
......@@ -364,11 +364,28 @@ void runMultiScopeTest() {
checkLocation("b1", segment1, *b1);
EXPECT_TRUE(*a1 == *c1);
// not yet supported by F14
// *a1 = std::move(*e2);
//
// checkLocation("a1", segment1, *a1);
// checkLocation("e2", segment2, *e2);
*a1 = std::move(*e2);
EXPECT_TRUE(*f2 == *a1);
checkLocation("a1", segment1, *a1);
checkLocation("e2", segment2, *e2);
auto g2 = segment2->construct<M>(anonymous_instance)(
std::move(*a1), typename M::allocator_type{mgr2});
EXPECT_TRUE(*f2 == *g2);
checkLocation("f2", segment2, *f2);
checkLocation("g2", segment2, *g2);
segment1->destroy_ptr(a1);
segment1->destroy_ptr(b1);
segment1->destroy_ptr(c1);
segment2->destroy_ptr(d2);
segment2->destroy_ptr(e2);
segment2->destroy_ptr(f2);
segment2->destroy_ptr(g2);
}
TEST(ShmF14ValueI2VVI, multiScope) {
......
......@@ -256,6 +256,8 @@ void runRandom() {
R r0;
R r1;
std::size_t rollbacks = 0;
std::size_t resizingSmallRollbacks = 0;
std::size_t resizingLargeRollbacks = 0;
for (std::size_t reps = 0; reps < 100000; ++reps) {
if (pctDist(gen) < 20) {
......@@ -476,6 +478,14 @@ void runRandom() {
}
}
if (t0.bucket_count() == t0.size() && t0.size() > 0) {
if (t0.size() < 10) {
++resizingSmallRollbacks;
} else {
++resizingLargeRollbacks;
}
}
assert(t0.size() == r0.size());
for (auto&& kv : r0) {
auto t = t0.find(kv.first);
......@@ -487,6 +497,8 @@ void runRandom() {
}
EXPECT_GE(rollbacks, 10);
EXPECT_GE(resizingSmallRollbacks, 1);
EXPECT_GE(resizingLargeRollbacks, 1);
}
EXPECT_EQ(testAllocatedMemorySize, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment