tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

sample_element_size_test.cc (4675B)


      1 // Copyright 2018 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include <cstddef>
     16 #include <unordered_set>
     17 #include <utility>
     18 #include <vector>
     19 
     20 #include "gmock/gmock.h"
     21 #include "gtest/gtest.h"
     22 #include "absl/container/flat_hash_map.h"
     23 #include "absl/container/flat_hash_set.h"
     24 #include "absl/container/internal/hashtablez_sampler.h"
     25 #include "absl/container/node_hash_map.h"
     26 #include "absl/container/node_hash_set.h"
     27 
     28 namespace absl {
     29 ABSL_NAMESPACE_BEGIN
     30 namespace container_internal {
     31 namespace {
     32 
     33 #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
     34 // Create some tables of type `Table`, then look at all the new
     35 // `HashtablezInfo`s to make sure that the `inline_element_size ==
     36 // expected_element_size`.  The `inline_element_size` is the amount of memory
     37 // allocated for each slot of a hash table, that is `sizeof(slot_type)`.  Add
     38 // the new `HashtablezInfo`s to `preexisting_info`.  Store all the new tables
     39 // into `tables`.
     40 template <class Table>
     41 void TestInlineElementSize(
     42    HashtablezSampler& sampler,
     43    // clang-tidy gives a false positive on this declaration.  This unordered
     44    // set cannot be flat_hash_set, however, since that would introduce a mutex
     45    // deadlock.
     46    std::unordered_set<const HashtablezInfo*>& preexisting_info,  // NOLINT
     47    std::vector<Table>& tables,
     48    const std::vector<typename Table::value_type>& values,
     49    size_t expected_element_size) {
     50  EXPECT_GT(values.size(), 0);
     51  for (int i = 0; i < 10; ++i) {
     52    // We create a new table and must store it somewhere so that when we store
     53    // a pointer to the resulting `HashtablezInfo` into `preexisting_info`
     54    // that we aren't storing a dangling pointer.
     55    tables.emplace_back();
     56    // We must insert elements to get a hashtablez to instantiate.
     57    tables.back().insert(values.begin(), values.end());
     58  }
     59  size_t new_count = 0;
     60  sampler.Iterate([&](const HashtablezInfo& info) {
     61    if (preexisting_info.insert(&info).second) {
     62      EXPECT_EQ(info.inline_element_size, expected_element_size);
     63      ++new_count;
     64    }
     65  });
     66  // Make sure we actually did get a new hashtablez.
     67  EXPECT_GT(new_count, 0);
     68 }
     69 
     70 struct bigstruct {
     71  char a[1000];
     72  friend bool operator==(const bigstruct& x, const bigstruct& y) {
     73    return memcmp(x.a, y.a, sizeof(x.a)) == 0;
     74  }
     75  template <typename H>
     76  friend H AbslHashValue(H h, const bigstruct& c) {
     77    return H::combine_contiguous(std::move(h), c.a, sizeof(c.a));
     78  }
     79 };
     80 #endif
     81 
     82 TEST(FlatHashMap, SampleElementSize) {
     83 #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
     84  // Enable sampling even if the prod default is off.
     85  SetHashtablezEnabled(true);
     86  SetHashtablezSampleParameter(1);
     87  TestOnlyRefreshSamplingStateForCurrentThread();
     88 
     89  auto& sampler = GlobalHashtablezSampler();
     90  std::vector<flat_hash_map<int, bigstruct>> flat_map_tables;
     91  std::vector<flat_hash_set<bigstruct>> flat_set_tables;
     92  std::vector<node_hash_map<int, bigstruct>> node_map_tables;
     93  std::vector<node_hash_set<bigstruct>> node_set_tables;
     94  std::vector<bigstruct> set_values = {bigstruct{{0}}, bigstruct{{1}}};
     95  std::vector<std::pair<const int, bigstruct>> map_values = {{0, bigstruct{}},
     96                                                             {1, bigstruct{}}};
     97 
     98  // clang-tidy gives a false positive on this declaration.  This unordered set
     99  // cannot be a flat_hash_set, however, since that would introduce a mutex
    100  // deadlock.
    101  std::unordered_set<const HashtablezInfo*> preexisting_info;  // NOLINT
    102  sampler.Iterate(
    103      [&](const HashtablezInfo& info) { preexisting_info.insert(&info); });
    104  TestInlineElementSize(sampler, preexisting_info, flat_map_tables, map_values,
    105                        sizeof(int) + sizeof(bigstruct));
    106  TestInlineElementSize(sampler, preexisting_info, node_map_tables, map_values,
    107                        sizeof(void*));
    108  TestInlineElementSize(sampler, preexisting_info, flat_set_tables, set_values,
    109                        sizeof(bigstruct));
    110  TestInlineElementSize(sampler, preexisting_info, node_set_tables, set_values,
    111                        sizeof(void*));
    112 #endif
    113 }
    114 
    115 }  // namespace
    116 }  // namespace container_internal
    117 ABSL_NAMESPACE_END
    118 }  // namespace absl