diff options
Diffstat (limited to 'absl/strings')
-rw-r--r-- | absl/strings/cord.cc | 8 | ||||
-rw-r--r-- | absl/strings/cord.h | 28 | ||||
-rw-r--r-- | absl/strings/cord_test.cc | 4 | ||||
-rw-r--r-- | absl/strings/internal/cord_internal.h | 6 |
4 files changed, 37 insertions, 9 deletions
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc index 39191ef5..93533757 100644 --- a/absl/strings/cord.cc +++ b/absl/strings/cord.cc @@ -495,7 +495,9 @@ void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { data_ = src.data_; if (is_tree()) { + data_.set_profiled(false); CordRep::Ref(tree()); + clear_cordz_info(); } } @@ -509,12 +511,6 @@ void Cord::InlineRep::ClearSlow() { // -------------------------------------------------------------------- // Constructors and destructors -Cord::Cord(const Cord& src) : contents_(src.contents_) { - if (CordRep* tree = contents_.tree()) { - CordRep::Ref(tree); - } -} - Cord::Cord(absl::string_view src) { const size_t n = src.size(); if (n <= InlineRep::kMaxInline) { diff --git a/absl/strings/cord.h b/absl/strings/cord.h index aefb5e53..320226d2 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h @@ -755,6 +755,23 @@ class Cord { bool is_tree() const { return data_.is_tree(); } + // Returns true if the Cord is being profiled by cordz. + bool is_profiled() const { return data_.is_tree() && data_.is_profiled(); } + + // Returns the profiled CordzInfo, or nullptr if not sampled. + absl::cord_internal::CordzInfo* cordz_info() const { + return data_.cordz_info(); + } + + // Sets the profiled CordzInfo. `cordz_info` must not be null. + void set_cordz_info(cord_internal::CordzInfo* cordz_info) { + assert(cordz_info != nullptr); + data_.set_cordz_info(cordz_info); + } + + // Resets the current cordz_info to null / empty. + void clear_cordz_info() { data_.clear_cordz_info(); } + private: friend class Cord; @@ -921,8 +938,12 @@ Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) { constexpr Cord::InlineRep::InlineRep(cord_internal::InlineData data) : data_(data) {} -inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src) { - data_ = src.data_; +inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src) + : data_(src.data_) { + if (is_tree()) { + data_.clear_cordz_info(); + absl::cord_internal::CordRep::Ref(as_tree()); + } } inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) { @@ -956,7 +977,6 @@ inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) { if (rhs == this) { return; } - std::swap(data_, rhs->data_); } @@ -1037,6 +1057,8 @@ inline Cord& Cord::operator=(const Cord& x) { return *this; } +inline Cord::Cord(const Cord& src) : contents_(src.contents_) {} + inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {} inline void Cord::swap(Cord& other) noexcept { diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc index bf7a6820..f9982428 100644 --- a/absl/strings/cord_test.cc +++ b/absl/strings/cord_test.cc @@ -183,6 +183,10 @@ class CordTestPeer { } static bool IsTree(const Cord& c) { return c.contents_.is_tree(); } + + static cord_internal::CordzInfo* GetCordzInfo(const Cord& c) { + return c.contents_.cordz_info(); + } }; ABSL_NAMESPACE_END diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index cda00a44..a1ba67fe 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h @@ -387,6 +387,12 @@ class InlineData { as_tree_.cordz_info = absl::big_endian::FromHost64(info); } + // Resets the current cordz_info to null / empty. + void clear_cordz_info() { + assert(is_tree()); + as_tree_.cordz_info = kNullCordzInfo; + } + // Returns a read only pointer to the character data inside this instance. // Requires the current instance to hold inline data. const char* as_chars() const { |