Skip to content

Commit

Permalink
move Counts and Tracked from F14MapTest.cpp to F14TestUtil.h
Browse files Browse the repository at this point in the history
Summary:
Move the helper classes into F14TestUtil header so that F14SetTest could use
them as well.

Reviewed By: yfeldblum

Differential Revision: D7336571

fbshipit-source-id: 9fc96e43fe882d05b6b6fbcd075a42f5184f7d62
  • Loading branch information
shixiao authored and facebook-github-bot committed Mar 21, 2018
1 parent 2be7915 commit e3f2a69
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 174 deletions.
174 changes: 1 addition & 173 deletions folly/container/test/F14MapTest.cpp
Expand Up @@ -33,6 +33,7 @@
#include <folly/container/test/F14TestUtil.h>

using namespace folly;
using namespace folly::f14;
using namespace folly::string_piece_literals;

namespace {
Expand Down Expand Up @@ -432,179 +433,6 @@ TEST(F14ValueMap, steady_state_stats) {
LOG(INFO) << "F14ValueMap at steady state -> " << F14TableStats::compute(h);
}

// Tracked is implicitly constructible across tags
namespace {
struct Counts {
uint64_t copyConstruct{0};
uint64_t moveConstruct{0};
uint64_t copyConvert{0};
uint64_t moveConvert{0};
uint64_t copyAssign{0};
uint64_t moveAssign{0};
uint64_t defaultConstruct{0};

explicit Counts(
uint64_t copConstr = 0,
uint64_t movConstr = 0,
uint64_t copConv = 0,
uint64_t movConv = 0,
uint64_t copAssign = 0,
uint64_t movAssign = 0,
uint64_t def = 0)
: copyConstruct{copConstr},
moveConstruct{movConstr},
copyConvert{copConv},
moveConvert{movConv},
copyAssign{copAssign},
moveAssign{movAssign},
defaultConstruct{def} {}

uint64_t dist(Counts const& rhs) const {
auto d = [](uint64_t x, uint64_t y) { return (x - y) * (x - y); };
return d(copyConstruct, rhs.copyConstruct) +
d(moveConstruct, rhs.moveConstruct) + d(copyConvert, rhs.copyConvert) +
d(moveConvert, rhs.moveConvert) + d(copyAssign, rhs.copyAssign) +
d(moveAssign, rhs.moveAssign) +
d(defaultConstruct, rhs.defaultConstruct);
}

bool operator==(Counts const& rhs) const {
return copyConstruct == rhs.copyConstruct &&
moveConstruct == rhs.moveConstruct && copyConvert == rhs.copyConvert &&
moveConvert == rhs.moveConvert && copyAssign == rhs.copyAssign &&
moveAssign == rhs.moveAssign &&
defaultConstruct == rhs.defaultConstruct;
}
bool operator!=(Counts const& rhs) const {
return !(*this == rhs);
}
};

thread_local Counts sumCounts{};

template <int Tag>
struct Tracked {
static thread_local Counts counts;

uint64_t val_;

Tracked() : val_{0} {
sumCounts.defaultConstruct++;
counts.defaultConstruct++;
}
/* implicit */ Tracked(uint64_t val) : val_{val} {
sumCounts.copyConvert++;
counts.copyConvert++;
}
Tracked(Tracked const& rhs) : val_{rhs.val_} {
sumCounts.copyConstruct++;
counts.copyConstruct++;
}
Tracked(Tracked&& rhs) noexcept : val_{rhs.val_} {
sumCounts.moveConstruct++;
counts.moveConstruct++;
}
Tracked& operator=(Tracked const& rhs) {
val_ = rhs.val_;
sumCounts.copyAssign++;
counts.copyAssign++;
return *this;
}
Tracked& operator=(Tracked&& rhs) noexcept {
val_ = rhs.val_;
sumCounts.moveAssign++;
counts.moveAssign++;
return *this;
}

template <int T>
/* implicit */ Tracked(Tracked<T> const& rhs) : val_{rhs.val_} {
sumCounts.copyConvert++;
counts.copyConvert++;
}

template <int T>
/* implicit */ Tracked(Tracked<T>&& rhs) : val_{rhs.val_} {
sumCounts.moveConvert++;
counts.moveConvert++;
}

bool operator==(Tracked const& rhs) const {
return val_ == rhs.val_;
}
bool operator!=(Tracked const& rhs) const {
return !(*this == rhs);
}
};

template <>
thread_local Counts Tracked<0>::counts{};
template <>
thread_local Counts Tracked<1>::counts{};
template <>
thread_local Counts Tracked<2>::counts{};
template <>
thread_local Counts Tracked<3>::counts{};
template <>
thread_local Counts Tracked<4>::counts{};
template <>
thread_local Counts Tracked<5>::counts{};

void resetTracking() {
sumCounts = Counts{};
Tracked<0>::counts = Counts{};
Tracked<1>::counts = Counts{};
Tracked<2>::counts = Counts{};
Tracked<3>::counts = Counts{};
Tracked<4>::counts = Counts{};
Tracked<5>::counts = Counts{};
}
} // namespace

std::ostream& operator<<(std::ostream& xo, Counts const& counts) {
xo << "[";
std::string glue = "";
if (counts.copyConstruct > 0) {
xo << glue << counts.copyConstruct << " copy";
glue = ", ";
}
if (counts.moveConstruct > 0) {
xo << glue << counts.moveConstruct << " move";
glue = ", ";
}
if (counts.copyConvert > 0) {
xo << glue << counts.copyConvert << " copy convert";
glue = ", ";
}
if (counts.moveConvert > 0) {
xo << glue << counts.moveConvert << " move convert";
glue = ", ";
}
if (counts.copyAssign > 0) {
xo << glue << counts.copyAssign << " copy assign";
glue = ", ";
}
if (counts.moveAssign > 0) {
xo << glue << counts.moveAssign << " move assign";
glue = ", ";
}
if (counts.defaultConstruct > 0) {
xo << glue << counts.defaultConstruct << " default construct";
glue = ", ";
}
xo << "]";
return xo;
}

namespace std {
template <int Tag>
struct hash<Tracked<Tag>> {
size_t operator()(Tracked<Tag> const& tracked) const {
return tracked.val_ ^ Tag;
}
};
} // namespace std

TEST(Tracked, baseline) {
Tracked<0> a0;

Expand Down
1 change: 1 addition & 0 deletions folly/container/test/F14SetTest.cpp
Expand Up @@ -31,6 +31,7 @@
#include <folly/container/test/F14TestUtil.h>

using namespace folly;
using namespace folly::f14;
using namespace folly::string_piece_literals;

namespace {
Expand Down
170 changes: 169 additions & 1 deletion folly/container/test/F14TestUtil.h
Expand Up @@ -108,7 +108,167 @@ struct MoveOnlyTestInt {
}
};

} // namespace f14
// Tracked is implicitly constructible across tags
struct Counts {
uint64_t copyConstruct{0};
uint64_t moveConstruct{0};
uint64_t copyConvert{0};
uint64_t moveConvert{0};
uint64_t copyAssign{0};
uint64_t moveAssign{0};
uint64_t defaultConstruct{0};

explicit Counts(
uint64_t copConstr = 0,
uint64_t movConstr = 0,
uint64_t copConv = 0,
uint64_t movConv = 0,
uint64_t copAssign = 0,
uint64_t movAssign = 0,
uint64_t def = 0)
: copyConstruct{copConstr},
moveConstruct{movConstr},
copyConvert{copConv},
moveConvert{movConv},
copyAssign{copAssign},
moveAssign{movAssign},
defaultConstruct{def} {}

uint64_t dist(Counts const& rhs) const {
auto d = [](uint64_t x, uint64_t y) { return (x - y) * (x - y); };
return d(copyConstruct, rhs.copyConstruct) +
d(moveConstruct, rhs.moveConstruct) + d(copyConvert, rhs.copyConvert) +
d(moveConvert, rhs.moveConvert) + d(copyAssign, rhs.copyAssign) +
d(moveAssign, rhs.moveAssign) +
d(defaultConstruct, rhs.defaultConstruct);
}

bool operator==(Counts const& rhs) const {
return copyConstruct == rhs.copyConstruct &&
moveConstruct == rhs.moveConstruct && copyConvert == rhs.copyConvert &&
moveConvert == rhs.moveConvert && copyAssign == rhs.copyAssign &&
moveAssign == rhs.moveAssign &&
defaultConstruct == rhs.defaultConstruct;
}
bool operator!=(Counts const& rhs) const {
return !(*this == rhs);
}
};

std::ostream& operator<<(std::ostream& xo, Counts const& counts) {
xo << "[";
std::string glue = "";
if (counts.copyConstruct > 0) {
xo << glue << counts.copyConstruct << " copy";
glue = ", ";
}
if (counts.moveConstruct > 0) {
xo << glue << counts.moveConstruct << " move";
glue = ", ";
}
if (counts.copyConvert > 0) {
xo << glue << counts.copyConvert << " copy convert";
glue = ", ";
}
if (counts.moveConvert > 0) {
xo << glue << counts.moveConvert << " move convert";
glue = ", ";
}
if (counts.copyAssign > 0) {
xo << glue << counts.copyAssign << " copy assign";
glue = ", ";
}
if (counts.moveAssign > 0) {
xo << glue << counts.moveAssign << " move assign";
glue = ", ";
}
if (counts.defaultConstruct > 0) {
xo << glue << counts.defaultConstruct << " default construct";
glue = ", ";
}
xo << "]";
return xo;
}

thread_local Counts sumCounts{};

template <int Tag>
struct Tracked {
static thread_local Counts counts;

uint64_t val_;

Tracked() : val_{0} {
sumCounts.defaultConstruct++;
counts.defaultConstruct++;
}
/* implicit */ Tracked(uint64_t val) : val_{val} {
sumCounts.copyConvert++;
counts.copyConvert++;
}
Tracked(Tracked const& rhs) : val_{rhs.val_} {
sumCounts.copyConstruct++;
counts.copyConstruct++;
}
Tracked(Tracked&& rhs) noexcept : val_{rhs.val_} {
sumCounts.moveConstruct++;
counts.moveConstruct++;
}
Tracked& operator=(Tracked const& rhs) {
val_ = rhs.val_;
sumCounts.copyAssign++;
counts.copyAssign++;
return *this;
}
Tracked& operator=(Tracked&& rhs) noexcept {
val_ = rhs.val_;
sumCounts.moveAssign++;
counts.moveAssign++;
return *this;
}

template <int T>
/* implicit */ Tracked(Tracked<T> const& rhs) : val_{rhs.val_} {
sumCounts.copyConvert++;
counts.copyConvert++;
}

template <int T>
/* implicit */ Tracked(Tracked<T>&& rhs) : val_{rhs.val_} {
sumCounts.moveConvert++;
counts.moveConvert++;
}

bool operator==(Tracked const& rhs) const {
return val_ == rhs.val_;
}
bool operator!=(Tracked const& rhs) const {
return !(*this == rhs);
}
};

template <>
thread_local Counts Tracked<0>::counts{};
template <>
thread_local Counts Tracked<1>::counts{};
template <>
thread_local Counts Tracked<2>::counts{};
template <>
thread_local Counts Tracked<3>::counts{};
template <>
thread_local Counts Tracked<4>::counts{};
template <>
thread_local Counts Tracked<5>::counts{};

void resetTracking() {
sumCounts = Counts{};
Tracked<0>::counts = Counts{};
Tracked<1>::counts = Counts{};
Tracked<2>::counts = Counts{};
Tracked<3>::counts = Counts{};
Tracked<4>::counts = Counts{};
Tracked<5>::counts = Counts{};
}

std::ostream& operator<<(std::ostream& xo, F14TableStats const& stats) {
using f14::Histo;
Expand Down Expand Up @@ -140,6 +300,7 @@ std::ostream& operator<<(std::ostream& xo, F14TableStats const& stats) {
return xo;
}

} // namespace f14
} // namespace folly

namespace std {
Expand All @@ -149,4 +310,11 @@ struct hash<folly::f14::MoveOnlyTestInt> {
return val.x;
}
};

template <int Tag>
struct hash<folly::f14::Tracked<Tag>> {
size_t operator()(folly::f14::Tracked<Tag> const& tracked) const {
return tracked.val_ ^ Tag;
}
};
} // namespace std

0 comments on commit e3f2a69

Please sign in to comment.