Abseil Common Libraries (C++) (grcp 依赖) https://abseil.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
4.4 KiB

// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/container/node_hash_map.h"
#include "absl/container/node_hash_set.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {
namespace {
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
// Create some tables of type `Table`, then look at all the new
// `HashtablezInfo`s to make sure that the `inline_element_size ==
// expected_element_size`. The `inline_element_size` is the amount of memory
// allocated for each slot of a hash table, that is `sizeof(slot_type)`. Add
// the new `HashtablezInfo`s to `preexisting_info`. Store all the new tables
// into `tables`.
template <class Table>
void TestInlineElementSize(
HashtablezSampler& sampler,
// clang-tidy gives a false positive on this declaration. This unordered
// set cannot be flat_hash_set, however, since that would introduce a mutex
// deadlock.
std::unordered_set<const HashtablezInfo*>& preexisting_info, // NOLINT
std::vector<Table>& tables, const typename Table::value_type& elt,
size_t expected_element_size) {
for (int i = 0; i < 10; ++i) {
// We create a new table and must store it somewhere so that when we store
// a pointer to the resulting `HashtablezInfo` into `preexisting_info`
// that we aren't storing a dangling pointer.
tables.emplace_back();
// We must insert an element to get a hashtablez to instantiate.
tables.back().insert(elt);
}
size_t new_count = 0;
sampler.Iterate([&](const HashtablezInfo& info) {
if (preexisting_info.insert(&info).second) {
Export of internal Abseil changes -- e7f53dfbf809812e84770217777f81b6308a3084 by Abseil Team <absl-team@google.com>: Add a parameter pack to absl profile to allow profiles to separate dynamic data from static data that is available at constructor-time. Background: `inline_element_size` is effectively constant, but there is a data race between its initialization and its access. We had fixed that race by making inline_element_size atomic. This CL changes `inline_element_size` back to a non-atomic integer, and provides a way for all profiles to provide Register()-time values. PiperOrigin-RevId: 413960559 -- 70234c5943f8e37e17c1d9c54d8ed61d39880abf by Chris Kennelly <ckennelly@google.com>: Document that absl::FunctionRef does not allocate. PiperOrigin-RevId: 413946831 -- 3308ae571412c4be3cc32d088c6edac98ff2d1ed by Samuel Benzaquen <sbenza@google.com>: Internal change PiperOrigin-RevId: 413933619 -- 1617093a730d055edcf7bc04fdd6509783f5f75d by Martijn Vels <mvels@google.com>: Internal Change PiperOrigin-RevId: 413778735 -- 03ad683f059c806a6c8b04f5b79b2662c3df8c73 by Evan Brown <ezb@google.com>: Unify btree erase_if definitions and optimize them so that we only do rebalancing once per leaf node. PiperOrigin-RevId: 413757280 -- 5ba402f70801938178e486617063f01c7862525d by Martijn Vels <mvels@google.com>: Cleanup up cord sampling internals PiperOrigin-RevId: 413755011 -- 522da8f9d3e0f11630d89fb41952004742bc335a by Evan Brown <ezb@google.com>: Add b-tree benchmark for erase_if. Since this benchmark doesn't work for std:: containers before C++20, disable it for them. PiperOrigin-RevId: 413740844 -- a690ea42de8ed4a761d00235d8b2fb7548ba9732 by Andy Getzendanner <durandal@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 413735737 GitOrigin-RevId: e7f53dfbf809812e84770217777f81b6308a3084 Change-Id: I4f9f9039ba92831bc48971964aa063244c9fed72
3 years ago
EXPECT_EQ(info.inline_element_size, expected_element_size);
++new_count;
}
});
// Make sure we actually did get a new hashtablez.
EXPECT_GT(new_count, 0);
}
struct bigstruct {
char a[1000];
friend bool operator==(const bigstruct& x, const bigstruct& y) {
return memcmp(x.a, y.a, sizeof(x.a)) == 0;
}
template <typename H>
friend H AbslHashValue(H h, const bigstruct& c) {
return H::combine_contiguous(std::move(h), c.a, sizeof(c.a));
}
};
#endif
TEST(FlatHashMap, SampleElementSize) {
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
// Enable sampling even if the prod default is off.
SetHashtablezEnabled(true);
SetHashtablezSampleParameter(1);
auto& sampler = GlobalHashtablezSampler();
std::vector<flat_hash_map<int, bigstruct>> flat_map_tables;
std::vector<flat_hash_set<bigstruct>> flat_set_tables;
std::vector<node_hash_map<int, bigstruct>> node_map_tables;
std::vector<node_hash_set<bigstruct>> node_set_tables;
// It takes thousands of new tables after changing the sampling parameters
// before you actually get some instrumentation. And if you must actually
// put something into those tables.
for (int i = 0; i < 10000; ++i) {
flat_map_tables.emplace_back();
flat_map_tables.back()[i] = bigstruct{};
}
// clang-tidy gives a false positive on this declaration. This unordered set
// cannot be a flat_hash_set, however, since that would introduce a mutex
// deadlock.
std::unordered_set<const HashtablezInfo*> preexisting_info; // NOLINT
sampler.Iterate(
[&](const HashtablezInfo& info) { preexisting_info.insert(&info); });
TestInlineElementSize(sampler, preexisting_info, flat_map_tables,
{0, bigstruct{}}, sizeof(int) + sizeof(bigstruct));
TestInlineElementSize(sampler, preexisting_info, node_map_tables,
{0, bigstruct{}}, sizeof(void*));
TestInlineElementSize(sampler, preexisting_info, flat_set_tables, //
bigstruct{}, sizeof(bigstruct));
TestInlineElementSize(sampler, preexisting_info, node_set_tables, //
bigstruct{}, sizeof(void*));
#endif
}
} // namespace
} // namespace container_internal
ABSL_NAMESPACE_END
} // namespace absl