summaryrefslogtreecommitdiff
path: root/absl/strings/cord.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-04-30 10:41:56 -0700
committerGravatar Derek Mauro <dmauro@google.com>2021-04-30 13:55:34 -0400
commit5dd240724366295970c613ed23d0092bcf392f18 (patch)
tree6f4f75dacce4a7e10f0fe354474fca849aaa446c /absl/strings/cord.h
parentf14d5f4af12eb521a5142151d6ea3addbbed42bb (diff)
Export of internal Abseil changes
-- 60b8e77be4bab1bbd3b4c3b70054879229634511 by Derek Mauro <dmauro@google.com>: Use _MSVC_LANG for some C++ dialect checks since MSVC doesn't set __cplusplus accurately by default. https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ See GitHub #722. PiperOrigin-RevId: 371362181 -- 5d736accdff04db0e722f377c0d79f2d3ed53263 by Martijn Vels <mvels@google.com>: Fix the estimated memory size for CordRepExternal PiperOrigin-RevId: 371350380 -- eaaa1d8a167aeca67a2aa3a098a2b61a9d72172f by Martijn Vels <mvels@google.com>: Remove flakes by not enforcing re-allocated pointers do never match original Tests that do multiple updates could end up with the original allocated pointer on a 2nd resize, so the 'EqIfPrivate' should not assume that if we do 'not' have the capacity that all following relocations will never match the original. We only care about 'pointer unchanged if private and there is capacity', trying to establish 'pointer changed at some point due to re-allocation; is pointless. PiperOrigin-RevId: 371338965 -- d1837bee6bade1902b095c1cbf64231668bb84c5 by Martijn Vels <mvels@google.com>: Undo inline of small data copy in cord This leads to a performance regression as the code is not inlined (absent hard FDO inputs), and there are no suitable tail call options. PiperOrigin-RevId: 371332332 -- 06dc64b833069efc7d18b11df607c8c22be690da by Martijn Vels <mvels@google.com>: Add final instrumentation for Cordz and remove 'old' cordz logic. This change instruments the last cord function for cordz. It removes the 'old' functions: set_tree, replace_tree, UpdateCordzStatistics and RecordMetrics. PiperOrigin-RevId: 371219909 -- a5e0be538579c603052feec03e6d9910c43ea787 by Martijn Vels <mvels@google.com>: Extend the life of CordRep* if inside a snapshot If a snapshot (potentially) includes the current CordzInfo, we need to extent the lifetime of the CordRep*, as the snapshot 'point in time' observation of the cord should ideally be preserved. PiperOrigin-RevId: 371146151 -- 74d77a89774cd6c8ecdeebee0193b294a39383d6 by Martijn Vels <mvels@google.com>: Instrument std::string consuming methods: ctor, operator=, Append and Prepend This change moves the 'steal into CordRep' logic into a separate function so we can use it directly in the ctor, operator assign and append and prepend, allowing Cordz instrumentation with the proper method attributes. The assign operator is implemented in AssignLargeString leaving the dispatch inlined in cord.h (which as a side effects also allows clean tail calls in the AssignLargeString method) PiperOrigin-RevId: 371094756 -- b39effc45266b7ce2e7f96caa3b16cb6e3acc2dd by Martijn Vels <mvels@google.com>: Add Cordz instrumentation to CordReader PiperOrigin-RevId: 370990181 GitOrigin-RevId: 60b8e77be4bab1bbd3b4c3b70054879229634511 Change-Id: I96af62e6f1a643e8b1228ae01e6c84e33706bb05
Diffstat (limited to 'absl/strings/cord.h')
-rw-r--r--absl/strings/cord.h77
1 files changed, 25 insertions, 52 deletions
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index d7b43247..8abc4742 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -678,6 +678,10 @@ class Cord {
using InlineData = cord_internal::InlineData;
using MethodIdentifier = CordzUpdateTracker::MethodIdentifier;
+ // Creates a cord instance with `method` representing the originating
+ // public API call causing the cord to be created.
+ explicit Cord(absl::string_view src, MethodIdentifier method);
+
friend class CordTestPeer;
friend bool operator==(const Cord& lhs, const Cord& rhs);
friend bool operator==(const Cord& lhs, absl::string_view rhs);
@@ -692,10 +696,6 @@ class Cord {
// called by Flatten() when the cord was not already flat.
absl::string_view FlattenSlowPath();
- // Copies `new_size` bytes starting at `pos` into `dest`. Requires at least
- // `new_size` bytes to be available, and `new_size` to be <= kMaxInline.
- void CopyDataAtPosition(size_t pos, size_t new_size, char* dest) const;
-
// Actual cord contents are hidden inside the following simple
// class so that we can isolate the bulk of cord.cc from changes
// to the representation.
@@ -725,11 +725,6 @@ class Cord {
// Returns nullptr if holding bytes
absl::cord_internal::CordRep* tree() const;
absl::cord_internal::CordRep* as_tree() const;
- // Discards old pointer, if any
- void set_tree(absl::cord_internal::CordRep* rep);
- // Replaces a tree with a new root. This is faster than set_tree, but it
- // should only be used when it's clear that the old rep was a tree.
- void replace_tree(absl::cord_internal::CordRep* rep);
// Returns non-null iff was holding a pointer
absl::cord_internal::CordRep* clear();
// Converts to pointer if necessary.
@@ -831,11 +826,6 @@ class Cord {
// Resets the current cordz_info to null / empty.
void clear_cordz_info() { data_.clear_cordz_info(); }
- // Updates the cordz statistics. info may be nullptr if the CordzInfo object
- // is unknown.
- void UpdateCordzStatistics();
- void UpdateCordzStatisticsSlow();
-
private:
friend class Cord;
@@ -892,6 +882,10 @@ class Cord {
template <typename C>
void AppendImpl(C&& src);
+ // Assigns the value in 'src' to this instance, 'stealing' its contents.
+ // Requires src.length() > kMaxBytesToCopy.
+ Cord& AssignLargeString(std::string&& src);
+
// Helper for AbslHashValue().
template <typename H>
H HashFragmented(H hash_state) const {
@@ -994,8 +988,11 @@ inline CordRep* NewExternalRep(absl::string_view data,
template <typename Releaser>
Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) {
Cord cord;
- cord.contents_.set_tree(::absl::cord_internal::NewExternalRep(
- data, std::forward<Releaser>(releaser)));
+ if (auto* rep = ::absl::cord_internal::NewExternalRep(
+ data, std::forward<Releaser>(releaser))) {
+ cord.contents_.EmplaceTree(rep,
+ Cord::MethodIdentifier::kMakeCordFromExternal);
+ }
return cord;
}
@@ -1119,36 +1116,6 @@ inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep,
}
}
-inline void Cord::InlineRep::set_tree(absl::cord_internal::CordRep* rep) {
- if (rep == nullptr) {
- if (data_.is_tree()) {
- CordzInfo::MaybeUntrackCord(data_.cordz_info());
- }
- ResetToEmpty();
- } else {
- if (data_.is_tree()) {
- // `data_` already holds a 'tree' value and an optional cordz_info value.
- // Replace the tree value only, leaving the cordz_info value unchanged.
- data_.set_tree(rep);
- } else {
- // `data_` contains inlined data: initialize data_ to tree value `rep`.
- data_.make_tree(rep);
- CordzInfo::MaybeTrackCord(data_, CordzUpdateTracker::kUnknown);
- }
- UpdateCordzStatistics();
- }
-}
-
-inline void Cord::InlineRep::replace_tree(absl::cord_internal::CordRep* rep) {
- ABSL_ASSERT(is_tree());
- if (ABSL_PREDICT_FALSE(rep == nullptr)) {
- set_tree(rep);
- return;
- }
- data_.set_tree(rep);
- UpdateCordzStatistics();
-}
-
inline absl::cord_internal::CordRep* Cord::InlineRep::clear() {
if (is_tree()) {
CordzInfo::MaybeUntrackCord(cordz_info());
@@ -1165,13 +1132,11 @@ inline void Cord::InlineRep::CopyToArray(char* dst) const {
cord_internal::SmallMemmove(dst, data_.as_chars(), n);
}
-inline void Cord::InlineRep::UpdateCordzStatistics() {
- if (ABSL_PREDICT_TRUE(!is_profiled())) return;
- UpdateCordzStatisticsSlow();
-}
-
constexpr inline Cord::Cord() noexcept {}
+inline Cord::Cord(absl::string_view src)
+ : Cord(src, CordzUpdateTracker::kConstructorString) {}
+
template <typename T>
constexpr Cord::Cord(strings_internal::StringConstant<T>)
: contents_(strings_internal::StringConstant<T>::value.size() <=
@@ -1187,6 +1152,15 @@ inline Cord& Cord::operator=(const Cord& x) {
return *this;
}
+template <typename T, Cord::EnableIfString<T>>
+Cord& Cord::operator=(T&& src) {
+ if (src.size() <= cord_internal::kMaxBytesToCopy) {
+ return operator=(absl::string_view(src));
+ } else {
+ return AssignLargeString(std::forward<T>(src));
+ }
+}
+
inline Cord::Cord(const Cord& src) : contents_(src.contents_) {}
inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {}
@@ -1201,7 +1175,6 @@ inline Cord& Cord::operator=(Cord&& x) noexcept {
}
extern template Cord::Cord(std::string&& src);
-extern template Cord& Cord::operator=(std::string&& src);
inline size_t Cord::size() const {
// Length is 1st field in str.rep_