|
|
|
// 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/strings/internal/cord_internal.h"
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <cassert>
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
#include "absl/container/inlined_vector.h"
|
|
|
|
#include "absl/strings/internal/cord_rep_btree.h"
|
|
|
|
#include "absl/strings/internal/cord_rep_crc.h"
|
|
|
|
#include "absl/strings/internal/cord_rep_flat.h"
|
|
|
|
#include "absl/strings/internal/cord_rep_ring.h"
|
|
|
|
|
|
|
|
namespace absl {
|
|
|
|
ABSL_NAMESPACE_BEGIN
|
|
|
|
namespace cord_internal {
|
|
|
|
|
Export of internal Abseil changes
--
007ce045d5d38a727ededdb5bf06e64785fd73bd by Martijn Vels <mvels@google.com>:
Add `cord_enable_btree` feature flag (default false).
PiperOrigin-RevId: 383729939
--
98e7dc6a0407b0fd7b8713d883cdb3a766e0583d by Benjamin Barenblat <bbaren@google.com>:
Eliminate some byte swapping from randen_slow
Stop swapping bytes when serializing randen_slow’s Vector128 into and
out of memory. Instead, simply index different bytes in the AES round
function. This requires byte swapping the te{0..3} lookup tables, but it
produces an 8% speedup on my Xeon W-2135.
PiperOrigin-RevId: 383689402
--
180b6bf45049188840d439b16a28e6b968669340 by Evan Brown <ezb@google.com>:
Minor simplification in drop_deletes_without_resize() - save probe_offset outside the lambda.
Also, add some consts, avoid an auto, and use lambda capture by value instead of reference.
I realized that the compiler can already optimize this - https://godbolt.org/z/Wxd9c4TfK, but I think this way makes the code a bit clearer.
PiperOrigin-RevId: 383646658
--
781706a974c4dc1c0abbb6b801fca0550229e883 by Martijn Vels <mvels@google.com>:
Change storage to contain 3 bytes.
As per the comments in the code, this allows us to utilize all available space in CordRep that may otherwise be 'lost' in padding in derived clases. For the upcoming CordrepBtree class, we want a strong guarantee on having a 64 bytes aligned implementation.
PiperOrigin-RevId: 383633963
--
8fe22ecf92492fa6649938a2215934ebfe01c714 by Derek Mauro <dmauro@google.com>:
Remove reference to str_format_arg.h, which no longer exists
PiperOrigin-RevId: 383517865
--
79397f3b18f18c1e2d7aea993b687329d626ce64 by Benjamin Barenblat <bbaren@google.com>:
Use absl::uint128 for AES random number generator
Replace randen’s internal 128-bit integer struct, u64x2, with
absl::uint128. This eliminates some code and improves support for
big-endian platforms.
PiperOrigin-RevId: 383475671
GitOrigin-RevId: 007ce045d5d38a727ededdb5bf06e64785fd73bd
Change-Id: Ia9d9c40de557221f1744fb0d6d4d6ca7ac569070
3 years ago
|
|
|
ABSL_CONST_INIT std::atomic<bool> cord_btree_enabled(kCordEnableBtreeDefault);
|
|
|
|
ABSL_CONST_INIT std::atomic<bool> cord_ring_buffer_enabled(
|
|
|
|
kCordEnableRingBufferDefault);
|
|
|
|
ABSL_CONST_INIT std::atomic<bool> shallow_subcords_enabled(
|
|
|
|
kCordShallowSubcordsDefault);
|
|
|
|
ABSL_CONST_INIT std::atomic<bool> cord_btree_exhaustive_validation(false);
|
|
|
|
|
|
|
|
void CordRep::Destroy(CordRep* rep) {
|
|
|
|
assert(rep != nullptr);
|
|
|
|
|
|
|
|
absl::InlinedVector<CordRep*, Constants::kInlinedVectorSize> pending;
|
|
|
|
while (true) {
|
|
|
|
assert(!rep->refcount.IsImmortal());
|
|
|
|
if (rep->tag == CONCAT) {
|
|
|
|
CordRepConcat* rep_concat = rep->concat();
|
|
|
|
CordRep* right = rep_concat->right;
|
|
|
|
if (!right->refcount.Decrement()) {
|
|
|
|
pending.push_back(right);
|
|
|
|
}
|
|
|
|
CordRep* left = rep_concat->left;
|
|
|
|
delete rep_concat;
|
|
|
|
rep = nullptr;
|
|
|
|
if (!left->refcount.Decrement()) {
|
|
|
|
rep = left;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else if (rep->tag == BTREE) {
|
|
|
|
CordRepBtree::Destroy(rep->btree());
|
|
|
|
rep = nullptr;
|
|
|
|
} else if (rep->tag == RING) {
|
|
|
|
CordRepRing::Destroy(rep->ring());
|
|
|
|
rep = nullptr;
|
|
|
|
} else if (rep->tag == EXTERNAL) {
|
|
|
|
CordRepExternal::Delete(rep);
|
|
|
|
rep = nullptr;
|
|
|
|
} else if (rep->tag == SUBSTRING) {
|
|
|
|
CordRepSubstring* rep_substring = rep->substring();
|
|
|
|
CordRep* child = rep_substring->child;
|
|
|
|
delete rep_substring;
|
|
|
|
rep = nullptr;
|
|
|
|
if (!child->refcount.Decrement()) {
|
|
|
|
rep = child;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else if (rep->tag == CRC) {
|
|
|
|
CordRepCrc::Destroy(rep->crc());
|
|
|
|
rep = nullptr;
|
|
|
|
} else {
|
|
|
|
CordRepFlat::Delete(rep);
|
|
|
|
rep = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pending.empty()) {
|
|
|
|
rep = pending.back();
|
|
|
|
pending.pop_back();
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace cord_internal
|
|
|
|
ABSL_NAMESPACE_END
|
|
|
|
} // namespace absl
|