diff options
author | heretic <heretic@yandex-team.ru> | 2022-02-10 16:45:43 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:43 +0300 |
commit | 397cbe258b9e064f49c4ca575279f02f39fef76e (patch) | |
tree | a0b0eb3cca6a14e4e8ea715393637672fa651284 /contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal | |
parent | 43f5a35593ebc9f6bcea619bb170394ea7ae468e (diff) | |
download | ydb-397cbe258b9e064f49c4ca575279f02f39fef76e.tar.gz |
Restoring authorship annotation for <heretic@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal')
8 files changed, 359 insertions, 359 deletions
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/.yandex_meta/licenses.list.txt b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/.yandex_meta/licenses.list.txt index bbc98ff778..757688c969 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/.yandex_meta/licenses.list.txt +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/.yandex_meta/licenses.list.txt @@ -1,34 +1,34 @@ -====================Apache-2.0==================== -// 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. - - -====================Apache-2.0==================== -// 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. - - -====================COPYRIGHT==================== -// Copyright 2018 The Abseil Authors. - - -====================COPYRIGHT==================== -// Copyright 2020 The Abseil Authors. +====================Apache-2.0==================== +// 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. + + +====================Apache-2.0==================== +// 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. + + +====================COPYRIGHT==================== +// Copyright 2018 The Abseil Authors. + + +====================COPYRIGHT==================== +// Copyright 2020 The Abseil Authors. diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/city.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/city.cc index 5f1b655e7e..27d253ebd8 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/city.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/city.cc @@ -210,11 +210,11 @@ static uint64_t HashLen16(uint64_t u, uint64_t v, uint64_t mul) { return b; } -static uint64_t HashLen16(uint64_t u, uint64_t v) { - const uint64_t kMul = 0x9ddfea08eb382d69ULL; - return HashLen16(u, v, kMul); -} - +static uint64_t HashLen16(uint64_t u, uint64_t v) { + const uint64_t kMul = 0x9ddfea08eb382d69ULL; + return HashLen16(u, v, kMul); +} + static uint64_t HashLen0to16(const char *s, size_t len) { if (len >= 8) { uint64_t mul = k2 + len * 2; @@ -254,8 +254,8 @@ static uint64_t HashLen17to32(const char *s, size_t len) { // Return a 16-byte hash for 48 bytes. Quick and dirty. // Callers do best to use "random-looking" values for a and b. -static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds( - uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) { +static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds( + uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) { a += w; b = Rotate(b + a + z, 21); uint64_t c = a; @@ -266,9 +266,9 @@ static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds( } // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. -static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(const char *s, - uint64_t a, - uint64_t b) { +static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(const char *s, + uint64_t a, + uint64_t b) { return WeakHashLen32WithSeeds(Fetch64(s), Fetch64(s + 8), Fetch64(s + 16), Fetch64(s + 24), a, b); } @@ -311,10 +311,10 @@ uint64_t CityHash64(const char *s, size_t len) { uint64_t x = Fetch64(s + len - 40); uint64_t y = Fetch64(s + len - 16) + Fetch64(s + len - 56); uint64_t z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24)); - std::pair<uint64_t, uint64_t> v = - WeakHashLen32WithSeeds(s + len - 64, len, z); - std::pair<uint64_t, uint64_t> w = - WeakHashLen32WithSeeds(s + len - 32, y + k1, x); + std::pair<uint64_t, uint64_t> v = + WeakHashLen32WithSeeds(s + len - 64, len, z); + std::pair<uint64_t, uint64_t> w = + WeakHashLen32WithSeeds(s + len - 32, y + k1, x); x = x * k1 + Fetch64(s); // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. @@ -340,7 +340,7 @@ uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed) { } uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0, - uint64_t seed1) { + uint64_t seed1) { return HashLen16(CityHash64(s, len) - seed0, seed1); } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/city.h b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/city.h index d2b32f0068..4efdc6ead1 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/city.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/city.h @@ -66,7 +66,7 @@ uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed); // Hash function for a byte array. For convenience, two seeds are also // hashed into the result. uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0, - uint64_t seed1); + uint64_t seed1); // Hash function for a byte array. Most useful in 32-bit binaries. uint32_t CityHash32(const char *s, size_t len); diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.cc index fe075de43a..68123f84cb 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.cc @@ -35,7 +35,7 @@ uint64_t MixingHashState::CombineLargeContiguousImpl32( uint64_t MixingHashState::CombineLargeContiguousImpl64( uint64_t state, const unsigned char* first, size_t len) { while (len >= PiecewiseChunkSize()) { - state = Mix(state, Hash64(first, PiecewiseChunkSize())); + state = Mix(state, Hash64(first, PiecewiseChunkSize())); len -= PiecewiseChunkSize(); first += PiecewiseChunkSize(); } @@ -49,21 +49,21 @@ ABSL_CONST_INIT const void* const MixingHashState::kSeed = &kSeed; // The salt array used by LowLevelHash. This array is NOT the mechanism used to // make y_absl::Hash non-deterministic between program invocations. See `Seed()` // for that mechanism. -// -// Any random values are fine. These values are just digits from the decimal -// part of pi. -// https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number +// +// Any random values are fine. These values are just digits from the decimal +// part of pi. +// https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number constexpr uint64_t kHashSalt[5] = { - uint64_t{0x243F6A8885A308D3}, uint64_t{0x13198A2E03707344}, - uint64_t{0xA4093822299F31D0}, uint64_t{0x082EFA98EC4E6C89}, - uint64_t{0x452821E638D01377}, -}; - + uint64_t{0x243F6A8885A308D3}, uint64_t{0x13198A2E03707344}, + uint64_t{0xA4093822299F31D0}, uint64_t{0x082EFA98EC4E6C89}, + uint64_t{0x452821E638D01377}, +}; + uint64_t MixingHashState::LowLevelHashImpl(const unsigned char* data, size_t len) { return LowLevelHash(data, len, Seed(), kHashSalt); -} - +} + } // namespace hash_internal ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.h b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.h index fcbe43accd..37cf79a7b4 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.h @@ -39,8 +39,8 @@ #include <utility> #include <vector> -#include "y_absl/base/config.h" -#include "y_absl/base/internal/unaligned_access.h" +#include "y_absl/base/config.h" +#include "y_absl/base/internal/unaligned_access.h" #include "y_absl/base/port.h" #include "y_absl/container/fixed_array.h" #include "y_absl/hash/internal/city.h" @@ -60,61 +60,61 @@ namespace hash_internal { // returns the size of these chunks. constexpr size_t PiecewiseChunkSize() { return 1024; } -// PiecewiseCombiner -// -// PiecewiseCombiner is an internal-only helper class for hashing a piecewise -// buffer of `char` or `unsigned char` as though it were contiguous. This class -// provides two methods: -// -// H add_buffer(state, data, size) -// H finalize(state) -// -// `add_buffer` can be called zero or more times, followed by a single call to -// `finalize`. This will produce the same hash expansion as concatenating each -// buffer piece into a single contiguous buffer, and passing this to -// `H::combine_contiguous`. -// -// Example usage: -// PiecewiseCombiner combiner; -// for (const auto& piece : pieces) { -// state = combiner.add_buffer(std::move(state), piece.data, piece.size); -// } -// return combiner.finalize(std::move(state)); -class PiecewiseCombiner { - public: - PiecewiseCombiner() : position_(0) {} - PiecewiseCombiner(const PiecewiseCombiner&) = delete; - PiecewiseCombiner& operator=(const PiecewiseCombiner&) = delete; - - // PiecewiseCombiner::add_buffer() - // - // Appends the given range of bytes to the sequence to be hashed, which may - // modify the provided hash state. - template <typename H> - H add_buffer(H state, const unsigned char* data, size_t size); - template <typename H> - H add_buffer(H state, const char* data, size_t size) { - return add_buffer(std::move(state), - reinterpret_cast<const unsigned char*>(data), size); - } - - // PiecewiseCombiner::finalize() - // - // Finishes combining the hash sequence, which may may modify the provided - // hash state. - // - // Once finalize() is called, add_buffer() may no longer be called. The - // resulting hash state will be the same as if the pieces passed to - // add_buffer() were concatenated into a single flat buffer, and then provided - // to H::combine_contiguous(). - template <typename H> - H finalize(H state); - - private: - unsigned char buf_[PiecewiseChunkSize()]; - size_t position_; -}; - +// PiecewiseCombiner +// +// PiecewiseCombiner is an internal-only helper class for hashing a piecewise +// buffer of `char` or `unsigned char` as though it were contiguous. This class +// provides two methods: +// +// H add_buffer(state, data, size) +// H finalize(state) +// +// `add_buffer` can be called zero or more times, followed by a single call to +// `finalize`. This will produce the same hash expansion as concatenating each +// buffer piece into a single contiguous buffer, and passing this to +// `H::combine_contiguous`. +// +// Example usage: +// PiecewiseCombiner combiner; +// for (const auto& piece : pieces) { +// state = combiner.add_buffer(std::move(state), piece.data, piece.size); +// } +// return combiner.finalize(std::move(state)); +class PiecewiseCombiner { + public: + PiecewiseCombiner() : position_(0) {} + PiecewiseCombiner(const PiecewiseCombiner&) = delete; + PiecewiseCombiner& operator=(const PiecewiseCombiner&) = delete; + + // PiecewiseCombiner::add_buffer() + // + // Appends the given range of bytes to the sequence to be hashed, which may + // modify the provided hash state. + template <typename H> + H add_buffer(H state, const unsigned char* data, size_t size); + template <typename H> + H add_buffer(H state, const char* data, size_t size) { + return add_buffer(std::move(state), + reinterpret_cast<const unsigned char*>(data), size); + } + + // PiecewiseCombiner::finalize() + // + // Finishes combining the hash sequence, which may may modify the provided + // hash state. + // + // Once finalize() is called, add_buffer() may no longer be called. The + // resulting hash state will be the same as if the pieces passed to + // add_buffer() were concatenated into a single flat buffer, and then provided + // to H::combine_contiguous(). + template <typename H> + H finalize(H state); + + private: + unsigned char buf_[PiecewiseChunkSize()]; + size_t position_; +}; + // HashStateBase // // A hash state object represents an intermediate state in the computation @@ -181,7 +181,7 @@ class HashStateBase { template <typename T> static H combine_contiguous(H state, const T* data, size_t size); - using AbslInternalPiecewiseCombiner = PiecewiseCombiner; + using AbslInternalPiecewiseCombiner = PiecewiseCombiner; }; // is_uniquely_represented @@ -413,7 +413,7 @@ H AbslHashValue(H hash_state, const std::shared_ptr<T>& ptr) { // All the string-like types supported here provide the same hash expansion for // the same character sequence. These types are: // -// - `y_absl::Cord` +// - `y_absl::Cord` // - `TString` (and std::basic_string<char, std::char_traits<char>, A> for // any allocator A) // - `y_absl::string_view` and `std::string_view` @@ -576,13 +576,13 @@ typename std::enable_if<is_hashable<Key>::value, H>::type AbslHashValue( // AbslHashValue for Wrapper Types // ----------------------------------------------------------------------------- -// AbslHashValue for hashing std::reference_wrapper -template <typename H, typename T> -typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue( - H hash_state, std::reference_wrapper<T> opt) { - return H::combine(std::move(hash_state), opt.get()); -} - +// AbslHashValue for hashing std::reference_wrapper +template <typename H, typename T> +typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue( + H hash_state, std::reference_wrapper<T> opt) { + return H::combine(std::move(hash_state), opt.get()); +} + // AbslHashValue for hashing y_absl::optional template <typename H, typename T> typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue( @@ -834,7 +834,7 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { static uint64_t CombineContiguousImpl(uint64_t state, const unsigned char* first, size_t len, std::integral_constant<int, 8> - /* sizeof_size_t */); + /* sizeof_size_t */); // Slow dispatch path for calls to CombineContiguousImpl with a size argument // larger than PiecewiseChunkSize(). Has the same effect as calling @@ -847,54 +847,54 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { size_t len); // Reads 9 to 16 bytes from p. - // The least significant 8 bytes are in .first, the rest (zero padded) bytes - // are in .second. + // The least significant 8 bytes are in .first, the rest (zero padded) bytes + // are in .second. static std::pair<uint64_t, uint64_t> Read9To16(const unsigned char* p, size_t len) { - uint64_t low_mem = y_absl::base_internal::UnalignedLoad64(p); - uint64_t high_mem = y_absl::base_internal::UnalignedLoad64(p + len - 8); -#ifdef ABSL_IS_LITTLE_ENDIAN - uint64_t most_significant = high_mem; - uint64_t least_significant = low_mem; -#else - uint64_t most_significant = low_mem; - uint64_t least_significant = high_mem; -#endif - return {least_significant, most_significant >> (128 - len * 8)}; + uint64_t low_mem = y_absl::base_internal::UnalignedLoad64(p); + uint64_t high_mem = y_absl::base_internal::UnalignedLoad64(p + len - 8); +#ifdef ABSL_IS_LITTLE_ENDIAN + uint64_t most_significant = high_mem; + uint64_t least_significant = low_mem; +#else + uint64_t most_significant = low_mem; + uint64_t least_significant = high_mem; +#endif + return {least_significant, most_significant >> (128 - len * 8)}; } // Reads 4 to 8 bytes from p. Zero pads to fill uint64_t. static uint64_t Read4To8(const unsigned char* p, size_t len) { - uint32_t low_mem = y_absl::base_internal::UnalignedLoad32(p); - uint32_t high_mem = y_absl::base_internal::UnalignedLoad32(p + len - 4); -#ifdef ABSL_IS_LITTLE_ENDIAN - uint32_t most_significant = high_mem; - uint32_t least_significant = low_mem; -#else - uint32_t most_significant = low_mem; - uint32_t least_significant = high_mem; -#endif - return (static_cast<uint64_t>(most_significant) << (len - 4) * 8) | - least_significant; + uint32_t low_mem = y_absl::base_internal::UnalignedLoad32(p); + uint32_t high_mem = y_absl::base_internal::UnalignedLoad32(p + len - 4); +#ifdef ABSL_IS_LITTLE_ENDIAN + uint32_t most_significant = high_mem; + uint32_t least_significant = low_mem; +#else + uint32_t most_significant = low_mem; + uint32_t least_significant = high_mem; +#endif + return (static_cast<uint64_t>(most_significant) << (len - 4) * 8) | + least_significant; } // Reads 1 to 3 bytes from p. Zero pads to fill uint32_t. static uint32_t Read1To3(const unsigned char* p, size_t len) { - unsigned char mem0 = p[0]; - unsigned char mem1 = p[len / 2]; - unsigned char mem2 = p[len - 1]; -#ifdef ABSL_IS_LITTLE_ENDIAN - unsigned char significant2 = mem2; - unsigned char significant1 = mem1; - unsigned char significant0 = mem0; -#else - unsigned char significant2 = mem0; - unsigned char significant1 = mem1; - unsigned char significant0 = mem2; -#endif - return static_cast<uint32_t>(significant0 | // - (significant1 << (len / 2 * 8)) | // - (significant2 << ((len - 1) * 8))); + unsigned char mem0 = p[0]; + unsigned char mem1 = p[len / 2]; + unsigned char mem2 = p[len - 1]; +#ifdef ABSL_IS_LITTLE_ENDIAN + unsigned char significant2 = mem2; + unsigned char significant1 = mem1; + unsigned char significant0 = mem0; +#else + unsigned char significant2 = mem0; + unsigned char significant1 = mem1; + unsigned char significant0 = mem2; +#endif + return static_cast<uint32_t>(significant0 | // + (significant1 << (len / 2 * 8)) | // + (significant2 << ((len - 1) * 8))); } ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) { @@ -919,16 +919,16 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { // An extern to avoid bloat on a direct call to LowLevelHash() with fixed // values for both the seed and salt parameters. static uint64_t LowLevelHashImpl(const unsigned char* data, size_t len); - - ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Hash64(const unsigned char* data, - size_t len) { -#ifdef ABSL_HAVE_INTRINSIC_INT128 + + ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Hash64(const unsigned char* data, + size_t len) { +#ifdef ABSL_HAVE_INTRINSIC_INT128 return LowLevelHashImpl(data, len); -#else +#else return hash_internal::CityHash64(reinterpret_cast<const char*>(data), len); -#endif - } - +#endif + } + // Seed() // // A non-deterministic seed. @@ -946,14 +946,14 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { // On other platforms this is still going to be non-deterministic but most // probably per-build and not per-process. ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Seed() { -#if (!defined(__clang__) || __clang_major__ > 11) && \ - !defined(__apple_build_version__) - return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&kSeed)); -#else - // Workaround the absence of - // https://github.com/llvm/llvm-project/commit/bc15bf66dcca76cc06fe71fca35b74dc4d521021. +#if (!defined(__clang__) || __clang_major__ > 11) && \ + !defined(__apple_build_version__) + return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&kSeed)); +#else + // Workaround the absence of + // https://github.com/llvm/llvm-project/commit/bc15bf66dcca76cc06fe71fca35b74dc4d521021. return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(kSeed)); -#endif +#endif } static const void* const kSeed; @@ -994,7 +994,7 @@ inline uint64_t MixingHashState::CombineContiguousImpl( if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) { return CombineLargeContiguousImpl64(state, first, len); } - v = Hash64(first, len); + v = Hash64(first, len); } else if (len > 8) { auto p = Read9To16(first, len); state = Mix(state, p.first); @@ -1060,15 +1060,15 @@ H PiecewiseCombiner::add_buffer(H state, const unsigned char* data, return state; } - // If the buffer is partially filled we need to complete the buffer - // and hash it. - if (position_ != 0) { - const size_t bytes_needed = PiecewiseChunkSize() - position_; - memcpy(buf_ + position_, data, bytes_needed); - state = H::combine_contiguous(std::move(state), buf_, PiecewiseChunkSize()); - data += bytes_needed; - size -= bytes_needed; - } + // If the buffer is partially filled we need to complete the buffer + // and hash it. + if (position_ != 0) { + const size_t bytes_needed = PiecewiseChunkSize() - position_; + memcpy(buf_ + position_, data, bytes_needed); + state = H::combine_contiguous(std::move(state), buf_, PiecewiseChunkSize()); + data += bytes_needed; + size -= bytes_needed; + } // Hash whatever chunks we can without copying while (size >= PiecewiseChunkSize()) { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.cc index 08b6dd85d4..d77a8efb58 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.cc @@ -1,33 +1,33 @@ -// 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. - +// 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 "y_absl/hash/internal/low_level_hash.h" - -#include "y_absl/base/internal/unaligned_access.h" + +#include "y_absl/base/internal/unaligned_access.h" #include "y_absl/numeric/bits.h" -#include "y_absl/numeric/int128.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace hash_internal { - +#include "y_absl/numeric/int128.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace hash_internal { + static uint64_t Mix(uint64_t v0, uint64_t v1) { #if !defined(__aarch64__) // The default bit-mixer uses 64x64->128-bit multiplication. - y_absl::uint128 p = v0; - p *= v1; - return y_absl::Uint128Low64(p) ^ y_absl::Uint128High64(p); + y_absl::uint128 p = v0; + p *= v1; + return y_absl::Uint128Low64(p) ^ y_absl::Uint128High64(p); #else // The default bit-mixer above would perform poorly on some ARM microarchs, // where calculating a 128-bit product requires a sequence of two @@ -37,87 +37,87 @@ static uint64_t Mix(uint64_t v0, uint64_t v1) { p *= v1 ^ y_absl::rotl(v0, 39); return p ^ (p >> 11); #endif -} - +} + uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, const uint64_t salt[]) { - const uint8_t* ptr = static_cast<const uint8_t*>(data); - uint64_t starting_length = static_cast<uint64_t>(len); - uint64_t current_state = seed ^ salt[0]; - - if (len > 64) { - // If we have more than 64 bytes, we're going to handle chunks of 64 - // bytes at a time. We're going to build up two separate hash states - // which we will then hash together. - uint64_t duplicated_state = current_state; - - do { - uint64_t a = y_absl::base_internal::UnalignedLoad64(ptr); - uint64_t b = y_absl::base_internal::UnalignedLoad64(ptr + 8); - uint64_t c = y_absl::base_internal::UnalignedLoad64(ptr + 16); - uint64_t d = y_absl::base_internal::UnalignedLoad64(ptr + 24); - uint64_t e = y_absl::base_internal::UnalignedLoad64(ptr + 32); - uint64_t f = y_absl::base_internal::UnalignedLoad64(ptr + 40); - uint64_t g = y_absl::base_internal::UnalignedLoad64(ptr + 48); - uint64_t h = y_absl::base_internal::UnalignedLoad64(ptr + 56); - + const uint8_t* ptr = static_cast<const uint8_t*>(data); + uint64_t starting_length = static_cast<uint64_t>(len); + uint64_t current_state = seed ^ salt[0]; + + if (len > 64) { + // If we have more than 64 bytes, we're going to handle chunks of 64 + // bytes at a time. We're going to build up two separate hash states + // which we will then hash together. + uint64_t duplicated_state = current_state; + + do { + uint64_t a = y_absl::base_internal::UnalignedLoad64(ptr); + uint64_t b = y_absl::base_internal::UnalignedLoad64(ptr + 8); + uint64_t c = y_absl::base_internal::UnalignedLoad64(ptr + 16); + uint64_t d = y_absl::base_internal::UnalignedLoad64(ptr + 24); + uint64_t e = y_absl::base_internal::UnalignedLoad64(ptr + 32); + uint64_t f = y_absl::base_internal::UnalignedLoad64(ptr + 40); + uint64_t g = y_absl::base_internal::UnalignedLoad64(ptr + 48); + uint64_t h = y_absl::base_internal::UnalignedLoad64(ptr + 56); + uint64_t cs0 = Mix(a ^ salt[1], b ^ current_state); uint64_t cs1 = Mix(c ^ salt[2], d ^ current_state); - current_state = (cs0 ^ cs1); - + current_state = (cs0 ^ cs1); + uint64_t ds0 = Mix(e ^ salt[3], f ^ duplicated_state); uint64_t ds1 = Mix(g ^ salt[4], h ^ duplicated_state); - duplicated_state = (ds0 ^ ds1); - - ptr += 64; - len -= 64; - } while (len > 64); - - current_state = current_state ^ duplicated_state; - } - - // We now have a data `ptr` with at most 64 bytes and the current state - // of the hashing state machine stored in current_state. - while (len > 16) { - uint64_t a = y_absl::base_internal::UnalignedLoad64(ptr); - uint64_t b = y_absl::base_internal::UnalignedLoad64(ptr + 8); - + duplicated_state = (ds0 ^ ds1); + + ptr += 64; + len -= 64; + } while (len > 64); + + current_state = current_state ^ duplicated_state; + } + + // We now have a data `ptr` with at most 64 bytes and the current state + // of the hashing state machine stored in current_state. + while (len > 16) { + uint64_t a = y_absl::base_internal::UnalignedLoad64(ptr); + uint64_t b = y_absl::base_internal::UnalignedLoad64(ptr + 8); + current_state = Mix(a ^ salt[1], b ^ current_state); - - ptr += 16; - len -= 16; - } - - // We now have a data `ptr` with at most 16 bytes. - uint64_t a = 0; - uint64_t b = 0; - if (len > 8) { - // When we have at least 9 and at most 16 bytes, set A to the first 64 - // bits of the input and B to the last 64 bits of the input. Yes, they will - // overlap in the middle if we are working with less than the full 16 - // bytes. - a = y_absl::base_internal::UnalignedLoad64(ptr); - b = y_absl::base_internal::UnalignedLoad64(ptr + len - 8); - } else if (len > 3) { - // If we have at least 4 and at most 8 bytes, set A to the first 32 - // bits and B to the last 32 bits. - a = y_absl::base_internal::UnalignedLoad32(ptr); - b = y_absl::base_internal::UnalignedLoad32(ptr + len - 4); - } else if (len > 0) { - // If we have at least 1 and at most 3 bytes, read all of the provided - // bits into A, with some adjustments. - a = ((ptr[0] << 16) | (ptr[len >> 1] << 8) | ptr[len - 1]); - b = 0; - } else { - a = 0; - b = 0; - } - + + ptr += 16; + len -= 16; + } + + // We now have a data `ptr` with at most 16 bytes. + uint64_t a = 0; + uint64_t b = 0; + if (len > 8) { + // When we have at least 9 and at most 16 bytes, set A to the first 64 + // bits of the input and B to the last 64 bits of the input. Yes, they will + // overlap in the middle if we are working with less than the full 16 + // bytes. + a = y_absl::base_internal::UnalignedLoad64(ptr); + b = y_absl::base_internal::UnalignedLoad64(ptr + len - 8); + } else if (len > 3) { + // If we have at least 4 and at most 8 bytes, set A to the first 32 + // bits and B to the last 32 bits. + a = y_absl::base_internal::UnalignedLoad32(ptr); + b = y_absl::base_internal::UnalignedLoad32(ptr + len - 4); + } else if (len > 0) { + // If we have at least 1 and at most 3 bytes, read all of the provided + // bits into A, with some adjustments. + a = ((ptr[0] << 16) | (ptr[len >> 1] << 8) | ptr[len - 1]); + b = 0; + } else { + a = 0; + b = 0; + } + uint64_t w = Mix(a ^ salt[1], b ^ current_state); - uint64_t z = salt[1] ^ starting_length; + uint64_t z = salt[1] ^ starting_length; return Mix(w, z); -} - -} // namespace hash_internal -ABSL_NAMESPACE_END -} // namespace y_absl +} + +} // namespace hash_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.h b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.h index 4a71ab9418..a9cf012cc5 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.h @@ -1,19 +1,19 @@ -// 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. -// +// 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. +// // This file provides the Google-internal implementation of LowLevelHash. -// +// // LowLevelHash is a fast hash function for hash tables, the fastest we've // currently (late 2020) found that passes the SMHasher tests. The algorithm // relies on intrinsic 128-bit multiplication for speed. This is not meant to be @@ -21,30 +21,30 @@ // // It is closely based on a version of wyhash, but does not maintain or // guarantee future compatibility with it. - + #ifndef ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ #define ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ - -#include <stdint.h> -#include <stdlib.h> - -#include "y_absl/base/config.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace hash_internal { - -// Hash function for a byte array. A 64-bit seed and a set of five 64-bit -// integers are hashed into the result. -// -// To allow all hashable types (including string_view and Span) to depend on + +#include <stdint.h> +#include <stdlib.h> + +#include "y_absl/base/config.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace hash_internal { + +// Hash function for a byte array. A 64-bit seed and a set of five 64-bit +// integers are hashed into the result. +// +// To allow all hashable types (including string_view and Span) to depend on // this algorithm, we keep the API low-level, with as few dependencies as -// possible. +// possible. uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, const uint64_t salt[5]); - -} // namespace hash_internal -ABSL_NAMESPACE_END -} // namespace y_absl - + +} // namespace hash_internal +ABSL_NAMESPACE_END +} // namespace y_absl + #endif // ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/ya.make index 7f3aae3751..f2244ccce9 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/ya.make @@ -1,32 +1,32 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -OWNER( - somov - g:cpp-contrib -) - -LICENSE(Apache-2.0) - -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - -PEERDIR( - contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/numeric -) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp-tstring -) - -NO_COMPILER_WARNINGS() - -SRCS( +# Generated by devtools/yamaker. + +LIBRARY() + +OWNER( + somov + g:cpp-contrib +) + +LICENSE(Apache-2.0) + +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + +PEERDIR( + contrib/restricted/abseil-cpp-tstring/y_absl/base + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait + contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity + contrib/restricted/abseil-cpp-tstring/y_absl/numeric +) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp-tstring +) + +NO_COMPILER_WARNINGS() + +SRCS( low_level_hash.cc -) - -END() +) + +END() |