Commit 299f59ca by Abseil Team Committed by dinord

Export of internal Abseil changes

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

Tweaking the documentation of c_all_of to state the effect more directly.

PiperOrigin-RevId: 410557900

--
4732289bf4b56123fed113e36be4710b55c6a6c7 by Greg Falcon <gfalcon@google.com>:

Improve the quality of absl::Hash<std::vector<bool>>.

This previously dispatched to std::hash<vector<bool>>, which suffers from trivial collisions on many platforms.  (They often hash the internal words but no size info, so that, e.g., {1, 1} and {1, 1, 0} collide.)

Also extended the unit test to exercise this.

PiperOrigin-RevId: 410329943

--
1c5f3934230a7669f74c96b305251786a265e235 by Greg Falcon <gfalcon@google.com>:

Add broader testing of absl hash contracts in the hash unit test.

In particular, test that the hash erasure mechanism works.

PiperOrigin-RevId: 410312738

--
5e1923f527ed3d02f6752a5b38d5e1c17a4a146f by Derek Mauro <dmauro@google.com>:

Internal change

PiperOrigin-RevId: 410290663

--
8c74bc962b3b98a5908017c345efc592393048ea by Martijn Vels <mvels@google.com>:

Add Cord::CreateFlat() function

PiperOrigin-RevId: 410260776

--
bd0de4e94c85620d3b8dd60fae367b730fc4cb34 by Evan Brown <ezb@google.com>:

Rename node_hash_policy to node_slot_policy.

