summaryrefslogtreecommitdiff
path: root/absl/strings/cord.h
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.h
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.h')
-rw-r--r--absl/strings/cord.h35
1 files changed, 34 insertions, 1 deletions
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index bca20981..dd6c3bca 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -670,6 +670,7 @@ class Cord {
explicit constexpr Cord(strings_internal::StringConstant<T>);
private:
+ using CordRep = absl::cord_internal::CordRep;
using CordzInfo = cord_internal::CordzInfo;
using CordzUpdateScope = cord_internal::CordzUpdateScope;
using CordzUpdateTracker = cord_internal::CordzUpdateTracker;
@@ -680,6 +681,8 @@ class Cord {
friend bool operator==(const Cord& lhs, const Cord& rhs);
friend bool operator==(const Cord& lhs, absl::string_view rhs);
+ friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord);
+
// Calls the provided function once for each cord chunk, in order. Unlike
// Chunks(), this API will not allocate memory.
void ForEachChunk(absl::FunctionRef<void(absl::string_view)>) const;
@@ -730,7 +733,23 @@ class Cord {
void remove_prefix(size_t n); // REQUIRES: holding data
void AppendArray(const char* src_data, size_t src_size);
absl::string_view FindFlatStartPiece() const;
- void AppendTree(absl::cord_internal::CordRep* tree);
+
+ // Sets the tree value for this instance. `rep` must not be null.
+ // Requires the current instance to hold a tree, and a lock to be held on
+ // any CordzInfo referenced by this instance. The latter is enforced through
+ // the CordzUpdateScope argument. If the current instance is sampled, then
+ // the CordzInfo instance is updated to reference the new `rep` value.
+ void SetTree(CordRep* rep, const CordzUpdateScope& scope);
+
+ // Sets the tree value for this instance, and randomly samples this cord.
+ // This function disregards existing contents in `data_`, and should be
+ // called when a Cord is 'promoted' from an 'uninitialized' or 'inlined'
+ // value to a non-inlined (tree / ring) value.
+ void EmplaceTree(CordRep* rep, MethodIdentifier method);
+
+ void AppendTreeToInlined(CordRep* tree, MethodIdentifier method);
+ void AppendTreeToTree(CordRep* tree, MethodIdentifier method);
+ void AppendTree(CordRep* tree, MethodIdentifier method);
void PrependTree(absl::cord_internal::CordRep* tree);
void GetAppendRegion(char** region, size_t* size, size_t max_length);
void GetAppendRegion(char** region, size_t* size);
@@ -1022,6 +1041,20 @@ inline size_t Cord::InlineRep::size() const {
return is_tree() ? as_tree()->length : inline_size();
}
+inline void Cord::InlineRep::EmplaceTree(CordRep* rep,
+ MethodIdentifier method) {
+ data_.make_tree(rep);
+ CordzInfo::MaybeTrackCord(data_, method);
+}
+
+inline void Cord::InlineRep::SetTree(CordRep* rep,
+ const CordzUpdateScope& scope) {
+ assert(rep);
+ assert(data_.is_tree());
+ data_.set_tree(rep);
+ scope.SetCordRep(rep);
+}
+
inline void Cord::InlineRep::set_tree(absl::cord_internal::CordRep* rep) {
if (rep == nullptr) {
if (ABSL_PREDICT_FALSE(is_profiled())) {