summaryrefslogtreecommitdiff
path: root/absl/strings/cord.cc
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-04-23 05:02:23 -0700
committerGravatar Dino Radaković <dinor@google.com>2021-04-23 08:49:16 -0700
commitd96e287417766deddbff2d01b96321288c59491e (patch)
tree2a5aa297bf5be0f749db6368675ef723d5b4322a /absl/strings/cord.cc
parente38e1aae3866a4ae3a41ccb38d3f05618ea30ca4 (diff)
Export of internal Abseil changes
-- f825cf3feb6db06522b2b4ee785de7dfa325780d by Martijn Vels <mvels@google.com>: Move Cordz test helpers to cordz_test_helpers library PiperOrigin-RevId: 370059941 -- 5080249da6a4f5cc2b546aed48503fd028670379 by Martijn Vels <mvels@google.com>: Add new Cordz instrumentation on AppendTree. PiperOrigin-RevId: 369968167 -- 21092b889fad34ec605894e311b436d5f417456f by Benjamin Barenblat <bbaren@google.com>: Round floats using round(x), not static_cast<int>(x + 0.5) Adding 0.5 to an IEEE float may cause one bit of precision loss, which is enough to change the result in certain cases. For example, static_cast<int>(std::round(0.49999999999999994)) == 0 static_cast<int>(0.49999999999999994 + 0.5) == 1 PiperOrigin-RevId: 369926519 GitOrigin-RevId: f825cf3feb6db06522b2b4ee785de7dfa325780d Change-Id: Ib78ce1faec79f06578933db5dc6fc05de043ead1
Diffstat (limited to 'absl/strings/cord.cc')
-rw-r--r--absl/strings/cord.cc55
1 files changed, 42 insertions, 13 deletions
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index 44e4d464..768106d4 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -342,14 +342,37 @@ static CordRepRing* ForceRing(CordRep* rep, size_t extra) {
return (rep->tag == RING) ? rep->ring() : CordRepRing::Create(rep, extra);
}
-void Cord::InlineRep::AppendTree(CordRep* tree) {
+void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
+ MethodIdentifier method) {
+ assert(!is_tree());
+ if (!data_.is_empty()) {
+ CordRepFlat* flat = MakeFlat(data_);
+ if (cord_ring_enabled()) {
+ tree = CordRepRing::Append(CordRepRing::Create(flat, 1), tree);
+ } else {
+ tree = Concat(flat, tree);
+ }
+ }
+ EmplaceTree(tree, method);
+}
+
+void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) {
+ assert(is_tree());
+ const CordzUpdateScope scope(data_.cordz_info(), method);
+ if (cord_ring_enabled()) {
+ tree = CordRepRing::Append(ForceRing(data_.as_tree(), 1), tree);
+ } else {
+ tree = Concat(data_.as_tree(), tree);
+ }
+ SetTree(tree, scope);
+}
+
+void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) {
if (tree == nullptr) return;
- if (data_.is_empty()) {
- set_tree(tree);
- } else if (cord_ring_enabled()) {
- set_tree(CordRepRing::Append(ForceRing(force_tree(0), 1), tree));
+ if (data_.is_tree()) {
+ AppendTreeToTree(tree, method);
} else {
- set_tree(Concat(force_tree(0), tree));
+ AppendTreeToInlined(tree, method);
}
}
@@ -533,9 +556,8 @@ Cord::Cord(absl::string_view src) : contents_(InlineData::kDefaultInit) {
if (n <= InlineRep::kMaxInline) {
contents_.set_data(src.data(), n, true);
} else {
- contents_.data_.make_tree(NewTree(src.data(), n, 0));
- CordzInfo::MaybeTrackCord(contents_.data_,
- CordzUpdateTracker::kConstructorString);
+ CordRep* rep = NewTree(src.data(), n, 0);
+ contents_.EmplaceTree(rep, CordzUpdateTracker::kConstructorString);
}
}
@@ -713,9 +735,15 @@ inline CordRep* Cord::TakeRep() && {
template <typename C>
inline void Cord::AppendImpl(C&& src) {
if (empty()) {
- // In case of an empty destination avoid allocating a new node, do not copy
- // data.
- *this = std::forward<C>(src);
+ // Since destination is empty, we can avoid allocating a node,
+ if (src.contents_.is_tree()) {
+ // by taking the tree directly
+ CordRep* rep = std::forward<C>(src).TakeRep();
+ contents_.EmplaceTree(rep, CordzUpdateTracker::kAppendCord);
+ } else {
+ // or copying over inline data
+ contents_.data_ = src.contents_.data_;
+ }
return;
}
@@ -746,7 +774,8 @@ inline void Cord::AppendImpl(C&& src) {
}
// Guaranteed to be a tree (kMaxBytesToCopy > kInlinedSize)
- contents_.AppendTree(std::forward<C>(src).TakeRep());
+ CordRep* rep = std::forward<C>(src).TakeRep();
+ contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord);
}
void Cord::Append(const Cord& src) { AppendImpl(src); }