summaryrefslogtreecommitdiff
path: root/absl/strings
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/cord.cc8
-rw-r--r--absl/strings/cord.h28
-rw-r--r--absl/strings/cord_test.cc4
-rw-r--r--absl/strings/internal/cord_internal.h6
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 {