summaryrefslogtreecommitdiff
path: root/absl/strings/cord.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-04-27 09:11:54 -0700
committerGravatar Derek Mauro <dmauro@google.com>2021-04-27 16:35:21 +0000
commita5167f986b82e9a7535ee710e87e53cf4c8ef2a8 (patch)
tree05455a5490740b560cdd69550bd2844ecacd2ee2 /absl/strings/cord.h
parentd96e287417766deddbff2d01b96321288c59491e (diff)
Export of internal Abseil changes
-- f6fbb03bff276e72123e8590519079e87732ae62 by Abseil Team <absl-team@google.com>: Replace static absl::Mutex with SpinLock in absl::Cords to avoid static initializers by absl::Mutex destructors PiperOrigin-RevId: 370694199 -- 654b7d9edfdc24f226990b2b46cbf91451a1d92a by Martijn Vels <mvels@google.com>: Implement global data for CordzInfo in an ODR hardened way This change puts the global data into a global list structure, and stores a reference to the global list in the handle itself. This hardens the implementation against ODR violations where info pointers are crossing dynamic library boundaries which are privately loaded. PiperOrigin-RevId: 370673045 -- 712dba768e66ee2ba85d6010829c617cd2af6ba7 by Martijn Vels <mvels@google.com>: Intrument Cord::operator= for Cordz PiperOrigin-RevId: 370659149 -- c0b347a2289e151b72680269332e264b8fa989c0 by Matt Kulukundis <kfm@google.com>: Fix test guards for ABSL_ATTRIBUTE_RETURNS_NONNULL PiperOrigin-RevId: 370594807 -- c2bedaa3472ef223f907de2604f9b9b58852ec5f by Martijn Vels <mvels@google.com>: Add new Cordz instrumentation on GetAppendRegion. PiperOrigin-RevId: 370587761 -- 84fbfcc852697d509f6094482b86e84743a6b331 by Martijn Vels <mvels@google.com>: Add instrumentation on Cord::Apppend(string_view) PiperOrigin-RevId: 370576590 -- 9e077390b8ca2239e1cb7bfbe1d5a04f2fc11d30 by Abseil Team <absl-team@google.com>: Google-internal changes only. PiperOrigin-RevId: 370558424 -- fb53c149eb2364ea34e3a67235f873866618b8ac by Matt Kulukundis <kfm@google.com>: Update config.h macros with a few useful helpers to simplify version checking PiperOrigin-RevId: 370557684 -- abf8142e99b9ff7e15f6528a357f1005461950b0 by Martijn Vels <mvels@google.com>: clang-format cord PiperOrigin-RevId: 370549371 -- e555985eabe63fcf0e980e9c433dd84caffec191 by Martijn Vels <mvels@google.com>: Add MaybeUntrackCord() function This function is near identical to the old UntrackCord() but allows info to be null, moving the cord.is_profiled() branch into CordzInfo. PiperOrigin-RevId: 370528447 -- 3883538efe4601f7864bda70a50d868bb383c63b by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 370503186 -- a9514b65542fde1bc73584e6f3c1c4b3a05f215f by Derek Mauro <dmauro@google.com>: Add -Winvalid-constexpr to warning options for LLVM PiperOrigin-RevId: 370455171 -- d8a3966de2cf15a2dc28e17e49a3d27d205eca92 by Martijn Vels <mvels@google.com>: Add naive UniqueGenerator<T, kMaxValues, ...> to avoid flakes from dup random values. PiperOrigin-RevId: 370179772 -- 46d0caa1a12b68a5998d4f919e20f0f83b9286f8 by Martijn Vels <mvels@google.com>: Add new Cordz instrumentation on PrependTree. PiperOrigin-RevId: 370138969 GitOrigin-RevId: f6fbb03bff276e72123e8590519079e87732ae62 Change-Id: Ifa4c00a5c7b01198ee367a3253bea6b66612135e
Diffstat (limited to 'absl/strings/cord.h')
-rw-r--r--absl/strings/cord.h54
1 files changed, 44 insertions, 10 deletions
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index dd6c3bca..d5a13b34 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -671,6 +671,7 @@ class Cord {
private:
using CordRep = absl::cord_internal::CordRep;
+ using CordRepFlat = absl::cord_internal::CordRepFlat;
using CordzInfo = cord_internal::CordzInfo;
using CordzUpdateScope = cord_internal::CordzUpdateScope;
using CordzUpdateTracker = cord_internal::CordzUpdateTracker;
@@ -728,12 +729,15 @@ class Cord {
// Returns non-null iff was holding a pointer
absl::cord_internal::CordRep* clear();
// Converts to pointer if necessary.
- absl::cord_internal::CordRep* force_tree(size_t extra_hint);
void reduce_size(size_t n); // REQUIRES: holding data
void remove_prefix(size_t n); // REQUIRES: holding data
- void AppendArray(const char* src_data, size_t src_size);
+ void AppendArray(absl::string_view src, MethodIdentifier method);
absl::string_view FindFlatStartPiece() const;
+ // Creates a CordRepFlat instance from the current inlined data with `extra'
+ // bytes of desired additional capacity.
+ CordRepFlat* MakeFlatWithExtraCapacity(size_t extra);
+
// 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
@@ -747,12 +751,22 @@ class Cord {
// value to a non-inlined (tree / ring) value.
void EmplaceTree(CordRep* rep, MethodIdentifier method);
+ // Commits the change of a newly created, or updated `rep` root value into
+ // this cord. `old_rep` indicates the old (inlined or tree) value of the
+ // cord, and determines if the commit invokes SetTree() or EmplaceTree().
+ void CommitTree(const CordRep* old_rep, CordRep* rep,
+ const CordzUpdateScope& scope, 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);
+ void PrependTreeToInlined(CordRep* tree, MethodIdentifier method);
+ void PrependTreeToTree(CordRep* tree, MethodIdentifier method);
+ void PrependTree(CordRep* tree, MethodIdentifier method);
+
+ template <bool has_length>
+ void GetAppendRegion(char** region, size_t* size, size_t length);
+
bool IsSame(const InlineRep& other) const {
return memcmp(&data_, &other.data_, sizeof(data_)) == 0;
}
@@ -1041,6 +1055,16 @@ inline size_t Cord::InlineRep::size() const {
return is_tree() ? as_tree()->length : inline_size();
}
+inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity(
+ size_t extra) {
+ static_assert(cord_internal::kMinFlatLength >= sizeof(data_), "");
+ size_t len = data_.inline_size();
+ auto* result = CordRepFlat::New(len + extra);
+ result->length = len;
+ memcpy(result->Data(), data_.as_chars(), sizeof(data_));
+ return result;
+}
+
inline void Cord::InlineRep::EmplaceTree(CordRep* rep,
MethodIdentifier method) {
data_.make_tree(rep);
@@ -1055,10 +1079,20 @@ inline void Cord::InlineRep::SetTree(CordRep* rep,
scope.SetCordRep(rep);
}
+inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep,
+ const CordzUpdateScope& scope,
+ MethodIdentifier method) {
+ if (old_rep) {
+ SetTree(rep, scope);
+ } else {
+ EmplaceTree(rep, method);
+ }
+}
+
inline void Cord::InlineRep::set_tree(absl::cord_internal::CordRep* rep) {
if (rep == nullptr) {
- if (ABSL_PREDICT_FALSE(is_profiled())) {
- absl::cord_internal::CordzInfo::UntrackCord(cordz_info());
+ if (data_.is_tree()) {
+ CordzInfo::MaybeUntrackCord(data_.cordz_info());
}
ResetToEmpty();
} else {
@@ -1086,8 +1120,8 @@ inline void Cord::InlineRep::replace_tree(absl::cord_internal::CordRep* rep) {
}
inline absl::cord_internal::CordRep* Cord::InlineRep::clear() {
- if (ABSL_PREDICT_FALSE(is_profiled())) {
- absl::cord_internal::CordzInfo::UntrackCord(cordz_info());
+ if (is_tree()) {
+ CordzInfo::MaybeUntrackCord(cordz_info());
}
absl::cord_internal::CordRep* result = tree();
ResetToEmpty();
@@ -1180,7 +1214,7 @@ inline absl::string_view Cord::Flatten() {
}
inline void Cord::Append(absl::string_view src) {
- contents_.AppendArray(src.data(), src.size());
+ contents_.AppendArray(src, CordzUpdateTracker::kAppendString);
}
extern template void Cord::Append(std::string&& src);