Commit 0e9921b7 by Abseil Team Committed by Mark Barolak

Export of internal Abseil changes

--
23500704dd7c2642fad49f88c07ce41ebaab12e4 by Abseil Team <absl-team@google.com>:

Change fetch_add() to store(1 + load())

As there is only one concurrent writer to the Info struct, we can avoid using
the more expensive fetch_add() function.

PiperOrigin-RevId: 329523785

--
79e5018dba2e117ad89b76367165a604b3f24045 by Abseil Team <absl-team@google.com>:

Record rehash count in hashtablez

This will help identify which containers could benefit from a reserve call.

PiperOrigin-RevId: 329510552

--
e327e54b805d67556f934fa7f7dc2d4e72fa066a by Abseil Team <absl-team@google.com>:

Fix -Wsign-compare issues.

These lines could theoretically have overflowed in cases of very large stack
traces etc. Very unlikely, but this was causing warnings when built with
-Wsign-compare, which we intend to enable with Chromium.

In none of these three cases is it trivial to switch to a range-based for loop.

PiperOrigin-RevId: 329415195

--
08aca2fc75e8b3ad1201849987b64148fe48f283 by Xiaoyi Zhang <zhangxy@google.com>:

Release absl::StatusOr.

PiperOrigin-RevId: 329353348

--
bf4d2a7f8b089e2adf14d32b0e39de0a981005c3 by Xiaoyi Zhang <zhangxy@google.com>:

Internal change

PiperOrigin-RevId: 329337031

--
42fa7d2fb993bbfc344954227cf1eeb801eca065 by Abseil Team <absl-team@google.com>:

Internal change