Motivation: we can potentially reuse this code for node_btree_*.
PiperOrigin-RevId: 410082271
GitOrigin-RevId: 2130ba98c8359b08d97fb16d84dfd05687005dcf
Change-Id: Ie052084cf992dee250d8b2f388d39c4de0dcff40
parent 9b924ced
...@@ -81,7 +81,7 @@ set(ABSL_INTERNAL_DLL_FILES ...@@ -81,7 +81,7 @@ set(ABSL_INTERNAL_DLL_FILES
"container/internal/have_sse.h" "container/internal/have_sse.h"
"container/internal/inlined_vector.h" "container/internal/inlined_vector.h"
"container/internal/layout.h" "container/internal/layout.h"
"container/internal/node_hash_policy.h" "container/internal/node_slot_policy.h"
"container/internal/raw_hash_map.h" "container/internal/raw_hash_map.h"
"container/internal/raw_hash_set.cc" "container/internal/raw_hash_set.cc"
"container/internal/raw_hash_set.h" "container/internal/raw_hash_set.h"
...@@ -455,7 +455,7 @@ set(ABSL_INTERNAL_DLL_TARGETS ...@@ -455,7 +455,7 @@ set(ABSL_INTERNAL_DLL_TARGETS
"hashtable_debug" "hashtable_debug"
"hashtable_debug_hooks" "hashtable_debug_hooks"
"have_sse" "have_sse"
"node_hash_policy" "node_slot_policy"
"raw_hash_map" "raw_hash_map"
"container_common" "container_common"
"raw_hash_set" "raw_hash_set"
......
...@@ -166,7 +166,7 @@ container_algorithm_internal::ContainerDifferenceType<const C> c_distance( ...@@ -166,7 +166,7 @@ container_algorithm_internal::ContainerDifferenceType<const C> c_distance(
// c_all_of() // c_all_of()
// //
// Container-based version of the <algorithm> `std::all_of()` function to // Container-based version of the <algorithm> `std::all_of()` function to
// test a condition on all elements within a container. // test if all elements within a container satisfy a condition.
template <typename C, typename Pred> template <typename C, typename Pred>
bool c_all_of(const C& c, Pred&& pred) { bool c_all_of(const C& c, Pred&& pred) {
return std::all_of(container_algorithm_internal::c_begin(c), return std::all_of(container_algorithm_internal::c_begin(c),
......
...@@ -307,7 +307,7 @@ cc_library( ...@@ -307,7 +307,7 @@ cc_library(
deps = [ deps = [
":container_memory", ":container_memory",
":hash_function_defaults", ":hash_function_defaults",
":node_hash_policy", ":node_slot_policy",
":raw_hash_map", ":raw_hash_map",
"//absl/algorithm:container", "//absl/algorithm:container",
"//absl/memory", "//absl/memory",
...@@ -339,7 +339,7 @@ cc_library( ...@@ -339,7 +339,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [ deps = [
":hash_function_defaults", ":hash_function_defaults",
":node_hash_policy", ":node_slot_policy",
":raw_hash_set", ":raw_hash_set",
"//absl/algorithm:container", "//absl/algorithm:container",
"//absl/memory", "//absl/memory",
...@@ -535,21 +535,21 @@ cc_test( ...@@ -535,21 +535,21 @@ cc_test(
) )
cc_library( cc_library(
name = "node_hash_policy", name = "node_slot_policy",
hdrs = ["internal/node_hash_policy.h"], hdrs = ["internal/node_slot_policy.h"],
copts = ABSL_DEFAULT_COPTS, copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = ["//absl/base:config"], deps = ["//absl/base:config"],
) )
cc_test( cc_test(
name = "node_hash_policy_test", name = "node_slot_policy_test",
srcs = ["internal/node_hash_policy_test.cc"], srcs = ["internal/node_slot_policy_test.cc"],
copts = ABSL_TEST_COPTS, copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [ deps = [
":hash_policy_traits", ":hash_policy_traits",
":node_hash_policy", ":node_slot_policy",
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
], ],
) )
......
...@@ -348,7 +348,7 @@ absl_cc_library( ...@@ -348,7 +348,7 @@ absl_cc_library(
DEPS DEPS
absl::container_memory absl::container_memory
absl::hash_function_defaults absl::hash_function_defaults
absl::node_hash_policy absl::node_slot_policy
absl::raw_hash_map absl::raw_hash_map
absl::algorithm_container absl::algorithm_container
absl::memory absl::memory
...@@ -382,7 +382,7 @@ absl_cc_library( ...@@ -382,7 +382,7 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS} ${ABSL_DEFAULT_COPTS}
DEPS DEPS
absl::hash_function_defaults absl::hash_function_defaults
absl::node_hash_policy absl::node_slot_policy
absl::raw_hash_set absl::raw_hash_set
absl::algorithm_container absl::algorithm_container
absl::memory absl::memory
...@@ -599,9 +599,9 @@ absl_cc_library( ...@@ -599,9 +599,9 @@ absl_cc_library(
absl_cc_library( absl_cc_library(
NAME NAME
node_hash_policy node_slot_policy
HDRS HDRS
"internal/node_hash_policy.h" "internal/node_slot_policy.h"
COPTS COPTS
${ABSL_DEFAULT_COPTS} ${ABSL_DEFAULT_COPTS}
DEPS DEPS
...@@ -611,14 +611,14 @@ absl_cc_library( ...@@ -611,14 +611,14 @@ absl_cc_library(
absl_cc_test( absl_cc_test(
NAME NAME
node_hash_policy_test node_slot_policy_test
SRCS SRCS
"internal/node_hash_policy_test.cc" "internal/node_slot_policy_test.cc"
COPTS COPTS
${ABSL_TEST_COPTS} ${ABSL_TEST_COPTS}
DEPS DEPS
absl::hash_policy_traits absl::hash_policy_traits
absl::node_hash_policy absl::node_slot_policy
GTest::gmock_main GTest::gmock_main
) )
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
// It may also optionally define `value()` and `apply()`. For documentation on // It may also optionally define `value()` and `apply()`. For documentation on
// these, see hash_policy_traits.h. // these, see hash_policy_traits.h.
#ifndef ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ #ifndef ABSL_CONTAINER_INTERNAL_NODE_SLOT_POLICY_H_
#define ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ #define ABSL_CONTAINER_INTERNAL_NODE_SLOT_POLICY_H_
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
...@@ -46,7 +46,7 @@ ABSL_NAMESPACE_BEGIN ...@@ -46,7 +46,7 @@ ABSL_NAMESPACE_BEGIN
namespace container_internal { namespace container_internal {
template <class Reference, class Policy> template <class Reference, class Policy>
struct node_hash_policy { struct node_slot_policy {
static_assert(std::is_lvalue_reference<Reference>::value, ""); static_assert(std::is_lvalue_reference<Reference>::value, "");
using slot_type = typename std::remove_cv< using slot_type = typename std::remove_cv<
...@@ -89,4 +89,4 @@ struct node_hash_policy { ...@@ -89,4 +89,4 @@ struct node_hash_policy {
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
} // namespace absl } // namespace absl
#endif // ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ #endif // ABSL_CONTAINER_INTERNAL_NODE_SLOT_POLICY_H_
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "absl/container/internal/node_hash_policy.h" #include "absl/container/internal/node_slot_policy.h"
#include <memory> #include <memory>
...@@ -27,7 +27,7 @@ namespace { ...@@ -27,7 +27,7 @@ namespace {
using ::testing::Pointee; using ::testing::Pointee;
struct Policy : node_hash_policy<int&, Policy> { struct Policy : node_slot_policy<int&, Policy> {
using key_type = int; using key_type = int;
using init_type = int; using init_type = int;
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include "absl/container/internal/container_memory.h" #include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export
#include "absl/container/internal/node_hash_policy.h" #include "absl/container/internal/node_slot_policy.h"
#include "absl/container/internal/raw_hash_map.h" // IWYU pragma: export #include "absl/container/internal/raw_hash_map.h" // IWYU pragma: export
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
...@@ -535,7 +535,7 @@ namespace container_internal { ...@@ -535,7 +535,7 @@ namespace container_internal {
template <class Key, class Value> template <class Key, class Value>
class NodeHashMapPolicy class NodeHashMapPolicy
: public absl::container_internal::node_hash_policy< : public absl::container_internal::node_slot_policy<
std::pair<const Key, Value>&, NodeHashMapPolicy<Key, Value>> { std::pair<const Key, Value>&, NodeHashMapPolicy<Key, Value>> {
using value_type = std::pair<const Key, Value>; using value_type = std::pair<const Key, Value>;
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export
#include "absl/container/internal/node_hash_policy.h" #include "absl/container/internal/node_slot_policy.h"
#include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export #include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
...@@ -442,7 +442,7 @@ namespace container_internal { ...@@ -442,7 +442,7 @@ namespace container_internal {
template <class T> template <class T>
struct NodeHashSetPolicy struct NodeHashSetPolicy
: absl::container_internal::node_hash_policy<T&, NodeHashSetPolicy<T>> { : absl::container_internal::node_slot_policy<T&, NodeHashSetPolicy<T>> {
using key_type = T; using key_type = T;
using init_type = T; using init_type = T;
using constant_iterators = std::true_type; using constant_iterators = std::true_type;
......
...@@ -502,10 +502,9 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) { ...@@ -502,10 +502,9 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
vector.size()); vector.size());
} }
// AbslHashValue special cases for hashing std::vector<bool>
#if defined(ABSL_IS_BIG_ENDIAN) && \ #if defined(ABSL_IS_BIG_ENDIAN) && \
(defined(__GLIBCXX__) || defined(__GLIBCPP__)) (defined(__GLIBCXX__) || defined(__GLIBCPP__))
// AbslHashValue for hashing std::vector<bool>
//
// std::hash in libstdc++ does not work correctly with vector<bool> on Big // std::hash in libstdc++ does not work correctly with vector<bool> on Big
// Endian platforms therefore we need to implement a custom AbslHashValue for // Endian platforms therefore we need to implement a custom AbslHashValue for
// it. More details on the bug: // it. More details on the bug:
...@@ -521,6 +520,22 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) { ...@@ -521,6 +520,22 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
} }
return H::combine(combiner.finalize(std::move(hash_state)), vector.size()); return H::combine(combiner.finalize(std::move(hash_state)), vector.size());
} }
#else
// When not working around the libstdc++ bug above, we still have to contend
// with the fact that std::hash<vector<bool>> is often poor quality, hashing
// directly on the internal words and on no other state. On these platforms,
// vector<bool>{1, 1} and vector<bool>{1, 1, 0} hash to the same value.
//
// Mixing in the size (as we do in our other vector<> implementations) on top
// of the library-provided hash implementation avoids this QOI issue.
template <typename H, typename T, typename Allocator>
typename std::enable_if<is_hashable<T>::value && std::is_same<T, bool>::value,
H>::type
AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
return H::combine(std::move(hash_state),
std::hash<std::vector<T, Allocator>>{}(vector),
vector.size());
}
#endif #endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -855,6 +855,11 @@ class Cord { ...@@ -855,6 +855,11 @@ class Cord {
// Returns true if the Cord is being profiled by cordz. // Returns true if the Cord is being profiled by cordz.
bool is_profiled() const { return data_.is_tree() && data_.is_profiled(); } bool is_profiled() const { return data_.is_tree() && data_.is_profiled(); }
// Returns the available inlined capacity, or 0 if is_tree() == true.
size_t inline_capacity() const {
return data_.is_tree() ? 0 : kMaxInline - data_.inline_size();
}
// Returns the profiled CordzInfo, or nullptr if not sampled. // Returns the profiled CordzInfo, or nullptr if not sampled.
absl::cord_internal::CordzInfo* cordz_info() const { absl::cord_internal::CordzInfo* cordz_info() const {
return data_.cordz_info(); return data_.cordz_info();
......
...@@ -117,6 +117,17 @@ struct CordRepFlat : public CordRep { ...@@ -117,6 +117,17 @@ struct CordRepFlat : public CordRep {
#endif #endif
} }
// Create a CordRepFlat containing `data`, with an optional additional
// extra capacity of up to `extra` bytes. Requires that `data.size()`
// is less than kMaxFlatLength.
static CordRepFlat* Create(absl::string_view data, size_t extra = 0) {
assert(data.size() <= kMaxFlatLength);
CordRepFlat* flat = New(data.size() + (std::min)(extra, kMaxFlatLength));
memcpy(flat->Data(), data.data(), data.size());
flat->length = data.size();
return flat;
}
// Returns a pointer to the data inside this flat rep. // Returns a pointer to the data inside this flat rep.
char* Data() { return reinterpret_cast<char*>(storage); } char* Data() { return reinterpret_cast<char*>(storage); }
const char* Data() const { return reinterpret_cast<const char*>(storage); } const char* Data() const { return reinterpret_cast<const char*>(storage); }
......
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