diff options
Diffstat (limited to 'absl/strings/internal/cord_rep_ring.cc')
-rw-r--r-- | absl/strings/internal/cord_rep_ring.cc | 118 |
1 files changed, 2 insertions, 116 deletions
diff --git a/absl/strings/internal/cord_rep_ring.cc b/absl/strings/internal/cord_rep_ring.cc index f78c94e1..20a6fc2b 100644 --- a/absl/strings/internal/cord_rep_ring.cc +++ b/absl/strings/internal/cord_rep_ring.cc @@ -26,6 +26,7 @@ #include "absl/base/macros.h" #include "absl/container/inlined_vector.h" #include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_consume.h" #include "absl/strings/internal/cord_rep_flat.h" namespace absl { @@ -49,14 +50,6 @@ inline void CheckCapacity(size_t n, size_t extra) { } } -// Removes a reference from `rep` only. -// Asserts that the refcount after decrement is not zero. -inline bool UnrefNeverOne(CordRep* rep) { - bool result = rep->refcount.Decrement(); - assert(result); - return result; -} - // Creates a flat from the provided string data, allocating up to `extra` // capacity in the returned flat depending on kMaxFlatLength limitations. // Requires `len` to be less or equal to `kMaxFlatLength` @@ -68,40 +61,6 @@ CordRepFlat* CreateFlat(const char* s, size_t n, size_t extra = 0) { // NOLINT return rep; } -// Unrefs the provided `substring`, and returns `substring->child` -// Adds or assumes a reference on `substring->child` -CordRep* ClipSubstring(CordRepSubstring* substring) { - CordRep* child = substring->child; - if (substring->refcount.IsOne()) { - delete substring; - } else { - CordRep::Ref(child); - if (ABSL_PREDICT_FALSE(!substring->refcount.Decrement())) { - UnrefNeverOne(child); - delete substring; - } - } - return child; -} - -// Unrefs the provided `concat`, and returns `{concat->left, concat->right}` -// Adds or assumes a reference on `concat->left` and `concat->right`. -std::pair<CordRep*, CordRep*> ClipConcat(CordRepConcat* concat) { - auto result = std::make_pair(concat->left, concat->right); - if (concat->refcount.IsOne()) { - delete concat; - } else { - CordRep::Ref(result.first); - CordRep::Ref(result.second); - if (ABSL_PREDICT_FALSE(!concat->refcount.Decrement())) { - UnrefNeverOne(result.first); - UnrefNeverOne(result.second); - delete concat; - } - } - return result; -} - // Unrefs the entries in `[head, tail)`. // Requires all entries to be a FLAT or EXTERNAL node. void UnrefEntries(const CordRepRing* rep, index_type head, index_type tail) { @@ -117,79 +76,6 @@ void UnrefEntries(const CordRepRing* rep, index_type head, index_type tail) { }); } -template <typename F> -void Consume(Direction direction, CordRep* rep, F&& fn) { - size_t offset = 0; - size_t length = rep->length; - struct Entry { - CordRep* rep; - size_t offset; - size_t length; - }; - absl::InlinedVector<Entry, 40> stack; - - for (;;) { - if (rep->tag >= FLAT || rep->tag == EXTERNAL || rep->tag == RING) { - fn(rep, offset, length); - if (stack.empty()) return; - - rep = stack.back().rep; - offset = stack.back().offset; - length = stack.back().length; - stack.pop_back(); - } else if (rep->tag == SUBSTRING) { - offset += rep->substring()->start; - rep = ClipSubstring(rep->substring()); - } else if (rep->tag == CONCAT) { - auto res = ClipConcat(rep->concat()); - CordRep* left = res.first; - CordRep* right = res.second; - - if (left->length <= offset) { - // Don't need left node - offset -= left->length; - CordRep::Unref(left); - rep = right; - continue; - } - - size_t length_left = left->length - offset; - if (length_left >= length) { - // Don't need right node - CordRep::Unref(right); - rep = left; - continue; - } - - // Need both nodes - size_t length_right = length - length_left; - if (direction == Direction::kReversed) { - stack.push_back({left, offset, length_left}); - rep = right; - offset = 0; - length = length_right; - } else { - stack.push_back({right, 0, length_right}); - rep = left; - length = length_left; - } - } else { - assert("Valid tag" == nullptr); - return; - } - } -} - -template <typename F> -void Consume(CordRep* rep, F&& fn) { - return Consume(Direction::kForward, rep, std::forward<F>(fn)); -} - -template <typename F> -void RConsume(CordRep* rep, F&& fn) { - return Consume(Direction::kReversed, rep, std::forward<F>(fn)); -} - } // namespace std::ostream& operator<<(std::ostream& s, const CordRepRing& rep) { @@ -581,7 +467,7 @@ CordRepRing* CordRepRing::Append(CordRepRing* rep, CordRep* child) { } CordRepRing* CordRepRing::PrependSlow(CordRepRing* rep, CordRep* child) { - RConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) { + ReverseConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) { if (IsFlatOrExternal(child_arg)) { rep = PrependLeaf(rep, child_arg, offset, len); } else { |