PiperOrigin-RevId: 329099807
GitOrigin-RevId: 23500704dd7c2642fad49f88c07ce41ebaab12e4
Change-Id: I6713e4ca3bb0ab2ced5e487827ae036ab8ac61f1
parent a4cbb5f6
...@@ -175,8 +175,11 @@ set(ABSL_INTERNAL_DLL_FILES ...@@ -175,8 +175,11 @@ set(ABSL_INTERNAL_DLL_FILES
"random/uniform_real_distribution.h" "random/uniform_real_distribution.h"
"random/zipf_distribution.h" "random/zipf_distribution.h"
"status/internal/status_internal.h" "status/internal/status_internal.h"
"status/internal/statusor_internal.h"
"status/status.h" "status/status.h"
"status/status.cc" "status/status.cc"
"status/statusor.h"
"status/statusor.cc"
"status/status_payload_printer.h" "status/status_payload_printer.h"
"status/status_payload_printer.cc" "status/status_payload_printer.cc"
"strings/ascii.cc" "strings/ascii.cc"
......
...@@ -67,6 +67,7 @@ void HashtablezInfo::PrepareForSampling() { ...@@ -67,6 +67,7 @@ void HashtablezInfo::PrepareForSampling() {
capacity.store(0, std::memory_order_relaxed); capacity.store(0, std::memory_order_relaxed);
size.store(0, std::memory_order_relaxed); size.store(0, std::memory_order_relaxed);
num_erases.store(0, std::memory_order_relaxed); num_erases.store(0, std::memory_order_relaxed);
num_rehashes.store(0, std::memory_order_relaxed);
max_probe_length.store(0, std::memory_order_relaxed); max_probe_length.store(0, std::memory_order_relaxed);
total_probe_length.store(0, std::memory_order_relaxed); total_probe_length.store(0, std::memory_order_relaxed);
hashes_bitwise_or.store(0, std::memory_order_relaxed); hashes_bitwise_or.store(0, std::memory_order_relaxed);
......
...@@ -73,6 +73,7 @@ struct HashtablezInfo { ...@@ -73,6 +73,7 @@ struct HashtablezInfo {
std::atomic<size_t> capacity; std::atomic<size_t> capacity;
std::atomic<size_t> size; std::atomic<size_t> size;
std::atomic<size_t> num_erases; std::atomic<size_t> num_erases;
std::atomic<size_t> num_rehashes;
std::atomic<size_t> max_probe_length; std::atomic<size_t> max_probe_length;
std::atomic<size_t> total_probe_length; std::atomic<size_t> total_probe_length;
std::atomic<size_t> hashes_bitwise_or; std::atomic<size_t> hashes_bitwise_or;
...@@ -105,6 +106,11 @@ inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) { ...@@ -105,6 +106,11 @@ inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) {
#endif #endif
info->total_probe_length.store(total_probe_length, std::memory_order_relaxed); info->total_probe_length.store(total_probe_length, std::memory_order_relaxed);
info->num_erases.store(0, std::memory_order_relaxed); info->num_erases.store(0, std::memory_order_relaxed);
// There is only one concurrent writer, so `load` then `store` is sufficient
// instead of using `fetch_add`.
info->num_rehashes.store(
1 + info->num_rehashes.load(std::memory_order_relaxed),
std::memory_order_relaxed);
} }
inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size, inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size,
...@@ -113,7 +119,8 @@ inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size, ...@@ -113,7 +119,8 @@ inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size,
info->capacity.store(capacity, std::memory_order_relaxed); info->capacity.store(capacity, std::memory_order_relaxed);
if (size == 0) { if (size == 0) {
// This is a clear, reset the total/num_erases too. // This is a clear, reset the total/num_erases too.
RecordRehashSlow(info, 0); info->total_probe_length.store(0, std::memory_order_relaxed);
info->num_erases.store(0, std::memory_order_relaxed);
} }
} }
...@@ -122,7 +129,11 @@ void RecordInsertSlow(HashtablezInfo* info, size_t hash, ...@@ -122,7 +129,11 @@ void RecordInsertSlow(HashtablezInfo* info, size_t hash,
inline void RecordEraseSlow(HashtablezInfo* info) { inline void RecordEraseSlow(HashtablezInfo* info) {
info->size.fetch_sub(1, std::memory_order_relaxed); info->size.fetch_sub(1, std::memory_order_relaxed);
info->num_erases.fetch_add(1, std::memory_order_relaxed); // There is only one concurrent writer, so `load` then `store` is sufficient
// instead of using `fetch_add`.
info->num_erases.store(
1 + info->num_erases.load(std::memory_order_relaxed),
std::memory_order_relaxed);
} }
HashtablezInfo* SampleSlow(int64_t* next_sample); HashtablezInfo* SampleSlow(int64_t* next_sample);
......
...@@ -76,6 +76,7 @@ TEST(HashtablezInfoTest, PrepareForSampling) { ...@@ -76,6 +76,7 @@ TEST(HashtablezInfoTest, PrepareForSampling) {
EXPECT_EQ(info.capacity.load(), 0); EXPECT_EQ(info.capacity.load(), 0);
EXPECT_EQ(info.size.load(), 0); EXPECT_EQ(info.size.load(), 0);
EXPECT_EQ(info.num_erases.load(), 0); EXPECT_EQ(info.num_erases.load(), 0);
EXPECT_EQ(info.num_rehashes.load(), 0);
EXPECT_EQ(info.max_probe_length.load(), 0); EXPECT_EQ(info.max_probe_length.load(), 0);
EXPECT_EQ(info.total_probe_length.load(), 0); EXPECT_EQ(info.total_probe_length.load(), 0);
EXPECT_EQ(info.hashes_bitwise_or.load(), 0); EXPECT_EQ(info.hashes_bitwise_or.load(), 0);
...@@ -95,6 +96,7 @@ TEST(HashtablezInfoTest, PrepareForSampling) { ...@@ -95,6 +96,7 @@ TEST(HashtablezInfoTest, PrepareForSampling) {
EXPECT_EQ(info.capacity.load(), 0); EXPECT_EQ(info.capacity.load(), 0);
EXPECT_EQ(info.size.load(), 0); EXPECT_EQ(info.size.load(), 0);
EXPECT_EQ(info.num_erases.load(), 0); EXPECT_EQ(info.num_erases.load(), 0);
EXPECT_EQ(info.num_rehashes.load(), 0);
EXPECT_EQ(info.max_probe_length.load(), 0); EXPECT_EQ(info.max_probe_length.load(), 0);
EXPECT_EQ(info.total_probe_length.load(), 0); EXPECT_EQ(info.total_probe_length.load(), 0);
EXPECT_EQ(info.hashes_bitwise_or.load(), 0); EXPECT_EQ(info.hashes_bitwise_or.load(), 0);
...@@ -167,6 +169,7 @@ TEST(HashtablezInfoTest, RecordRehash) { ...@@ -167,6 +169,7 @@ TEST(HashtablezInfoTest, RecordRehash) {
EXPECT_EQ(info.size.load(), 2); EXPECT_EQ(info.size.load(), 2);
EXPECT_EQ(info.total_probe_length.load(), 3); EXPECT_EQ(info.total_probe_length.load(), 3);
EXPECT_EQ(info.num_erases.load(), 0); EXPECT_EQ(info.num_erases.load(), 0);
EXPECT_EQ(info.num_rehashes.load(), 1);
} }
#if defined(ABSL_HASHTABLEZ_SAMPLE) #if defined(ABSL_HASHTABLEZ_SAMPLE)
......
...@@ -65,3 +65,39 @@ cc_test( ...@@ -65,3 +65,39 @@ cc_test(
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
], ],
) )
cc_library(
name = "statusor",
srcs = [
"internal/statusor_internal.h",
"statusor.cc",
],
hdrs = [
"statusor.h",
],
copts = ABSL_DEFAULT_COPTS,
deps = [
":status",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"//absl/meta:type_traits",
"//absl/strings",
"//absl/types:variant",
"//absl/utility",
],
)
cc_test(
name = "statusor_test",
size = "small",
srcs = ["statusor_test.cc"],
deps = [
":status",
":statusor",
"//absl/base",
"//absl/memory",
"//absl/types:any",
"//absl/utility",
"@com_google_googletest//:gtest_main",
],
)
...@@ -52,3 +52,36 @@ absl_cc_test( ...@@ -52,3 +52,36 @@ absl_cc_test(
absl::strings absl::strings
gmock_main gmock_main
) )
absl_cc_library(
NAME
statusor
HDRS
"statusor.h"
SRCS
"statusor.cc"
"internal/statusor_internal.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::core_headers
absl::raw_logging_internal
absl::type_traits
absl::strings
absl::utility
absl::variant
PUBLIC
)
absl_cc_test(
NAME
statusor_test
SRCS
"statusor_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::status
absl::statusor
gmock_main
)
...@@ -78,7 +78,7 @@ static int FindPayloadIndexByUrl(const Payloads* payloads, ...@@ -78,7 +78,7 @@ static int FindPayloadIndexByUrl(const Payloads* payloads,
absl::string_view type_url) { absl::string_view type_url) {
if (payloads == nullptr) return -1; if (payloads == nullptr) return -1;
for (int i = 0; i < payloads->size(); ++i) { for (size_t i = 0; i < payloads->size(); ++i) {
if ((*payloads)[i].type_url == type_url) return i; if ((*payloads)[i].type_url == type_url) return i;
} }
...@@ -167,7 +167,7 @@ void Status::ForEachPayload( ...@@ -167,7 +167,7 @@ void Status::ForEachPayload(
bool in_reverse = bool in_reverse =
payloads->size() > 1 && reinterpret_cast<uintptr_t>(payloads) % 13 > 6; payloads->size() > 1 && reinterpret_cast<uintptr_t>(payloads) % 13 > 6;
for (int index = 0; index < payloads->size(); ++index) { for (size_t index = 0; index < payloads->size(); ++index) {
const auto& elem = const auto& elem =
(*payloads)[in_reverse ? payloads->size() - 1 - index : index]; (*payloads)[in_reverse ? payloads->size() - 1 - index : index];
......
// Copyright 2020 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 "absl/status/statusor.h"
#include <cstdlib>
#include <utility>
#include "absl/base/internal/raw_logging.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
BadStatusOrAccess::BadStatusOrAccess(absl::Status status)
: status_(std::move(status)) {}
BadStatusOrAccess::~BadStatusOrAccess() = default;
const char* BadStatusOrAccess::what() const noexcept {
return "Bad StatusOr access";
}
const absl::Status& BadStatusOrAccess::status() const { return status_; }
namespace internal_statusor {
void Helper::HandleInvalidStatusCtorArg(absl::Status* status) {
const char* kMessage =
"An OK status is not a valid constructor argument to StatusOr<T>";
#ifdef NDEBUG
ABSL_INTERNAL_LOG(ERROR, kMessage);
#else
ABSL_INTERNAL_LOG(FATAL, kMessage);
#endif
// In optimized builds, we will fall back to InternalError.
*status = absl::InternalError(kMessage);
}
void Helper::Crash(const absl::Status& status) {
ABSL_INTERNAL_LOG(
FATAL,
absl::StrCat("Attempting to fetch value instead of handling error ",
status.ToString()));
}
void ThrowBadStatusOrAccess(absl::Status status) {
#ifdef ABSL_HAVE_EXCEPTIONS
throw absl::BadStatusOrAccess(std::move(status));
#else
ABSL_INTERNAL_LOG(
FATAL,
absl::StrCat("Attempting to fetch value instead of handling error ",
status.ToString()));
std::abort();
#endif
}
} // namespace internal_statusor
ABSL_NAMESPACE_END
} // namespace absl
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