|
|
|
// 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 "absl/container/internal/raw_hash_set.h"
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <cstddef>
|
|
|
|
|
|
|
|
#include "absl/base/config.h"
|
|
|
|
|
|
|
|
namespace absl {
|
|
|
|
ABSL_NAMESPACE_BEGIN
|
|
|
|
namespace container_internal {
|
|
|
|
|
|
|
|
constexpr size_t Group::kWidth;
|
|
|
|
|
|
|
|
// Returns "random" seed.
|
|
|
|
inline size_t RandomSeed() {
|
|
|
|
#ifdef ABSL_HAVE_THREAD_LOCAL
|
|
|
|
static thread_local size_t counter = 0;
|
|
|
|
size_t value = ++counter;
|
|
|
|
#else // ABSL_HAVE_THREAD_LOCAL
|
|
|
|
static std::atomic<size_t> counter(0);
|
|
|
|
size_t value = counter.fetch_add(1, std::memory_order_relaxed);
|
|
|
|
#endif // ABSL_HAVE_THREAD_LOCAL
|
|
|
|
return value ^ static_cast<size_t>(reinterpret_cast<uintptr_t>(&counter));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ShouldInsertBackwards(size_t hash, ctrl_t* ctrl) {
|
|
|
|
// To avoid problems with weak hashes and single bit tests, we use % 13.
|
|
|
|
// TODO(kfm,sbenza): revisit after we do unconditional mixing
|
|
|
|
return (H1(hash, ctrl) ^ RandomSeed()) % 13 > 6;
|
|
|
|
}
|
|
|
|
|
Export of internal Abseil changes
--
92811d3307196b2810bdc3c7e50ef9544db3f23b by CJ Johnson <johnsoncj@google.com>:
Refactor InlinedVector's OverheadTest.Storage test to be easier to understand and modify in the future
PiperOrigin-RevId: 342718098
--
cf3f2af201775f9c4e68dd2f9806126aecbd0748 by Abseil Team <absl-team@google.com>:
Implement `reserve` more explicit to avoid calling `rehash`.
`reserve` is much more widely used method and doesn't need extra logic present in `rehash`.
E. g., accidental `t.reserve(0)` on non empty table shouldn't cause rehashing, which was a case before this change.
It also remove some unnecessary computations from `reserve`.
Was:
```
GrowthToLowerboundCapacity 2x
NormalizeCapacity 1x
bitwise | 1x
n == 0 && capacity_ == 0 1x
n == 0 && size_ == 0 1x
n == 0 1x
|| 1x
m > capacity_ 1x
overall branches 6x
(GrowthToLowerboundCapacity 2x, NormalizeCapacity 1x, rehash 3x)
```
Now:
```
GrowthToLowerboundCapacity 1x
NormalizeCapacity 1x
bitwise | 0x
n == 0 && capacity_ == 0 0x
n == 0 && size_ == 0 0x
n == 0 0x
|| 0x
m > capacity_ 1x
overall branches 3x
(GrowthToLowerboundCapacity 1x, NormalizeCapacity 1x, reserve 1x)
```
PiperOrigin-RevId: 342714022
--
c2ab8c1e4091ff685110c81bae12e3567e0cded3 by Abseil Team <absl-team@google.com>:
Remove `reset_growth_left` call, which already happen in `initialize_slots`.
PiperOrigin-RevId: 342701073
--
3f41ccb70afabec8bc0dcfcca3e3ac918726bb92 by Derek Mauro <dmauro@google.com>:
Use memmove instead of memcpy in situations where the source and
destination may point to the same buffer
Note that the OSS Abseil code never calls CUnescapeInternal with
leave_nulls_scaped=true, so there is no bug in the OSS code.
Fixes #844
PiperOrigin-RevId: 342633781
--
57afb2c307b008b9f9daaa736b49c066e0075e39 by Abseil Team <absl-team@google.com>:
Add absl::Round() for absl::Duration as a complementary to Floor, Ceil and Trunc. Rounding halfway cases away from zero as std::round() does.
PiperOrigin-RevId: 342610871
--
c49754ecddb9339eff60b826dc17b3b459333bc0 by Abseil Team <absl-team@google.com>:
Add absl::Round() for absl::Duration as a complementary to Floor, Ceil and Trunc. Rounding halfway cases away from zero as std::round() does.
PiperOrigin-RevId: 342594847
--
b51bd29233aaee6ef241de984635356d26c93e4d by Abseil Team <absl-team@google.com>:
Move `ConvertDeletedToEmptyAndFullToDeleted` to cc file.
This function is cold and only used when table become polluted with deleted slots.
So this shouldn't negatively affect performance and considered safe.
This change is reducing linkage and binary size.
PiperOrigin-RevId: 342319685
--
acb83c004d14e563a3b47dcfcb6c5508bee6408f by Abseil Team <absl-team@google.com>:
Fix indentation in uniform_int_distribution.h.
PiperOrigin-RevId: 342297575
GitOrigin-RevId: 92811d3307196b2810bdc3c7e50ef9544db3f23b
Change-Id: I4fbaf4aab122d5c939ae9a3ef46ee8cca3df75e6
4 years ago
|
|
|
void ConvertDeletedToEmptyAndFullToDeleted(
|
|
|
|
ctrl_t* ctrl, size_t capacity) {
|
|
|
|
assert(ctrl[capacity] == kSentinel);
|
|
|
|
assert(IsValidCapacity(capacity));
|
Export of internal Abseil changes
--
b1fc72630aaa81c8395c3b22ba267d938fe29a2e by Derek Mauro <dmauro@google.com>:
Fix -Wdeprecated-copy warnings from Clang 13.
Example:
error: definition of implicit copy assignment operator for 'UDT' is deprecated because it has a user-declared copy constructor [-Werror,-Wdeprecated-copy]
PiperOrigin-RevId: 380058303
--
0422744812b1a2010d9eea5b17fbe89f3441b66b by Evan Brown <ezb@google.com>:
Change the "full table!" asserts in raw_hash_set to use `<= capacity` instead of `< capacity`.
If we add support for non-power-of-two-minus-one capacities, this is the correct thing to assert. For example, consider: Group::kWidth = 8, capacity_ = 8, ctrl_ = {kEmpty, 1, 2, 3, 4, 5, 6, 7, kSentinel, kEmpty, 1, 2, 3, 4, 5, 6}. In this case, if we do an unsuccessful lookup with H2 mapping to slot 1, then the first Group will contain {1, 2, 3, 4, 5, 6, 7, kSentinel} so we need to continue to the second Group (at which point seq.index() == 8 == capacity_) to find a kEmpty.
Note: this is a no-op change for now since we never have `capacity % Group::kWidth == 0`.
PiperOrigin-RevId: 380033480
--
40628c34d540356de65fabb16c1439c0ec7a0764 by Abseil Team <absl-team@google.com>:
Drop out-of-date documentation about `absl::FixedArray`'s allocator support
PiperOrigin-RevId: 379811653
--
e7ad047863ae55c9b7aec0753cfc527a4ea614bc by Evan Brown <ezb@google.com>:
Fix a bug in ConvertDeletedToEmptyAndFullToDeleted in which we were copying 1 more cloned control byte than actually exists.
When alignof(slot_type)>1, this wouldn't cause a problem because the extra byte is padding.
Also change loop bounds to not rely on the fact that capacity_+1 is a multiple of Group::kWidth.
PiperOrigin-RevId: 379311830
--
1a3ba500fb2c33205854eb9258cd6e0fb1061bca by Martijn Vels <mvels@google.com>:
Change Ring, EXTERNAL and FLAT tag values to be consecutive values
The purpose of this change is to have FLAT = EXTERNAL + 1. Especially in the ring and btree alternative code, there is a common check if a node is a 'plain' edge (EXTERNAL or FLAT), or 'something else'. This change can make that check a single branch, i.e., instead of 'tag == EXTERNAL || tag >= FLAT', we can simply check for 'tag >= EXTERNAL'. Likewise we have some cases where we check for RING, EXTERNAL or FLAT, so we align RING + 1 with EXTERNAL.
PiperOrigin-RevId: 379291576
--
0c78e65ca4d85244b106c3f8e24cf268e09e72a3 by Benjamin Barenblat <bbaren@google.com>:
Round a double multiplication before casting it to integer
The code
static_cast<int>(x * y)
(for double x and y) performs a double multiplication into a temporary
that, by standard, may have excess precision. The subsequent cast to int
discards the excess precision. However, the cast may examine the excess
precision during conversion, producing surprising results like
static_cast<int>(1.7 * 10) == 16
on certain systems. Correct this case by explicitly rounding 1.7 * 10
before casting it.
PiperOrigin-RevId: 378922064
GitOrigin-RevId: b1fc72630aaa81c8395c3b22ba267d938fe29a2e
Change-Id: Ica708a006921118673e78d5fd2d61fe0fb0894d1
4 years ago
|
|
|
for (ctrl_t* pos = ctrl; pos < ctrl + capacity; pos += Group::kWidth) {
|
Export of internal Abseil changes
--
92811d3307196b2810bdc3c7e50ef9544db3f23b by CJ Johnson <johnsoncj@google.com>:
Refactor InlinedVector's OverheadTest.Storage test to be easier to understand and modify in the future
PiperOrigin-RevId: 342718098
--
cf3f2af201775f9c4e68dd2f9806126aecbd0748 by Abseil Team <absl-team@google.com>:
Implement `reserve` more explicit to avoid calling `rehash`.
`reserve` is much more widely used method and doesn't need extra logic present in `rehash`.
E. g., accidental `t.reserve(0)` on non empty table shouldn't cause rehashing, which was a case before this change.
It also remove some unnecessary computations from `reserve`.
Was:
```
GrowthToLowerboundCapacity 2x
NormalizeCapacity 1x
bitwise | 1x
n == 0 && capacity_ == 0 1x
n == 0 && size_ == 0 1x
n == 0 1x
|| 1x
m > capacity_ 1x
overall branches 6x
(GrowthToLowerboundCapacity 2x, NormalizeCapacity 1x, rehash 3x)
```
Now:
```
GrowthToLowerboundCapacity 1x
NormalizeCapacity 1x
bitwise | 0x
n == 0 && capacity_ == 0 0x
n == 0 && size_ == 0 0x
n == 0 0x
|| 0x
m > capacity_ 1x
overall branches 3x
(GrowthToLowerboundCapacity 1x, NormalizeCapacity 1x, reserve 1x)
```
PiperOrigin-RevId: 342714022
--
c2ab8c1e4091ff685110c81bae12e3567e0cded3 by Abseil Team <absl-team@google.com>:
Remove `reset_growth_left` call, which already happen in `initialize_slots`.
PiperOrigin-RevId: 342701073
--
3f41ccb70afabec8bc0dcfcca3e3ac918726bb92 by Derek Mauro <dmauro@google.com>:
Use memmove instead of memcpy in situations where the source and
destination may point to the same buffer
Note that the OSS Abseil code never calls CUnescapeInternal with
leave_nulls_scaped=true, so there is no bug in the OSS code.
Fixes #844
PiperOrigin-RevId: 342633781
--
57afb2c307b008b9f9daaa736b49c066e0075e39 by Abseil Team <absl-team@google.com>:
Add absl::Round() for absl::Duration as a complementary to Floor, Ceil and Trunc. Rounding halfway cases away from zero as std::round() does.
PiperOrigin-RevId: 342610871
--
c49754ecddb9339eff60b826dc17b3b459333bc0 by Abseil Team <absl-team@google.com>:
Add absl::Round() for absl::Duration as a complementary to Floor, Ceil and Trunc. Rounding halfway cases away from zero as std::round() does.
PiperOrigin-RevId: 342594847
--
b51bd29233aaee6ef241de984635356d26c93e4d by Abseil Team <absl-team@google.com>:
Move `ConvertDeletedToEmptyAndFullToDeleted` to cc file.
This function is cold and only used when table become polluted with deleted slots.
So this shouldn't negatively affect performance and considered safe.
This change is reducing linkage and binary size.
PiperOrigin-RevId: 342319685
--
acb83c004d14e563a3b47dcfcb6c5508bee6408f by Abseil Team <absl-team@google.com>:
Fix indentation in uniform_int_distribution.h.
PiperOrigin-RevId: 342297575
GitOrigin-RevId: 92811d3307196b2810bdc3c7e50ef9544db3f23b
Change-Id: I4fbaf4aab122d5c939ae9a3ef46ee8cca3df75e6
4 years ago
|
|
|
Group{pos}.ConvertSpecialToEmptyAndFullToDeleted(pos);
|
|
|
|
}
|
|
|
|
// Copy the cloned ctrl bytes.
|
Export of internal Abseil changes
--
b1fc72630aaa81c8395c3b22ba267d938fe29a2e by Derek Mauro <dmauro@google.com>:
Fix -Wdeprecated-copy warnings from Clang 13.
Example:
error: definition of implicit copy assignment operator for 'UDT' is deprecated because it has a user-declared copy constructor [-Werror,-Wdeprecated-copy]
PiperOrigin-RevId: 380058303
--
0422744812b1a2010d9eea5b17fbe89f3441b66b by Evan Brown <ezb@google.com>:
Change the "full table!" asserts in raw_hash_set to use `<= capacity` instead of `< capacity`.
If we add support for non-power-of-two-minus-one capacities, this is the correct thing to assert. For example, consider: Group::kWidth = 8, capacity_ = 8, ctrl_ = {kEmpty, 1, 2, 3, 4, 5, 6, 7, kSentinel, kEmpty, 1, 2, 3, 4, 5, 6}. In this case, if we do an unsuccessful lookup with H2 mapping to slot 1, then the first Group will contain {1, 2, 3, 4, 5, 6, 7, kSentinel} so we need to continue to the second Group (at which point seq.index() == 8 == capacity_) to find a kEmpty.
Note: this is a no-op change for now since we never have `capacity % Group::kWidth == 0`.
PiperOrigin-RevId: 380033480
--
40628c34d540356de65fabb16c1439c0ec7a0764 by Abseil Team <absl-team@google.com>:
Drop out-of-date documentation about `absl::FixedArray`'s allocator support
PiperOrigin-RevId: 379811653
--
e7ad047863ae55c9b7aec0753cfc527a4ea614bc by Evan Brown <ezb@google.com>:
Fix a bug in ConvertDeletedToEmptyAndFullToDeleted in which we were copying 1 more cloned control byte than actually exists.
When alignof(slot_type)>1, this wouldn't cause a problem because the extra byte is padding.
Also change loop bounds to not rely on the fact that capacity_+1 is a multiple of Group::kWidth.
PiperOrigin-RevId: 379311830
--
1a3ba500fb2c33205854eb9258cd6e0fb1061bca by Martijn Vels <mvels@google.com>:
Change Ring, EXTERNAL and FLAT tag values to be consecutive values
The purpose of this change is to have FLAT = EXTERNAL + 1. Especially in the ring and btree alternative code, there is a common check if a node is a 'plain' edge (EXTERNAL or FLAT), or 'something else'. This change can make that check a single branch, i.e., instead of 'tag == EXTERNAL || tag >= FLAT', we can simply check for 'tag >= EXTERNAL'. Likewise we have some cases where we check for RING, EXTERNAL or FLAT, so we align RING + 1 with EXTERNAL.
PiperOrigin-RevId: 379291576
--
0c78e65ca4d85244b106c3f8e24cf268e09e72a3 by Benjamin Barenblat <bbaren@google.com>:
Round a double multiplication before casting it to integer
The code
static_cast<int>(x * y)
(for double x and y) performs a double multiplication into a temporary
that, by standard, may have excess precision. The subsequent cast to int
discards the excess precision. However, the cast may examine the excess
precision during conversion, producing surprising results like
static_cast<int>(1.7 * 10) == 16
on certain systems. Correct this case by explicitly rounding 1.7 * 10
before casting it.
PiperOrigin-RevId: 378922064
GitOrigin-RevId: b1fc72630aaa81c8395c3b22ba267d938fe29a2e
Change-Id: Ica708a006921118673e78d5fd2d61fe0fb0894d1
4 years ago
|
|
|
std::memcpy(ctrl + capacity + 1, ctrl, Group::kWidth - 1);
|
Export of internal Abseil changes
--
92811d3307196b2810bdc3c7e50ef9544db3f23b by CJ Johnson <johnsoncj@google.com>:
Refactor InlinedVector's OverheadTest.Storage test to be easier to understand and modify in the future
PiperOrigin-RevId: 342718098
--
cf3f2af201775f9c4e68dd2f9806126aecbd0748 by Abseil Team <absl-team@google.com>:
Implement `reserve` more explicit to avoid calling `rehash`.
`reserve` is much more widely used method and doesn't need extra logic present in `rehash`.
E. g., accidental `t.reserve(0)` on non empty table shouldn't cause rehashing, which was a case before this change.
It also remove some unnecessary computations from `reserve`.
Was:
```
GrowthToLowerboundCapacity 2x
NormalizeCapacity 1x
bitwise | 1x
n == 0 && capacity_ == 0 1x
n == 0 && size_ == 0 1x
n == 0 1x
|| 1x
m > capacity_ 1x
overall branches 6x
(GrowthToLowerboundCapacity 2x, NormalizeCapacity 1x, rehash 3x)
```
Now:
```
GrowthToLowerboundCapacity 1x
NormalizeCapacity 1x
bitwise | 0x
n == 0 && capacity_ == 0 0x
n == 0 && size_ == 0 0x
n == 0 0x
|| 0x
m > capacity_ 1x
overall branches 3x
(GrowthToLowerboundCapacity 1x, NormalizeCapacity 1x, reserve 1x)
```
PiperOrigin-RevId: 342714022
--
c2ab8c1e4091ff685110c81bae12e3567e0cded3 by Abseil Team <absl-team@google.com>:
Remove `reset_growth_left` call, which already happen in `initialize_slots`.
PiperOrigin-RevId: 342701073
--
3f41ccb70afabec8bc0dcfcca3e3ac918726bb92 by Derek Mauro <dmauro@google.com>:
Use memmove instead of memcpy in situations where the source and
destination may point to the same buffer
Note that the OSS Abseil code never calls CUnescapeInternal with
leave_nulls_scaped=true, so there is no bug in the OSS code.
Fixes #844
PiperOrigin-RevId: 342633781
--
57afb2c307b008b9f9daaa736b49c066e0075e39 by Abseil Team <absl-team@google.com>:
Add absl::Round() for absl::Duration as a complementary to Floor, Ceil and Trunc. Rounding halfway cases away from zero as std::round() does.
PiperOrigin-RevId: 342610871
--
c49754ecddb9339eff60b826dc17b3b459333bc0 by Abseil Team <absl-team@google.com>:
Add absl::Round() for absl::Duration as a complementary to Floor, Ceil and Trunc. Rounding halfway cases away from zero as std::round() does.
PiperOrigin-RevId: 342594847
--
b51bd29233aaee6ef241de984635356d26c93e4d by Abseil Team <absl-team@google.com>:
Move `ConvertDeletedToEmptyAndFullToDeleted` to cc file.
This function is cold and only used when table become polluted with deleted slots.
So this shouldn't negatively affect performance and considered safe.
This change is reducing linkage and binary size.
PiperOrigin-RevId: 342319685
--
acb83c004d14e563a3b47dcfcb6c5508bee6408f by Abseil Team <absl-team@google.com>:
Fix indentation in uniform_int_distribution.h.
PiperOrigin-RevId: 342297575
GitOrigin-RevId: 92811d3307196b2810bdc3c7e50ef9544db3f23b
Change-Id: I4fbaf4aab122d5c939ae9a3ef46ee8cca3df75e6
4 years ago
|
|
|
ctrl[capacity] = kSentinel;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace container_internal
|
|
|
|
ABSL_NAMESPACE_END
|
|
|
|
} // namespace absl
|