diff options
author | 2021-01-20 12:39:22 -0800 | |
---|---|---|
committer | 2021-01-20 16:43:33 -0500 | |
commit | 22771d471930ce88e1e75d0ca9dd8c65a7b0f895 (patch) | |
tree | 7dcfb410421ef18643a08fc552691b07ace50395 /absl/strings/cord.h | |
parent | b2dcbba18341d75f3fef486b717585cefda0195d (diff) |
Export of internal Abseil changes
--
642ab296a2c9629c44f3f2ce6911cd2488bcf416 by Derek Mauro <dmauro@google.com>:
Remove an obsolete check in CMakeLists.txt
PiperOrigin-RevId: 352852564
--
ce78cb96bcfd162737dbcf35005da3d1d6a3486b by Abseil Team <absl-team@google.com>:
Clarify that the calling *thread* must have locked the mutex in order to unlock
it.
PiperOrigin-RevId: 352801804
--
24e1f5f72756046f5265abf618e951c341f09b8d by Derek Mauro <dmauro@google.com>:
Fixes failing CMake string comparisons
https://cmake.org/cmake/help/latest/policy/CMP0054.html
Fixes #791
PiperOrigin-RevId: 352791054
--
0ac10bc3f4dca2c4c4b51d7b8196a2eaee9537a1 by Abseil Team <absl-team@google.com>:
Introduce CordRepRing class
This change introduces the CordRepRing class that implements all the lower level / internal implementation for upcoming CordRepRing ring buffer support in cord.
PiperOrigin-RevId: 352771994
--
4bd36dda61760785844f0f29f26d90cc18046f75 by Abseil Team <absl-team@google.com>:
Optimize InlineData representation for cord sampling (cordz)
This CL changes InlineData to allow us to store a (future) Cordz Info pointer directly into the inline representation:
- make InlineData a class that provides a public API to set the active union members (tree or chars) and safely access that data.
- change 'tree' and 'profiled' bits to be the 2 least significant bits, allowing us 62 continquous bits for storing a Cordz Info pointer.
PiperOrigin-RevId: 352642411
--
dc55ba71bbce0e6a83e05a453990c51ac3d68426 by Mark Barolak <mbar@google.com>:
Add unit test coverage for the mutating overload of absl::AsciiStrToLower.
PiperOrigin-RevId: 352626006
GitOrigin-RevId: 642ab296a2c9629c44f3f2ce6911cd2488bcf416
Change-Id: I6c5929dd830d3c630e14e7fd5387fc3e25a69100
Diffstat (limited to 'absl/strings/cord.h')
-rw-r--r-- | absl/strings/cord.h | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/absl/strings/cord.h b/absl/strings/cord.h index 7136f034..9d8764a0 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h @@ -665,8 +665,6 @@ class Cord { public: static constexpr unsigned char kMaxInline = cord_internal::kMaxInline; static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), ""); - static constexpr unsigned char kTreeFlag = cord_internal::kTreeFlag; - static constexpr unsigned char kProfiledFlag = cord_internal::kProfiledFlag; constexpr InlineRep() : data_() {} InlineRep(const InlineRep& src); @@ -685,6 +683,7 @@ class Cord { char* set_data(size_t n); // Write data to the result // Returns nullptr if holding bytes absl::cord_internal::CordRep* tree() const; + absl::cord_internal::CordRep* as_tree() const; // Discards old pointer, if any void set_tree(absl::cord_internal::CordRep* rep); // Replaces a tree with a new root. This is faster than set_tree, but it @@ -728,13 +727,13 @@ class Cord { memcpy(&(*dst)[0], &data_, sizeof(data_) - 1); // erase is faster than resize because the logic for memory allocation is // not needed. - dst->erase(tagged_size()); + dst->erase(inline_size()); } // Copies the inline contents into `dst`. Assumes the cord is not empty. void CopyToArray(char* dst) const; - bool is_tree() const { return tagged_size() > kMaxInline; } + bool is_tree() const { return data_.is_tree(); } private: friend class Cord; @@ -745,14 +744,8 @@ class Cord { void ResetToEmpty() { data_ = {}; } - // This uses reinterpret_cast instead of the union to avoid accessing the - // inactive union element. The tagged size is not a common prefix. - void set_tagged_size(char new_tag) { - reinterpret_cast<char*>(&data_)[kMaxInline] = new_tag; - } - char tagged_size() const { - return reinterpret_cast<const char*>(&data_)[kMaxInline]; - } + void set_inline_size(size_t size) { data_.set_inline_size(size); } + size_t inline_size() const { return data_.inline_size(); } cord_internal::InlineData data_; }; @@ -948,35 +941,39 @@ inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) { } inline const char* Cord::InlineRep::data() const { - return is_tree() ? nullptr : data_.as_chars; + return is_tree() ? nullptr : data_.as_chars(); +} + +inline absl::cord_internal::CordRep* Cord::InlineRep::as_tree() const { + assert(data_.is_tree()); + return data_.as_tree(); } inline absl::cord_internal::CordRep* Cord::InlineRep::tree() const { if (is_tree()) { - return data_.as_tree.rep; + return as_tree(); } else { return nullptr; } } -inline bool Cord::InlineRep::empty() const { return tagged_size() == 0; } +inline bool Cord::InlineRep::empty() const { return data_.is_empty(); } inline size_t Cord::InlineRep::size() const { - const char tag = tagged_size(); - if (tag <= kMaxInline) return tag; - return static_cast<size_t>(tree()->length); + return is_tree() ? as_tree()->length : inline_size(); } inline void Cord::InlineRep::set_tree(absl::cord_internal::CordRep* rep) { if (rep == nullptr) { ResetToEmpty(); } else { - bool was_tree = is_tree(); - data_.as_tree = {rep, {}, tagged_size()}; - if (!was_tree) { - // If we were not a tree already, set the tag. - // Otherwise, leave it alone because it might have the profile bit on. - set_tagged_size(kTreeFlag); + if (data_.is_tree()) { + // `data_` already holds a 'tree' value and an optional cordz_info value. + // Replace the tree value only, leaving the cordz_info value unchanged. + data_.set_tree(rep); + } else { + // `data_` contains inlined data: initialize data_ to tree value `rep`. + data_.make_tree(rep); } } } @@ -987,7 +984,7 @@ inline void Cord::InlineRep::replace_tree(absl::cord_internal::CordRep* rep) { set_tree(rep); return; } - data_.as_tree = {rep, {}, tagged_size()}; + data_.set_tree(rep); } inline absl::cord_internal::CordRep* Cord::InlineRep::clear() { @@ -998,9 +995,9 @@ inline absl::cord_internal::CordRep* Cord::InlineRep::clear() { inline void Cord::InlineRep::CopyToArray(char* dst) const { assert(!is_tree()); - size_t n = tagged_size(); + size_t n = inline_size(); assert(n != 0); - cord_internal::SmallMemmove(dst, data_.as_chars, n); + cord_internal::SmallMemmove(dst, data_.as_chars(), n); } constexpr inline Cord::Cord() noexcept {} @@ -1011,11 +1008,9 @@ constexpr Cord::Cord(strings_internal::StringConstant<T>) cord_internal::kMaxInline ? cord_internal::InlineData( strings_internal::StringConstant<T>::value) - : cord_internal::InlineData(cord_internal::AsTree{ + : cord_internal::InlineData( &cord_internal::ConstInitExternalStorage< - strings_internal::StringConstant<T>>::value, - {}, - cord_internal::kTreeFlag})) {} + strings_internal::StringConstant<T>>::value)) {} inline Cord& Cord::operator=(const Cord& x) { contents_ = x.contents_; @@ -1107,12 +1102,12 @@ inline bool Cord::StartsWith(absl::string_view rhs) const { inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) : bytes_remaining_(cord->size()) { - if (cord->empty()) return; if (cord->contents_.is_tree()) { - stack_of_right_children_.push_back(cord->contents_.tree()); + stack_of_right_children_.push_back(cord->contents_.as_tree()); operator++(); } else { - current_chunk_ = absl::string_view(cord->contents_.data(), cord->size()); + current_chunk_ = + absl::string_view(cord->contents_.data(), bytes_remaining_); } } |