diff options
author | Abseil Team <absl-team@google.com> | 2021-02-10 08:52:54 -0800 |
---|---|---|
committer | Derek Mauro <dmauro@google.com> | 2021-02-10 17:01:18 -0500 |
commit | 1d1ad2292bb5c7be26074e516b4cc70d9cc469f9 (patch) | |
tree | 698d051a6c78c3b64e71b245d62a7ca80ee5b66a | |
parent | 2aa00ab2f22cf4e0e85e622c3254d483b2ddfb30 (diff) |
Export of internal Abseil changes
--
f9476c95cf7625d7b0fc4661f253b0aac4341044 by Abseil Team <absl-team@google.com>:
Add a test to verify that the new checksum field in Hashtablez is calculated
PiperOrigin-RevId: 356744293
--
ff8a3612463000e8c3d451e50367a3c65cb6cf21 by Abseil Team <absl-team@google.com>:
Remove the implied support comment for port.h, attributes.h, and integral_types.h's C compatibility from the header documentations.
Abseil-cpp is a C++ library; this brings port.h, attributes.h, and integral_types.h, into our stance for the rest of Abseil (aka, no assurance of C compatibility)
There is no guarantee that future changes to port.h, attributes.h, and integral_types.h, and their dependencies, will remain compatible with C, even for macros and definitions that currently are.
PiperOrigin-RevId: 356727505
--
be62292016381deee628dbb3f36cb6009bcc0282 by Abseil Team <absl-team@google.com>:
internal change
PiperOrigin-RevId: 356608125
--
13b35f17171df3d6853ea7088797b3be611505fc by Evan Brown <ezb@google.com>:
Clarify the comments for CapacityToGrowth/GrowthToLowerboundCapacity methods to specify the intent that capacity should equal growth when `capacity+1 < kWidth`.
Also add testing for this behavior.
PiperOrigin-RevId: 356579041
GitOrigin-RevId: f9476c95cf7625d7b0fc4661f253b0aac4341044
Change-Id: Iadd094d109b4869998f2427319ef66d1cf1e8eff
-rw-r--r-- | absl/base/attributes.h | 2 | ||||
-rw-r--r-- | absl/base/port.h | 1 | ||||
-rw-r--r-- | absl/container/internal/raw_hash_set.h | 14 | ||||
-rw-r--r-- | absl/container/internal/raw_hash_set_test.cc | 34 | ||||
-rw-r--r-- | absl/status/status_test.cc | 1 |
5 files changed, 40 insertions, 12 deletions
diff --git a/absl/base/attributes.h b/absl/base/attributes.h index f14f7bb0..faa5b27e 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -18,8 +18,6 @@ // These macros are used within Abseil and allow the compiler to optimize, where // applicable, certain function calls. // -// This file is used for both C and C++! -// // Most macros here are exposing GCC or Clang features, and are stubbed out for // other compilers. // diff --git a/absl/base/port.h b/absl/base/port.h index 6c28068d..5bc4d6cd 100644 --- a/absl/base/port.h +++ b/absl/base/port.h @@ -14,7 +14,6 @@ // // This files is a forwarding header for other headers containing various // portability macros and functions. -// This file is used for both C and C++! #ifndef ABSL_BASE_PORT_H_ #define ABSL_BASE_PORT_H_ diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 74b2ef4c..80fc2cba 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -468,8 +468,16 @@ inline size_t NormalizeCapacity(size_t n) { return n ? ~size_t{} >> countl_zero(n) : 1; } -// We use 7/8th as maximum load factor. -// For 16-wide groups, that gives an average of two empty slots per group. +// General notes on capacity/growth methods below: +// - We use 7/8th as maximum load factor. For 16-wide groups, that gives an +// average of two empty slots per group. +// - For (capacity+1) >= Group::kWidth, growth is 7/8*capacity. +// - For (capacity+1) < Group::kWidth, growth == capacity. In this case, we +// never need to probe (the whole table fits in one group) so we don't need a +// load factor less than 1. + +// Given `capacity` of the table, returns the size (i.e. number of full slots) +// at which we should grow the capacity. inline size_t CapacityToGrowth(size_t capacity) { assert(IsValidCapacity(capacity)); // `capacity*7/8` @@ -480,7 +488,7 @@ inline size_t CapacityToGrowth(size_t capacity) { return capacity - capacity / 8; } // From desired "growth" to a lowerbound of the necessary capacity. -// Might not be a valid one and required NormalizeCapacity(). +// Might not be a valid one and requires NormalizeCapacity(). inline size_t GrowthToLowerboundCapacity(size_t growth) { // `growth*8/7` if (Group::kWidth == 8 && growth == 7) { diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index 0fba46ff..81c4b47c 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -14,6 +14,7 @@ #include "absl/container/internal/raw_hash_set.h" +#include <atomic> #include <cmath> #include <cstdint> #include <deque> @@ -22,6 +23,8 @@ #include <numeric> #include <random> #include <string> +#include <unordered_map> +#include <unordered_set> #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -48,11 +51,10 @@ struct RawHashSetTestOnlyAccess { namespace { -using ::testing::DoubleNear; using ::testing::ElementsAre; +using ::testing::Eq; using ::testing::Ge; using ::testing::Lt; -using ::testing::Optional; using ::testing::Pair; using ::testing::UnorderedElementsAre; @@ -75,8 +77,14 @@ TEST(Util, GrowthAndCapacity) { for (size_t growth = 0; growth < 10000; ++growth) { SCOPED_TRACE(growth); size_t capacity = NormalizeCapacity(GrowthToLowerboundCapacity(growth)); - // The capacity is large enough for `growth` + // The capacity is large enough for `growth`. EXPECT_THAT(CapacityToGrowth(capacity), Ge(growth)); + // For (capacity+1) < kWidth, growth should equal capacity. + if (capacity + 1 < Group::kWidth) { + EXPECT_THAT(CapacityToGrowth(capacity), Eq(capacity)); + } else { + EXPECT_THAT(CapacityToGrowth(capacity), Lt(capacity)); + } if (growth != 0 && capacity > 1) { // There is no smaller capacity that works. EXPECT_THAT(CapacityToGrowth(capacity / 2), Lt(growth)); @@ -1875,18 +1883,34 @@ TEST(RawHashSamplerTest, Sample) { auto& sampler = HashtablezSampler::Global(); size_t start_size = 0; - start_size += sampler.Iterate([&](const HashtablezInfo&) { ++start_size; }); + std::unordered_set<const HashtablezInfo*> preexisting_info; + start_size += sampler.Iterate([&](const HashtablezInfo& info) { + preexisting_info.insert(&info); + ++start_size; + }); std::vector<IntTable> tables; for (int i = 0; i < 1000000; ++i) { tables.emplace_back(); tables.back().insert(1); + tables.back().insert(i % 5); } size_t end_size = 0; - end_size += sampler.Iterate([&](const HashtablezInfo&) { ++end_size; }); + std::unordered_map<size_t, int> observed_checksums; + end_size += sampler.Iterate([&](const HashtablezInfo& info) { + if (preexisting_info.count(&info) == 0) { + observed_checksums[info.hashes_bitwise_xor.load( + std::memory_order_relaxed)]++; + } + ++end_size; + }); EXPECT_NEAR((end_size - start_size) / static_cast<double>(tables.size()), 0.01, 0.005); + EXPECT_EQ(observed_checksums.size(), 5); + for (const auto& [_, count] : observed_checksums) { + EXPECT_NEAR((100 * count) / static_cast<double>(tables.size()), 0.2, 0.05); + } } #endif // ABSL_INTERNAL_HASHTABLEZ_SAMPLE diff --git a/absl/status/status_test.cc b/absl/status/status_test.cc index 25333fa2..24eaed61 100644 --- a/absl/status/status_test.cc +++ b/absl/status/status_test.cc @@ -460,5 +460,4 @@ TEST(Status, Swap) { test_swap(no_payload, with_payload); test_swap(with_payload, no_payload); } - } // namespace |