summaryrefslogtreecommitdiff
path: root/absl/strings
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-09-01 13:48:23 -0700
committerGravatar dinord <dinor@google.com>2021-09-01 21:37:10 +0000
commit4bb9e39c88854dbf466688177257d11810719853 (patch)
tree1f1630117478fc361c3fd4de49bf4c5d84fbb54f /absl/strings
parent665ac5b425cea2462bf85dcbb56dd68ec19ad00f (diff)
Export of internal Abseil changes
-- f73e17cb24f7878933fc100bd9bfc39fce190b64 by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 394306402 -- 3d3eeffa4e37f63aa50fec1b90858043b40fe377 by Abseil Team <absl-team@google.com>: Release a few more absl::Cord unit tests that were accidentally omitted from the OSS release before. PiperOrigin-RevId: 394016464 -- 8a77a8eb93d021aadd8fdf43e219bf35328001ad by CJ Johnson <johnsoncj@google.com>: Fix typo in identifier PiperOrigin-RevId: 394000560 -- d87206c7c8e045b03d74b91e47ef3db0eb47a17b by Derek Mauro <dmauro@google.com>: Fix typo: RandenHwAes PiperOrigin-RevId: 393879427 -- 980a3402eea77b0c77fb20dd124203002ff791ba by Derek Mauro <dmauro@google.com>: Adds macros `ABSL_LTS_RELEASE_VERSION` and `ABSL_LTS_RELEASE_PATCH_LEVEL` to allow projects to detect if an LTS version is being used. Fixes #1006 PiperOrigin-RevId: 393807178 -- aecc7ed34de718c64733dab76621eacb5af9af5f by CJ Johnson <johnsoncj@google.com>: Change `alloc` to `allocator` to match the fact that other identifiers are full words PiperOrigin-RevId: 393794869 -- ad754bbcf7b78f5d51ed5f39193ac3159429b2b4 by Derek Mauro <dmauro@google.com>: Remove self-include of cord_rep_btree.h PiperOrigin-RevId: 393792085 -- f8e937a0d8fe26400560754f3596e3c21bb6d0d7 by Abseil Team <absl-team@google.com>: Fix trivial typo in comment. PiperOrigin-RevId: 393770527 -- 7a58ca5d708038d222c6a2b6ff5076b4ceffd370 by Tomas Dzetkulic <dzetkulic@google.com>: Update Cord::AppendArray resize policy. PiperOrigin-RevId: 393362184 -- 316050d171190d9d6312cadf88b1cc2db2d1caa7 by Abseil Team <absl-team@google.com>: Add a new top level profiling/ directory to the Abseil library PiperOrigin-RevId: 393358109 -- 0dbb8e10f7fa4a7ac74e12b178e936a67b266c51 by CJ Johnson <johnsoncj@google.com>: Switch to the more common enable_if pattern of ` = 0` in InlinedVector PiperOrigin-RevId: 393301549 -- 136d3068ce33b50ac820e8bd01395a7164d5181f by Abseil Team <absl-team@google.com>: Clean up typedefs in internal/inlined_vector.h PiperOrigin-RevId: 393181754 GitOrigin-RevId: f73e17cb24f7878933fc100bd9bfc39fce190b64 Change-Id: I0c4cd4d71d97bd1bf651701b6302ea3d9ac59b66
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/cord.cc11
-rw-r--r--absl/strings/cord_test.cc53
-rw-r--r--absl/strings/internal/cord_rep_btree.h1
-rw-r--r--absl/strings/internal/str_format/bind.h2
4 files changed, 58 insertions, 9 deletions
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index e9d72fa8..115705a2 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -689,13 +689,10 @@ void Cord::InlineRep::AppendArray(absl::string_view src,
return;
}
- // Note: we don't concern ourselves if src aliases data stored in the
- // inlined data of 'this', as we update the InlineData only at the end.
- // We are going from an inline size to beyond inline size. Make the new size
- // either double the inlined size, or the added size + 10%.
- const size_t size1 = inline_length * 2 + src.size();
- const size_t size2 = inline_length + src.size() / 10;
- rep = CordRepFlat::New(std::max<size_t>(size1, size2));
+ // Allocate flat to be a perfect fit on first append exceeding inlined size.
+ // Subsequent growth will use amortized growth until we reach maximum flat
+ // size.
+ rep = CordRepFlat::New(inline_length + src.size());
appended = std::min(src.size(), rep->flat()->Capacity() - inline_length);
memcpy(rep->flat()->Data(), data_.as_chars(), inline_length);
memcpy(rep->flat()->Data() + inline_length, src.data(), appended);
diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc
index d0296338..06a7bd6c 100644
--- a/absl/strings/cord_test.cc
+++ b/absl/strings/cord_test.cc
@@ -1385,6 +1385,59 @@ TEST_P(CordTest, DiabolicalGrowth) {
cord.EstimatedMemoryUsage());
}
+// The following tests check support for >4GB cords in 64-bit binaries, and
+// 2GB-4GB cords in 32-bit binaries. This function returns the large cord size
+// that's appropriate for the binary.
+
+// Construct a huge cord with the specified valid prefix.
+static absl::Cord MakeHuge(absl::string_view prefix) {
+ absl::Cord cord;
+ if (sizeof(size_t) > 4) {
+ // In 64-bit binaries, test 64-bit Cord support.
+ const size_t size =
+ static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 314;
+ cord.Append(absl::MakeCordFromExternal(
+ absl::string_view(prefix.data(), size),
+ [](absl::string_view s) { DoNothing(s, nullptr); }));
+ } else {
+ // Cords are limited to 32-bit lengths in 32-bit binaries. The following
+ // tests check for use of "signed int" to represent Cord length/offset.
+ // However absl::string_view does not allow lengths >= (1u<<31), so we need
+ // to append in two parts;
+ const size_t s1 = (1u << 31) - 1;
+ // For shorter cord, `Append` copies the data rather than allocating a new
+ // node. The threshold is currently set to 511, so `s2` needs to be bigger
+ // to not trigger the copy.
+ const size_t s2 = 600;
+ cord.Append(absl::MakeCordFromExternal(
+ absl::string_view(prefix.data(), s1),
+ [](absl::string_view s) { DoNothing(s, nullptr); }));
+ cord.Append(absl::MakeCordFromExternal(
+ absl::string_view("", s2),
+ [](absl::string_view s) { DoNothing(s, nullptr); }));
+ }
+ return cord;
+}
+
+TEST_P(CordTest, HugeCord) {
+ absl::Cord cord = MakeHuge("huge cord");
+ EXPECT_LE(cord.size(), cord.EstimatedMemoryUsage());
+ EXPECT_GE(cord.size() + 100, cord.EstimatedMemoryUsage());
+}
+
+// Tests that Append() works ok when handed a self reference
+TEST_P(CordTest, AppendSelf) {
+ // We run the test until data is ~16K
+ // This guarantees it covers small, medium and large data.
+ std::string control_data = "Abc";
+ absl::Cord data(control_data);
+ while (control_data.length() < 0x4000) {
+ data.Append(data);
+ control_data.append(control_data);
+ ASSERT_EQ(control_data, data);
+ }
+}
+
TEST_P(CordTest, MakeFragmentedCordFromInitializerList) {
absl::Cord fragmented =
absl::MakeFragmentedCord({"A ", "fragmented ", "Cord"});
diff --git a/absl/strings/internal/cord_rep_btree.h b/absl/strings/internal/cord_rep_btree.h
index 303f4580..bbaa7934 100644
--- a/absl/strings/internal/cord_rep_btree.h
+++ b/absl/strings/internal/cord_rep_btree.h
@@ -23,7 +23,6 @@
#include "absl/base/internal/raw_logging.h"
#include "absl/base/optimization.h"
#include "absl/strings/internal/cord_internal.h"
-#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h
index 267cc0ef..b26cff66 100644
--- a/absl/strings/internal/str_format/bind.h
+++ b/absl/strings/internal/str_format/bind.h
@@ -100,7 +100,7 @@ class FormatSpecTemplate
// We use the 'unavailable' attribute to give a better compiler error than
// just 'method is deleted'.
// To avoid checking the format twice, we just check that the format is
- // constexpr. If is it valid, then the overload below will kick in.
+ // constexpr. If it is valid, then the overload below will kick in.
// We add the template here to make this overload have lower priority.
template <typename = void>
FormatSpecTemplate(const char* s) // NOLINT