|
|
|
// Copyright 2020 The Abseil Authors.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#include "absl/strings/cord.h"
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <climits>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <iterator>
|
|
|
|
#include <map>
|
|
|
|
#include <numeric>
|
|
|
|
#include <random>
|
|
|
|
#include <sstream>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "gmock/gmock.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "absl/base/config.h"
|
|
|
|
#include "absl/base/internal/endian.h"
|
|
|
|
#include "absl/base/internal/raw_logging.h"
|
|
|
|
#include "absl/base/macros.h"
|
|
|
|
#include "absl/container/fixed_array.h"
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
#include "absl/hash/hash.h"
|
Export of internal Abseil changes
--
f49e405201d2ffd5955503fa8ad0f08ec0cdfb2b by Martijn Vels <mvels@google.com>:
Add common [container.requirements] type definitions to `CharRange` and `ChunkRange`
The presence of these allow these range classes to be used in various utility functions which require some minimum type of container. For example, this change allows tests to use `EXPECT_THAT(cord.Chunks(), ElementsAre(...))`
PiperOrigin-RevId: 406941278
--
0c195f073632e21d9a4bce158047b2ba8551c2d1 by Evan Brown <ezb@google.com>:
Use explicit exponential growth in SubstituteAndAppendArray.
PiperOrigin-RevId: 406931952
--
afb043bccd809a55cab78abadb7548a057d9eda0 by Jorg Brown <jorg@google.com>:
Use longer var names in macro to avoid clang-tidy warning
PiperOrigin-RevId: 406930978
--
80397e2604e6b3d929a34742c3a32581b34d3ac4 by Martijn Vels <mvels@google.com>:
Add future kAppendBuffer and kPrependBuffer API trackers for Cordz sampling
PiperOrigin-RevId: 406912759
--
e910ce919ef83933f08a690e8b7325c7cc5b6d5d by Martijn Vels <mvels@google.com>:
Implement Prepend(string_view) in terms of PrependArray(string_view, MethodIdentifier).
PiperOrigin-RevId: 406891665
--
c9cff43d4c0568ed01f2fca0f6ef038ae03112b5 by Martijn Vels <mvels@google.com>:
Add 'Rebuild' logic to CordRepBtree
There are btree hostile scenarios where an application could perform repeated split/insert/merge operations on a cord leading to a tree exceeding the maximum height. While this should be rare in practice, this change adds a Rebuild() method that will rebuild a tree with a 100% fill factor, and we will invoke this rebuild when a tree exceeds the maximum height. This basically follows the similar 'balance' logic in Concat trees (although the latter is common in Concat uses)
PiperOrigin-RevId: 406875739
--
5b2b8fb88f1ebfdc1c670088152da2cb2ea4c376 by Martijn Vels <mvels@google.com>:
Add 'in place' enabled RemoveSuffix
An in-place RemoveSuffix is more efficient than SubTree() as it can directly modify privately owned nodes and flats allowing easy re-use of free capacity in right-most flats that may turn into Substring edges when using SubTree.
PiperOrigin-RevId: 406431230
--
f09903c0a3d7344f59aaf1380a16ea10829217d4 by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 406430373
--
9957af575c33bb18dc170572a4ee8cc5901df6b2 by Greg Falcon <gfalcon@google.com>:
Initial groundwork to allow storing checksum data inside CordRep instances.
This uses a RefcountAndFlags bit that was reserved for this purpose, and will be leveraged in a follow-up change to allow attaching checksums to a Cord's value.
This change splits RefcountAndFlags::IsOne() into two distinct operations:
* IsOne(): This returns true when the associated CordRep is not shared with other threads. This is useful for functions that consume CordRep instances; for example, code that consumes an unshared CordRep can assume ownership of its children without modifying those refcounts.
* IsMutable(): This returns true when the associated CordRep reference is not shared with other threads, *and* does not store an associated checksum value. This is useful for functions that modify a CordRep's contents: code may modify the bytes of a mutable-unshared CordRep without fear of races with other threads, or of invalidating a stored checksum.
The tricky part of this CL is ensuring that the correct choice between IsMutable() and IsOne() was made at each point. An incorrect application of IsOne() could lead to correctness bugs in the future. Code conditioned on IsOne() may delete the CordRep in question, or assume ownership of its children, but must not modify the CordRep's data without explicitly adjusting the CRC.
PiperOrigin-RevId: 406191103
--
686544814079e5ab6d4593cca0c068b510be400a by Martijn Vels <mvels@google.com>:
Reduce the size in the LargeString test when running with Sanitizers
PiperOrigin-RevId: 406186945
--
735b4490bdb695c35731f06ce4b8de14ce2be6ed by Alex Strelnikov <strel@google.com>:
Release absl::SimpleHexAtoi.
PiperOrigin-RevId: 406143188
GitOrigin-RevId: f49e405201d2ffd5955503fa8ad0f08ec0cdfb2b
Change-Id: Ic6527ac40fa03ea02ca813e8bb7868a219544de4
3 years ago
|
|
|
#include "absl/random/random.h"
|
|
|
|
#include "absl/strings/cord_test_helpers.h"
|
|
|
|
#include "absl/strings/cordz_test_helpers.h"
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
#include "absl/strings/match.h"
|
|
|
|
#include "absl/strings/str_cat.h"
|
|
|
|
#include "absl/strings/str_format.h"
|
|
|
|
#include "absl/strings/string_view.h"
|
|
|
|
|
|
|
|
// convenience local constants
|
|
|
|
static constexpr auto FLAT = absl::cord_internal::FLAT;
|
|
|
|
static constexpr auto MAX_FLAT_TAG = absl::cord_internal::MAX_FLAT_TAG;
|
|
|
|
|
|
|
|
typedef std::mt19937_64 RandomEngine;
|
|
|
|
|
|
|
|
using absl::cord_internal::CordRep;
|
|
|
|
using absl::cord_internal::CordRepBtree;
|
|
|
|
using absl::cord_internal::CordRepConcat;
|
|
|
|
using absl::cord_internal::CordRepCrc;
|
|
|
|
using absl::cord_internal::CordRepExternal;
|
|
|
|
using absl::cord_internal::CordRepFlat;
|
|
|
|
using absl::cord_internal::CordRepSubstring;
|
|
|
|
using absl::cord_internal::CordzUpdateTracker;
|
|
|
|
using absl::cord_internal::kFlatOverhead;
|
|
|
|
using absl::cord_internal::kMaxFlatLength;
|
|
|
|
|
|
|
|
static std::string RandomLowercaseString(RandomEngine* rng);
|
|
|
|
static std::string RandomLowercaseString(RandomEngine* rng, size_t length);
|
|
|
|
|
|
|
|
static int GetUniformRandomUpTo(RandomEngine* rng, int upper_bound) {
|
|
|
|
if (upper_bound > 0) {
|
|
|
|
std::uniform_int_distribution<int> uniform(0, upper_bound - 1);
|
|
|
|
return uniform(*rng);
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t GetUniformRandomUpTo(RandomEngine* rng, size_t upper_bound) {
|
|
|
|
if (upper_bound > 0) {
|
|
|
|
std::uniform_int_distribution<size_t> uniform(0, upper_bound - 1);
|
|
|
|
return uniform(*rng);
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int32_t GenerateSkewedRandom(RandomEngine* rng, int max_log) {
|
|
|
|
const uint32_t base = (*rng)() % (max_log + 1);
|
|
|
|
const uint32_t mask = ((base < 32) ? (1u << base) : 0u) - 1u;
|
|
|
|
return (*rng)() & mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string RandomLowercaseString(RandomEngine* rng) {
|
|
|
|
int length;
|
|
|
|
std::bernoulli_distribution one_in_1k(0.001);
|
|
|
|
std::bernoulli_distribution one_in_10k(0.0001);
|
|
|
|
// With low probability, make a large fragment
|
|
|
|
if (one_in_10k(*rng)) {
|
|
|
|
length = GetUniformRandomUpTo(rng, 1048576);
|
|
|
|
} else if (one_in_1k(*rng)) {
|
|
|
|
length = GetUniformRandomUpTo(rng, 10000);
|
|
|
|
} else {
|
|
|
|
length = GenerateSkewedRandom(rng, 10);
|
|
|
|
}
|
|
|
|
return RandomLowercaseString(rng, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string RandomLowercaseString(RandomEngine* rng, size_t length) {
|
|
|
|
std::string result(length, '\0');
|
|
|
|
std::uniform_int_distribution<int> chars('a', 'z');
|
|
|
|
std::generate(result.begin(), result.end(),
|
|
|
|
[&]() { return static_cast<char>(chars(*rng)); });
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DoNothing(absl::string_view /* data */, void* /* arg */) {}
|
|
|
|
|
|
|
|
static void DeleteExternalString(absl::string_view data, void* arg) {
|
|
|
|
std::string* s = reinterpret_cast<std::string*>(arg);
|
|
|
|
EXPECT_EQ(data, *s);
|
|
|
|
delete s;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add "s" to *dst via `MakeCordFromExternal`
|
|
|
|
static void AddExternalMemory(absl::string_view s, absl::Cord* dst) {
|
|
|
|
std::string* str = new std::string(s.data(), s.size());
|
|
|
|
dst->Append(absl::MakeCordFromExternal(*str, [str](absl::string_view data) {
|
|
|
|
DeleteExternalString(data, str);
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DumpGrowth() {
|
|
|
|
absl::Cord str;
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
char c = 'a' + i % 26;
|
|
|
|
str.Append(absl::string_view(&c, 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make a Cord with some number of fragments. Return the size (in bytes)
|
|
|
|
// of the smallest fragment.
|
|
|
|
static size_t AppendWithFragments(const std::string& s, RandomEngine* rng,
|
|
|
|
absl::Cord* cord) {
|
|
|
|
size_t j = 0;
|
|
|
|
const size_t max_size = s.size() / 5; // Make approx. 10 fragments
|
|
|
|
size_t min_size = max_size; // size of smallest fragment
|
|
|
|
while (j < s.size()) {
|
|
|
|
size_t N = 1 + GetUniformRandomUpTo(rng, max_size);
|
|
|
|
if (N > (s.size() - j)) {
|
|
|
|
N = s.size() - j;
|
|
|
|
}
|
|
|
|
if (N < min_size) {
|
|
|
|
min_size = N;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::bernoulli_distribution coin_flip(0.5);
|
|
|
|
if (coin_flip(*rng)) {
|
|
|
|
// Grow by adding an external-memory.
|
|
|
|
AddExternalMemory(absl::string_view(s.data() + j, N), cord);
|
|
|
|
} else {
|
|
|
|
cord->Append(absl::string_view(s.data() + j, N));
|
|
|
|
}
|
|
|
|
j += N;
|
|
|
|
}
|
|
|
|
return min_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add an external memory that contains the specified std::string to cord
|
|
|
|
static void AddNewStringBlock(const std::string& str, absl::Cord* dst) {
|
|
|
|
char* data = new char[str.size()];
|
|
|
|
memcpy(data, str.data(), str.size());
|
|
|
|
dst->Append(absl::MakeCordFromExternal(
|
|
|
|
absl::string_view(data, str.size()),
|
|
|
|
[](absl::string_view s) { delete[] s.data(); }));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make a Cord out of many different types of nodes.
|
|
|
|
static absl::Cord MakeComposite() {
|
|
|
|
absl::Cord cord;
|
|
|
|
cord.Append("the");
|
|
|
|
AddExternalMemory(" quick brown", &cord);
|
|
|
|
AddExternalMemory(" fox jumped", &cord);
|
|
|
|
|
|
|
|
absl::Cord full(" over");
|
|
|
|
AddExternalMemory(" the lazy", &full);
|
|
|
|
AddNewStringBlock(" dog slept the whole day away", &full);
|
|
|
|
absl::Cord substring = full.Subcord(0, 18);
|
|
|
|
|
|
|
|
// Make substring long enough to defeat the copying fast path in Append.
|
|
|
|
substring.Append(std::string(1000, '.'));
|
|
|
|
cord.Append(substring);
|
|
|
|
cord = cord.Subcord(0, cord.size() - 998); // Remove most of extra junk
|
|
|
|
|
|
|
|
return cord;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace absl {
|
|
|
|
ABSL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
class CordTestPeer {
|
|
|
|
public:
|
|
|
|
static void ForEachChunk(
|
|
|
|
const Cord& c, absl::FunctionRef<void(absl::string_view)> callback) {
|
|
|
|
c.ForEachChunk(callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool IsTree(const Cord& c) { return c.contents_.is_tree(); }
|
|
|
|
static CordRep* Tree(const Cord& c) { return c.contents_.tree(); }
|
|
|
|
|
|
|
|
static cord_internal::CordzInfo* GetCordzInfo(const Cord& c) {
|
|
|
|
return c.contents_.cordz_info();
|
|
|
|
}
|
|
|
|
|
|
|
|
static Cord MakeSubstring(Cord src, size_t offset, size_t length) {
|
Export of internal Abseil changes
--
60b8e77be4bab1bbd3b4c3b70054879229634511 by Derek Mauro <dmauro@google.com>:
Use _MSVC_LANG for some C++ dialect checks since MSVC doesn't
set __cplusplus accurately by default.
https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
See GitHub #722.
PiperOrigin-RevId: 371362181
--
5d736accdff04db0e722f377c0d79f2d3ed53263 by Martijn Vels <mvels@google.com>:
Fix the estimated memory size for CordRepExternal
PiperOrigin-RevId: 371350380
--
eaaa1d8a167aeca67a2aa3a098a2b61a9d72172f by Martijn Vels <mvels@google.com>:
Remove flakes by not enforcing re-allocated pointers do never match original
Tests that do multiple updates could end up with the original allocated pointer on a 2nd resize, so the 'EqIfPrivate' should not assume that if we do 'not' have the capacity that all following relocations will never match the original. We only care about 'pointer unchanged if private and there is capacity', trying to establish 'pointer changed at some point due to re-allocation; is pointless.
PiperOrigin-RevId: 371338965
--
d1837bee6bade1902b095c1cbf64231668bb84c5 by Martijn Vels <mvels@google.com>:
Undo inline of small data copy in cord
This leads to a performance regression as the code is not inlined (absent hard FDO inputs), and there are no suitable tail call options.
PiperOrigin-RevId: 371332332
--
06dc64b833069efc7d18b11df607c8c22be690da by Martijn Vels <mvels@google.com>:
Add final instrumentation for Cordz and remove 'old' cordz logic.
This change instruments the last cord function for cordz. It removes the 'old' functions: set_tree, replace_tree, UpdateCordzStatistics and RecordMetrics.
PiperOrigin-RevId: 371219909
--
a5e0be538579c603052feec03e6d9910c43ea787 by Martijn Vels <mvels@google.com>:
Extend the life of CordRep* if inside a snapshot
If a snapshot (potentially) includes the current CordzInfo, we need to extent the lifetime of the CordRep*, as the snapshot 'point in time' observation of the cord should ideally be preserved.
PiperOrigin-RevId: 371146151
--
74d77a89774cd6c8ecdeebee0193b294a39383d6 by Martijn Vels <mvels@google.com>:
Instrument std::string consuming methods: ctor, operator=, Append and Prepend
This change moves the 'steal into CordRep' logic into a separate function so we can use it directly in the ctor, operator assign and append and prepend, allowing Cordz instrumentation with the proper method attributes.
The assign operator is implemented in AssignLargeString leaving the dispatch inlined in cord.h (which as a side effects also allows clean tail calls in the AssignLargeString method)
PiperOrigin-RevId: 371094756
--
b39effc45266b7ce2e7f96caa3b16cb6e3acc2dd by Martijn Vels <mvels@google.com>:
Add Cordz instrumentation to CordReader
PiperOrigin-RevId: 370990181
GitOrigin-RevId: 60b8e77be4bab1bbd3b4c3b70054879229634511
Change-Id: I96af62e6f1a643e8b1228ae01e6c84e33706bb05
4 years ago
|
|
|
ABSL_RAW_CHECK(src.contents_.is_tree(), "Can not be inlined");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
ABSL_RAW_CHECK(src.ExpectedChecksum() == absl::nullopt,
|
|
|
|
"Can not be hardened");
|
Export of internal Abseil changes
--
60b8e77be4bab1bbd3b4c3b70054879229634511 by Derek Mauro <dmauro@google.com>:
Use _MSVC_LANG for some C++ dialect checks since MSVC doesn't
set __cplusplus accurately by default.
https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
See GitHub #722.
PiperOrigin-RevId: 371362181
--
5d736accdff04db0e722f377c0d79f2d3ed53263 by Martijn Vels <mvels@google.com>:
Fix the estimated memory size for CordRepExternal
PiperOrigin-RevId: 371350380
--
eaaa1d8a167aeca67a2aa3a098a2b61a9d72172f by Martijn Vels <mvels@google.com>:
Remove flakes by not enforcing re-allocated pointers do never match original
Tests that do multiple updates could end up with the original allocated pointer on a 2nd resize, so the 'EqIfPrivate' should not assume that if we do 'not' have the capacity that all following relocations will never match the original. We only care about 'pointer unchanged if private and there is capacity', trying to establish 'pointer changed at some point due to re-allocation; is pointless.
PiperOrigin-RevId: 371338965
--
d1837bee6bade1902b095c1cbf64231668bb84c5 by Martijn Vels <mvels@google.com>:
Undo inline of small data copy in cord
This leads to a performance regression as the code is not inlined (absent hard FDO inputs), and there are no suitable tail call options.
PiperOrigin-RevId: 371332332
--
06dc64b833069efc7d18b11df607c8c22be690da by Martijn Vels <mvels@google.com>:
Add final instrumentation for Cordz and remove 'old' cordz logic.
This change instruments the last cord function for cordz. It removes the 'old' functions: set_tree, replace_tree, UpdateCordzStatistics and RecordMetrics.
PiperOrigin-RevId: 371219909
--
a5e0be538579c603052feec03e6d9910c43ea787 by Martijn Vels <mvels@google.com>:
Extend the life of CordRep* if inside a snapshot
If a snapshot (potentially) includes the current CordzInfo, we need to extent the lifetime of the CordRep*, as the snapshot 'point in time' observation of the cord should ideally be preserved.
PiperOrigin-RevId: 371146151
--
74d77a89774cd6c8ecdeebee0193b294a39383d6 by Martijn Vels <mvels@google.com>:
Instrument std::string consuming methods: ctor, operator=, Append and Prepend
This change moves the 'steal into CordRep' logic into a separate function so we can use it directly in the ctor, operator assign and append and prepend, allowing Cordz instrumentation with the proper method attributes.
The assign operator is implemented in AssignLargeString leaving the dispatch inlined in cord.h (which as a side effects also allows clean tail calls in the AssignLargeString method)
PiperOrigin-RevId: 371094756
--
b39effc45266b7ce2e7f96caa3b16cb6e3acc2dd by Martijn Vels <mvels@google.com>:
Add Cordz instrumentation to CordReader
PiperOrigin-RevId: 370990181
GitOrigin-RevId: 60b8e77be4bab1bbd3b4c3b70054879229634511
Change-Id: I96af62e6f1a643e8b1228ae01e6c84e33706bb05
4 years ago
|
|
|
Cord cord;
|
|
|
|
auto* tree = cord_internal::SkipCrcNode(src.contents_.tree());
|
|
|
|
auto* rep = CordRepSubstring::Create(CordRep::Ref(tree), offset, length);
|
|
|
|
cord.contents_.EmplaceTree(rep, CordzUpdateTracker::kSubCord);
|
|
|
|
return cord;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
ABSL_NAMESPACE_END
|
|
|
|
} // namespace absl
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
// The CordTest fixture runs all tests with and without Cord Btree enabled,
|
|
|
|
// and with our without expected CRCs being set on the subject Cords.
|
|
|
|
class CordTest : public testing::TestWithParam<int> {
|
|
|
|
public:
|
|
|
|
// Returns true if test is running with btree enabled.
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
bool UseCrc() const { return GetParam() == 2 || GetParam() == 3; }
|
|
|
|
void MaybeHarden(absl::Cord& c) {
|
|
|
|
if (UseCrc()) {
|
|
|
|
c.SetExpectedChecksum(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
absl::Cord MaybeHardened(absl::Cord c) {
|
|
|
|
MaybeHarden(c);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns human readable string representation of the test parameter.
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
static std::string ToString(testing::TestParamInfo<int> param) {
|
|
|
|
switch (param.param) {
|
|
|
|
case 0:
|
|
|
|
return "Btree";
|
|
|
|
case 1:
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
return "BtreeHardened";
|
|
|
|
default:
|
|
|
|
assert(false);
|
|
|
|
return "???";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_SUITE_P(WithParam, CordTest, testing::Values(0, 1),
|
|
|
|
CordTest::ToString);
|
|
|
|
|
|
|
|
TEST(CordRepFlat, AllFlatCapacities) {
|
|
|
|
// Explicitly and redundantly assert built-in min/max limits
|
|
|
|
static_assert(absl::cord_internal::kFlatOverhead < 32, "");
|
|
|
|
static_assert(absl::cord_internal::kMinFlatSize == 32, "");
|
|
|
|
static_assert(absl::cord_internal::kMaxLargeFlatSize == 256 << 10, "");
|
|
|
|
EXPECT_EQ(absl::cord_internal::TagToAllocatedSize(FLAT), 32);
|
|
|
|
EXPECT_EQ(absl::cord_internal::TagToAllocatedSize(MAX_FLAT_TAG), 256 << 10);
|
|
|
|
|
|
|
|
// Verify all tags to map perfectly back and forth, and
|
|
|
|
// that sizes are monotonically increasing.
|
|
|
|
size_t last_size = 0;
|
|
|
|
for (int tag = FLAT; tag <= MAX_FLAT_TAG; ++tag) {
|
|
|
|
size_t size = absl::cord_internal::TagToAllocatedSize(tag);
|
|
|
|
ASSERT_GT(size, last_size);
|
|
|
|
ASSERT_EQ(absl::cord_internal::TagToAllocatedSize(tag), size);
|
|
|
|
last_size = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
// All flat size from 32 - 512 are 8 byte granularity
|
|
|
|
for (size_t size = 32; size <= 512; size += 8) {
|
|
|
|
ASSERT_EQ(absl::cord_internal::RoundUpForTag(size), size);
|
|
|
|
uint8_t tag = absl::cord_internal::AllocatedSizeToTag(size);
|
|
|
|
ASSERT_EQ(absl::cord_internal::TagToAllocatedSize(tag), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
// All flat sizes from 512 - 8192 are 64 byte granularity
|
|
|
|
for (size_t size = 512; size <= 8192; size += 64) {
|
|
|
|
ASSERT_EQ(absl::cord_internal::RoundUpForTag(size), size);
|
|
|
|
uint8_t tag = absl::cord_internal::AllocatedSizeToTag(size);
|
|
|
|
ASSERT_EQ(absl::cord_internal::TagToAllocatedSize(tag), size);
|
|
|
|
}
|
|
|
|
|
|
|
|
// All flat sizes from 8KB to 256KB are 4KB granularity
|
|
|
|
for (size_t size = 8192; size <= 256 * 1024; size += 4 * 1024) {
|
|
|
|
ASSERT_EQ(absl::cord_internal::RoundUpForTag(size), size);
|
|
|
|
uint8_t tag = absl::cord_internal::AllocatedSizeToTag(size);
|
|
|
|
ASSERT_EQ(absl::cord_internal::TagToAllocatedSize(tag), size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordRepFlat, MaxFlatSize) {
|
|
|
|
CordRepFlat* flat = CordRepFlat::New(kMaxFlatLength);
|
|
|
|
EXPECT_EQ(flat->Capacity(), kMaxFlatLength);
|
|
|
|
CordRep::Unref(flat);
|
|
|
|
|
|
|
|
flat = CordRepFlat::New(kMaxFlatLength * 4);
|
|
|
|
EXPECT_EQ(flat->Capacity(), kMaxFlatLength);
|
|
|
|
CordRep::Unref(flat);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordRepFlat, MaxLargeFlatSize) {
|
|
|
|
const size_t size = 256 * 1024 - kFlatOverhead;
|
|
|
|
CordRepFlat* flat = CordRepFlat::New(CordRepFlat::Large(), size);
|
|
|
|
EXPECT_GE(flat->Capacity(), size);
|
|
|
|
CordRep::Unref(flat);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordRepFlat, AllFlatSizes) {
|
|
|
|
const size_t kMaxSize = 256 * 1024;
|
|
|
|
for (size_t size = 32; size <= kMaxSize; size *=2) {
|
|
|
|
const size_t length = size - kFlatOverhead - 1;
|
|
|
|
CordRepFlat* flat = CordRepFlat::New(CordRepFlat::Large(), length);
|
|
|
|
EXPECT_GE(flat->Capacity(), length);
|
|
|
|
memset(flat->Data(), 0xCD, flat->Capacity());
|
|
|
|
CordRep::Unref(flat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, AllFlatSizes) {
|
|
|
|
using absl::strings_internal::CordTestAccess;
|
|
|
|
|
|
|
|
for (size_t s = 0; s < CordTestAccess::MaxFlatLength(); s++) {
|
|
|
|
// Make a string of length s.
|
|
|
|
std::string src;
|
|
|
|
while (src.size() < s) {
|
|
|
|
src.push_back('a' + (src.size() % 26));
|
|
|
|
}
|
|
|
|
|
|
|
|
absl::Cord dst(src);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(dst);
|
|
|
|
EXPECT_EQ(std::string(dst), src) << s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We create a Cord at least 128GB in size using the fact that Cords can
|
|
|
|
// internally reference-count; thus the Cord is enormous without actually
|
|
|
|
// consuming very much memory.
|
|
|
|
TEST_P(CordTest, GigabyteCordFromExternal) {
|
|
|
|
const size_t one_gig = 1024U * 1024U * 1024U;
|
|
|
|
size_t max_size = 2 * one_gig;
|
|
|
|
if (sizeof(max_size) > 4) max_size = 128 * one_gig;
|
|
|
|
|
|
|
|
size_t length = 128 * 1024;
|
|
|
|
char* data = new char[length];
|
|
|
|
absl::Cord from = absl::MakeCordFromExternal(
|
|
|
|
absl::string_view(data, length),
|
|
|
|
[](absl::string_view sv) { delete[] sv.data(); });
|
|
|
|
|
|
|
|
// This loop may seem odd due to its combination of exponential doubling of
|
|
|
|
// size and incremental size increases. We do it incrementally to be sure the
|
|
|
|
// Cord will need rebalancing and will exercise code that, in the past, has
|
|
|
|
// caused crashes in production. We grow exponentially so that the code will
|
|
|
|
// execute in a reasonable amount of time.
|
|
|
|
absl::Cord c;
|
|
|
|
c.Append(from);
|
|
|
|
while (c.size() < max_size) {
|
|
|
|
c.Append(c);
|
|
|
|
c.Append(from);
|
|
|
|
c.Append(from);
|
|
|
|
c.Append(from);
|
|
|
|
c.Append(from);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 1024; ++i) {
|
|
|
|
c.Append(from);
|
|
|
|
}
|
|
|
|
ABSL_RAW_LOG(INFO, "Made a Cord with %zu bytes!", c.size());
|
|
|
|
// Note: on a 32-bit build, this comes out to 2,818,048,000 bytes.
|
|
|
|
// Note: on a 64-bit build, this comes out to 171,932,385,280 bytes.
|
|
|
|
}
|
|
|
|
|
|
|
|
static absl::Cord MakeExternalCord(int size) {
|
|
|
|
char* buffer = new char[size];
|
|
|
|
memset(buffer, 'x', size);
|
|
|
|
absl::Cord cord;
|
|
|
|
cord.Append(absl::MakeCordFromExternal(
|
|
|
|
absl::string_view(buffer, size),
|
|
|
|
[](absl::string_view s) { delete[] s.data(); }));
|
|
|
|
return cord;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extern to fool clang that this is not constant. Needed to suppress
|
|
|
|
// a warning of unsafe code we want to test.
|
|
|
|
extern bool my_unique_true_boolean;
|
|
|
|
bool my_unique_true_boolean = true;
|
|
|
|
|
|
|
|
TEST_P(CordTest, Assignment) {
|
|
|
|
absl::Cord x(absl::string_view("hi there"));
|
|
|
|
absl::Cord y(x);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(y);
|
|
|
|
ASSERT_EQ(x.ExpectedChecksum(), absl::nullopt);
|
|
|
|
ASSERT_EQ(std::string(x), "hi there");
|
|
|
|
ASSERT_EQ(std::string(y), "hi there");
|
|
|
|
ASSERT_TRUE(x == y);
|
|
|
|
ASSERT_TRUE(x <= y);
|
|
|
|
ASSERT_TRUE(y <= x);
|
|
|
|
|
|
|
|
x = absl::string_view("foo");
|
|
|
|
ASSERT_EQ(std::string(x), "foo");
|
|
|
|
ASSERT_EQ(std::string(y), "hi there");
|
|
|
|
ASSERT_TRUE(x < y);
|
|
|
|
ASSERT_TRUE(y > x);
|
|
|
|
ASSERT_TRUE(x != y);
|
|
|
|
ASSERT_TRUE(x <= y);
|
|
|
|
ASSERT_TRUE(y >= x);
|
|
|
|
|
|
|
|
x = "foo";
|
|
|
|
ASSERT_EQ(x, "foo");
|
|
|
|
|
|
|
|
// Test that going from inline rep to tree we don't leak memory.
|
|
|
|
std::vector<std::pair<absl::string_view, absl::string_view>>
|
|
|
|
test_string_pairs = {{"hi there", "foo"},
|
|
|
|
{"loooooong coooooord", "short cord"},
|
|
|
|
{"short cord", "loooooong coooooord"},
|
|
|
|
{"loooooong coooooord1", "loooooong coooooord2"}};
|
|
|
|
for (std::pair<absl::string_view, absl::string_view> test_strings :
|
|
|
|
test_string_pairs) {
|
|
|
|
absl::Cord tmp(test_strings.first);
|
|
|
|
absl::Cord z(std::move(tmp));
|
|
|
|
ASSERT_EQ(std::string(z), test_strings.first);
|
|
|
|
tmp = test_strings.second;
|
|
|
|
z = std::move(tmp);
|
|
|
|
ASSERT_EQ(std::string(z), test_strings.second);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
// Test that self-move assignment doesn't crash/leak.
|
|
|
|
// Do not write such code!
|
|
|
|
absl::Cord my_small_cord("foo");
|
|
|
|
absl::Cord my_big_cord("loooooong coooooord");
|
|
|
|
// Bypass clang's warning on self move-assignment.
|
|
|
|
absl::Cord* my_small_alias =
|
|
|
|
my_unique_true_boolean ? &my_small_cord : &my_big_cord;
|
|
|
|
absl::Cord* my_big_alias =
|
|
|
|
!my_unique_true_boolean ? &my_small_cord : &my_big_cord;
|
|
|
|
|
|
|
|
*my_small_alias = std::move(my_small_cord);
|
|
|
|
*my_big_alias = std::move(my_big_cord);
|
|
|
|
// my_small_cord and my_big_cord are in an unspecified but valid
|
|
|
|
// state, and will be correctly destroyed here.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, StartsEndsWith) {
|
|
|
|
absl::Cord x(absl::string_view("abcde"));
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
absl::Cord empty("");
|
|
|
|
|
|
|
|
ASSERT_TRUE(x.StartsWith(absl::Cord("abcde")));
|
|
|
|
ASSERT_TRUE(x.StartsWith(absl::Cord("abc")));
|
|
|
|
ASSERT_TRUE(x.StartsWith(absl::Cord("")));
|
|
|
|
ASSERT_TRUE(empty.StartsWith(absl::Cord("")));
|
|
|
|
ASSERT_TRUE(x.EndsWith(absl::Cord("abcde")));
|
|
|
|
ASSERT_TRUE(x.EndsWith(absl::Cord("cde")));
|
|
|
|
ASSERT_TRUE(x.EndsWith(absl::Cord("")));
|
|
|
|
ASSERT_TRUE(empty.EndsWith(absl::Cord("")));
|
|
|
|
|
|
|
|
ASSERT_TRUE(!x.StartsWith(absl::Cord("xyz")));
|
|
|
|
ASSERT_TRUE(!empty.StartsWith(absl::Cord("xyz")));
|
|
|
|
ASSERT_TRUE(!x.EndsWith(absl::Cord("xyz")));
|
|
|
|
ASSERT_TRUE(!empty.EndsWith(absl::Cord("xyz")));
|
|
|
|
|
|
|
|
ASSERT_TRUE(x.StartsWith("abcde"));
|
|
|
|
ASSERT_TRUE(x.StartsWith("abc"));
|
|
|
|
ASSERT_TRUE(x.StartsWith(""));
|
|
|
|
ASSERT_TRUE(empty.StartsWith(""));
|
|
|
|
ASSERT_TRUE(x.EndsWith("abcde"));
|
|
|
|
ASSERT_TRUE(x.EndsWith("cde"));
|
|
|
|
ASSERT_TRUE(x.EndsWith(""));
|
|
|
|
ASSERT_TRUE(empty.EndsWith(""));
|
|
|
|
|
|
|
|
ASSERT_TRUE(!x.StartsWith("xyz"));
|
|
|
|
ASSERT_TRUE(!empty.StartsWith("xyz"));
|
|
|
|
ASSERT_TRUE(!x.EndsWith("xyz"));
|
|
|
|
ASSERT_TRUE(!empty.EndsWith("xyz"));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, Subcord) {
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
const std::string s = RandomLowercaseString(&rng, 1024);
|
|
|
|
|
|
|
|
absl::Cord a;
|
|
|
|
AppendWithFragments(s, &rng, &a);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(a);
|
|
|
|
ASSERT_EQ(s, std::string(a));
|
|
|
|
|
|
|
|
// Check subcords of a, from a variety of interesting points.
|
|
|
|
std::set<size_t> positions;
|
|
|
|
for (int i = 0; i <= 32; ++i) {
|
|
|
|
positions.insert(i);
|
|
|
|
positions.insert(i * 32 - 1);
|
|
|
|
positions.insert(i * 32);
|
|
|
|
positions.insert(i * 32 + 1);
|
|
|
|
positions.insert(a.size() - i);
|
|
|
|
}
|
|
|
|
positions.insert(237);
|
|
|
|
positions.insert(732);
|
|
|
|
for (size_t pos : positions) {
|
|
|
|
if (pos > a.size()) continue;
|
|
|
|
for (size_t end_pos : positions) {
|
|
|
|
if (end_pos < pos || end_pos > a.size()) continue;
|
|
|
|
absl::Cord sa = a.Subcord(pos, end_pos - pos);
|
|
|
|
ASSERT_EQ(absl::string_view(s).substr(pos, end_pos - pos),
|
|
|
|
std::string(sa))
|
|
|
|
<< a;
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
if (pos != 0 || end_pos != a.size()) {
|
|
|
|
ASSERT_EQ(sa.ExpectedChecksum(), absl::nullopt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do the same thing for an inline cord.
|
|
|
|
const std::string sh = "short";
|
|
|
|
absl::Cord c(sh);
|
|
|
|
for (size_t pos = 0; pos <= sh.size(); ++pos) {
|
|
|
|
for (size_t n = 0; n <= sh.size() - pos; ++n) {
|
|
|
|
absl::Cord sc = c.Subcord(pos, n);
|
|
|
|
ASSERT_EQ(sh.substr(pos, n), std::string(sc)) << c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check subcords of subcords.
|
|
|
|
absl::Cord sa = a.Subcord(0, a.size());
|
|
|
|
std::string ss = s.substr(0, s.size());
|
|
|
|
while (sa.size() > 1) {
|
|
|
|
sa = sa.Subcord(1, sa.size() - 2);
|
|
|
|
ss = ss.substr(1, ss.size() - 2);
|
|
|
|
ASSERT_EQ(ss, std::string(sa)) << a;
|
|
|
|
if (HasFailure()) break; // halt cascade
|
|
|
|
}
|
|
|
|
|
|
|
|
// It is OK to ask for too much.
|
|
|
|
sa = a.Subcord(0, a.size() + 1);
|
|
|
|
EXPECT_EQ(s, std::string(sa));
|
|
|
|
|
|
|
|
// It is OK to ask for something beyond the end.
|
|
|
|
sa = a.Subcord(a.size() + 1, 0);
|
|
|
|
EXPECT_TRUE(sa.empty());
|
|
|
|
sa = a.Subcord(a.size() + 1, 1);
|
|
|
|
EXPECT_TRUE(sa.empty());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, Swap) {
|
|
|
|
absl::string_view a("Dexter");
|
|
|
|
absl::string_view b("Mandark");
|
|
|
|
absl::Cord x(a);
|
|
|
|
absl::Cord y(b);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
swap(x, y);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
if (UseCrc()) {
|
|
|
|
ASSERT_EQ(x.ExpectedChecksum(), absl::nullopt);
|
|
|
|
ASSERT_EQ(y.ExpectedChecksum(), 1);
|
|
|
|
}
|
|
|
|
ASSERT_EQ(x, absl::Cord(b));
|
|
|
|
ASSERT_EQ(y, absl::Cord(a));
|
|
|
|
x.swap(y);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
if (UseCrc()) {
|
|
|
|
ASSERT_EQ(x.ExpectedChecksum(), 1);
|
|
|
|
ASSERT_EQ(y.ExpectedChecksum(), absl::nullopt);
|
|
|
|
}
|
|
|
|
ASSERT_EQ(x, absl::Cord(a));
|
|
|
|
ASSERT_EQ(y, absl::Cord(b));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void VerifyCopyToString(const absl::Cord& cord) {
|
|
|
|
std::string initially_empty;
|
|
|
|
absl::CopyCordToString(cord, &initially_empty);
|
|
|
|
EXPECT_EQ(initially_empty, cord);
|
|
|
|
|
|
|
|
constexpr size_t kInitialLength = 1024;
|
|
|
|
std::string has_initial_contents(kInitialLength, 'x');
|
|
|
|
const char* address_before_copy = has_initial_contents.data();
|
|
|
|
absl::CopyCordToString(cord, &has_initial_contents);
|
|
|
|
EXPECT_EQ(has_initial_contents, cord);
|
|
|
|
|
|
|
|
if (cord.size() <= kInitialLength) {
|
|
|
|
EXPECT_EQ(has_initial_contents.data(), address_before_copy)
|
|
|
|
<< "CopyCordToString allocated new string storage; "
|
|
|
|
"has_initial_contents = \""
|
|
|
|
<< has_initial_contents << "\"";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CopyToString) {
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
VerifyCopyToString(absl::Cord()); // empty cords cannot carry CRCs
|
|
|
|
VerifyCopyToString(MaybeHardened(absl::Cord("small cord")));
|
|
|
|
VerifyCopyToString(MaybeHardened(
|
|
|
|
absl::MakeFragmentedCord({"fragmented ", "cord ", "to ", "test ",
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
"copying ", "to ", "a ", "string."})));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, AppendEmptyBuffer) {
|
|
|
|
absl::Cord cord;
|
|
|
|
cord.Append(absl::CordBuffer());
|
|
|
|
cord.Append(absl::CordBuffer::CreateWithDefaultLimit(2000));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, AppendEmptyBufferToFlat) {
|
|
|
|
absl::Cord cord(std::string(2000, 'x'));
|
|
|
|
cord.Append(absl::CordBuffer());
|
|
|
|
cord.Append(absl::CordBuffer::CreateWithDefaultLimit(2000));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, AppendEmptyBufferToTree) {
|
|
|
|
absl::Cord cord(std::string(2000, 'x'));
|
|
|
|
cord.Append(std::string(2000, 'y'));
|
|
|
|
cord.Append(absl::CordBuffer());
|
|
|
|
cord.Append(absl::CordBuffer::CreateWithDefaultLimit(2000));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, AppendSmallBuffer) {
|
|
|
|
absl::Cord cord;
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(3);
|
|
|
|
ASSERT_THAT(buffer.capacity(), ::testing::Le(15));
|
|
|
|
memcpy(buffer.data(), "Abc", 3);
|
|
|
|
buffer.SetLength(3);
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
EXPECT_EQ(buffer.length(), 0); // NOLINT
|
|
|
|
EXPECT_GT(buffer.capacity(), 0); // NOLINT
|
|
|
|
|
|
|
|
buffer = absl::CordBuffer::CreateWithDefaultLimit(3);
|
|
|
|
memcpy(buffer.data(), "defgh", 5);
|
|
|
|
buffer.SetLength(5);
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
EXPECT_EQ(buffer.length(), 0); // NOLINT
|
|
|
|
EXPECT_GT(buffer.capacity(), 0); // NOLINT
|
|
|
|
|
|
|
|
EXPECT_THAT(cord.Chunks(), ::testing::ElementsAre("Abcdefgh"));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, AppendAndPrependBufferArePrecise) {
|
|
|
|
// Create a cord large enough to force 40KB flats.
|
|
|
|
std::string test_data(absl::cord_internal::kMaxFlatLength * 10, 'x');
|
|
|
|
absl::Cord cord1(test_data);
|
|
|
|
absl::Cord cord2(test_data);
|
|
|
|
const size_t size1 = cord1.EstimatedMemoryUsage();
|
|
|
|
const size_t size2 = cord2.EstimatedMemoryUsage();
|
|
|
|
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(3);
|
|
|
|
memcpy(buffer.data(), "Abc", 3);
|
|
|
|
buffer.SetLength(3);
|
|
|
|
cord1.Append(std::move(buffer));
|
|
|
|
|
|
|
|
buffer = absl::CordBuffer::CreateWithDefaultLimit(3);
|
|
|
|
memcpy(buffer.data(), "Abc", 3);
|
|
|
|
buffer.SetLength(3);
|
|
|
|
cord2.Prepend(std::move(buffer));
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
// Allow 32 bytes new CordRepFlat, and 128 bytes for 'glue nodes'
|
|
|
|
constexpr size_t kMaxDelta = 128 + 32;
|
|
|
|
#else
|
|
|
|
// Allow 256 bytes extra for 'allocation debug overhead'
|
|
|
|
constexpr size_t kMaxDelta = 128 + 32 + 256;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
EXPECT_LE(cord1.EstimatedMemoryUsage() - size1, kMaxDelta);
|
|
|
|
EXPECT_LE(cord2.EstimatedMemoryUsage() - size2, kMaxDelta);
|
|
|
|
|
|
|
|
EXPECT_EQ(cord1, absl::StrCat(test_data, "Abc"));
|
|
|
|
EXPECT_EQ(cord2, absl::StrCat("Abc", test_data));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, PrependSmallBuffer) {
|
|
|
|
absl::Cord cord;
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(3);
|
|
|
|
ASSERT_THAT(buffer.capacity(), ::testing::Le(15));
|
|
|
|
memcpy(buffer.data(), "Abc", 3);
|
|
|
|
buffer.SetLength(3);
|
|
|
|
cord.Prepend(std::move(buffer));
|
|
|
|
EXPECT_EQ(buffer.length(), 0); // NOLINT
|
|
|
|
EXPECT_GT(buffer.capacity(), 0); // NOLINT
|
|
|
|
|
|
|
|
buffer = absl::CordBuffer::CreateWithDefaultLimit(3);
|
|
|
|
memcpy(buffer.data(), "defgh", 5);
|
|
|
|
buffer.SetLength(5);
|
|
|
|
cord.Prepend(std::move(buffer));
|
|
|
|
EXPECT_EQ(buffer.length(), 0); // NOLINT
|
|
|
|
EXPECT_GT(buffer.capacity(), 0); // NOLINT
|
|
|
|
|
|
|
|
EXPECT_THAT(cord.Chunks(), ::testing::ElementsAre("defghAbc"));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, AppendLargeBuffer) {
|
|
|
|
absl::Cord cord;
|
|
|
|
|
|
|
|
std::string s1(700, '1');
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(s1.size());
|
|
|
|
memcpy(buffer.data(), s1.data(), s1.size());
|
|
|
|
buffer.SetLength(s1.size());
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
EXPECT_EQ(buffer.length(), 0); // NOLINT
|
|
|
|
EXPECT_GT(buffer.capacity(), 0); // NOLINT
|
|
|
|
|
|
|
|
std::string s2(1000, '2');
|
|
|
|
buffer = absl::CordBuffer::CreateWithDefaultLimit(s2.size());
|
|
|
|
memcpy(buffer.data(), s2.data(), s2.size());
|
|
|
|
buffer.SetLength(s2.size());
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
EXPECT_EQ(buffer.length(), 0); // NOLINT
|
|
|
|
EXPECT_GT(buffer.capacity(), 0); // NOLINT
|
|
|
|
|
|
|
|
EXPECT_THAT(cord.Chunks(), ::testing::ElementsAre(s1, s2));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, PrependLargeBuffer) {
|
|
|
|
absl::Cord cord;
|
|
|
|
|
|
|
|
std::string s1(700, '1');
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(s1.size());
|
|
|
|
memcpy(buffer.data(), s1.data(), s1.size());
|
|
|
|
buffer.SetLength(s1.size());
|
|
|
|
cord.Prepend(std::move(buffer));
|
|
|
|
EXPECT_EQ(buffer.length(), 0); // NOLINT
|
|
|
|
EXPECT_GT(buffer.capacity(), 0); // NOLINT
|
|
|
|
|
|
|
|
std::string s2(1000, '2');
|
|
|
|
buffer = absl::CordBuffer::CreateWithDefaultLimit(s2.size());
|
|
|
|
memcpy(buffer.data(), s2.data(), s2.size());
|
|
|
|
buffer.SetLength(s2.size());
|
|
|
|
cord.Prepend(std::move(buffer));
|
|
|
|
EXPECT_EQ(buffer.length(), 0); // NOLINT
|
|
|
|
EXPECT_GT(buffer.capacity(), 0); // NOLINT
|
|
|
|
|
|
|
|
EXPECT_THAT(cord.Chunks(), ::testing::ElementsAre(s2, s1));
|
|
|
|
}
|
|
|
|
|
|
|
|
class CordAppendBufferTest : public testing::TestWithParam<bool> {
|
|
|
|
public:
|
|
|
|
size_t is_default() const { return GetParam(); }
|
|
|
|
|
|
|
|
// Returns human readable string representation of the test parameter.
|
|
|
|
static std::string ToString(testing::TestParamInfo<bool> param) {
|
|
|
|
return param.param ? "DefaultLimit" : "CustomLimit";
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t limit() const {
|
|
|
|
return is_default() ? absl::CordBuffer::kDefaultLimit
|
|
|
|
: absl::CordBuffer::kCustomLimit;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t maximum_payload() const {
|
|
|
|
return is_default() ? absl::CordBuffer::MaximumPayload()
|
|
|
|
: absl::CordBuffer::MaximumPayload(limit());
|
|
|
|
}
|
|
|
|
|
|
|
|
absl::CordBuffer GetAppendBuffer(absl::Cord& cord, size_t capacity,
|
|
|
|
size_t min_capacity = 16) {
|
|
|
|
return is_default()
|
|
|
|
? cord.GetAppendBuffer(capacity, min_capacity)
|
|
|
|
: cord.GetCustomAppendBuffer(limit(), capacity, min_capacity);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_SUITE_P(WithParam, CordAppendBufferTest, testing::Bool(),
|
|
|
|
CordAppendBufferTest::ToString);
|
|
|
|
|
|
|
|
TEST_P(CordAppendBufferTest, GetAppendBufferOnEmptyCord) {
|
|
|
|
absl::Cord cord;
|
|
|
|
absl::CordBuffer buffer = GetAppendBuffer(cord, 1000);
|
|
|
|
EXPECT_GE(buffer.capacity(), 1000);
|
|
|
|
EXPECT_EQ(buffer.length(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordAppendBufferTest, GetAppendBufferOnInlinedCord) {
|
|
|
|
static constexpr int kInlinedSize = sizeof(absl::CordBuffer) - 1;
|
|
|
|
for (int size : {6, kInlinedSize - 3, kInlinedSize - 2, 1000}) {
|
|
|
|
absl::Cord cord("Abc");
|
|
|
|
absl::CordBuffer buffer = GetAppendBuffer(cord, size, 1);
|
|
|
|
EXPECT_GE(buffer.capacity(), 3 + size);
|
|
|
|
EXPECT_EQ(buffer.length(), 3);
|
|
|
|
EXPECT_EQ(absl::string_view(buffer.data(), buffer.length()), "Abc");
|
|
|
|
EXPECT_TRUE(cord.empty());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordAppendBufferTest, GetAppendBufferOnInlinedCordCapacityCloseToMax) {
|
|
|
|
// Cover the use case where we have a non empty inlined cord with some size
|
|
|
|
// 'n', and ask for something like 'uint64_max - k', assuming internal logic
|
|
|
|
// could overflow on 'uint64_max - k + size', and return a valid, but
|
|
|
|
// inefficiently smaller buffer if it would provide is the max allowed size.
|
|
|
|
for (size_t dist_from_max = 0; dist_from_max <= 4; ++dist_from_max) {
|
|
|
|
absl::Cord cord("Abc");
|
|
|
|
size_t size = std::numeric_limits<size_t>::max() - dist_from_max;
|
|
|
|
absl::CordBuffer buffer = GetAppendBuffer(cord, size, 1);
|
|
|
|
EXPECT_GE(buffer.capacity(), maximum_payload());
|
|
|
|
EXPECT_EQ(buffer.length(), 3);
|
|
|
|
EXPECT_EQ(absl::string_view(buffer.data(), buffer.length()), "Abc");
|
|
|
|
EXPECT_TRUE(cord.empty());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordAppendBufferTest, GetAppendBufferOnFlat) {
|
|
|
|
// Create a cord with a single flat and extra capacity
|
|
|
|
absl::Cord cord;
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(500);
|
|
|
|
const size_t expected_capacity = buffer.capacity();
|
|
|
|
buffer.SetLength(3);
|
|
|
|
memcpy(buffer.data(), "Abc", 3);
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
|
|
|
|
buffer = GetAppendBuffer(cord, 6);
|
|
|
|
EXPECT_EQ(buffer.capacity(), expected_capacity);
|
|
|
|
EXPECT_EQ(buffer.length(), 3);
|
|
|
|
EXPECT_EQ(absl::string_view(buffer.data(), buffer.length()), "Abc");
|
|
|
|
EXPECT_TRUE(cord.empty());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordAppendBufferTest, GetAppendBufferOnFlatWithoutMinCapacity) {
|
|
|
|
// Create a cord with a single flat and extra capacity
|
|
|
|
absl::Cord cord;
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(500);
|
|
|
|
buffer.SetLength(30);
|
|
|
|
memset(buffer.data(), 'x', 30);
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
|
|
|
|
buffer = GetAppendBuffer(cord, 1000, 900);
|
|
|
|
EXPECT_GE(buffer.capacity(), 1000);
|
|
|
|
EXPECT_EQ(buffer.length(), 0);
|
|
|
|
EXPECT_EQ(cord, std::string(30, 'x'));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordAppendBufferTest, GetAppendBufferOnTree) {
|
|
|
|
RandomEngine rng;
|
|
|
|
for (int num_flats : {2, 3, 100}) {
|
|
|
|
// Create a cord with `num_flats` flats and extra capacity
|
|
|
|
absl::Cord cord;
|
|
|
|
std::string prefix;
|
|
|
|
std::string last;
|
|
|
|
for (int i = 0; i < num_flats - 1; ++i) {
|
|
|
|
prefix += last;
|
|
|
|
last = RandomLowercaseString(&rng, 10);
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(500);
|
|
|
|
buffer.SetLength(10);
|
|
|
|
memcpy(buffer.data(), last.data(), 10);
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
}
|
|
|
|
absl::CordBuffer buffer = GetAppendBuffer(cord, 6);
|
|
|
|
EXPECT_GE(buffer.capacity(), 500);
|
|
|
|
EXPECT_EQ(buffer.length(), 10);
|
|
|
|
EXPECT_EQ(absl::string_view(buffer.data(), buffer.length()), last);
|
|
|
|
EXPECT_EQ(cord, prefix);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordAppendBufferTest, GetAppendBufferOnTreeWithoutMinCapacity) {
|
|
|
|
absl::Cord cord;
|
|
|
|
for (int i = 0; i < 2; ++i) {
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(500);
|
|
|
|
buffer.SetLength(3);
|
|
|
|
memcpy(buffer.data(), i ? "def" : "Abc", 3);
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
}
|
|
|
|
absl::CordBuffer buffer = GetAppendBuffer(cord, 1000, 900);
|
|
|
|
EXPECT_GE(buffer.capacity(), 1000);
|
|
|
|
EXPECT_EQ(buffer.length(), 0);
|
|
|
|
EXPECT_EQ(cord, "Abcdef");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordAppendBufferTest, GetAppendBufferOnSubstring) {
|
|
|
|
// Create a large cord with a single flat and some extra capacity
|
|
|
|
absl::Cord cord;
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(500);
|
|
|
|
buffer.SetLength(450);
|
|
|
|
memset(buffer.data(), 'x', 450);
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
cord.RemovePrefix(1);
|
|
|
|
|
|
|
|
// Deny on substring
|
|
|
|
buffer = GetAppendBuffer(cord, 6);
|
|
|
|
EXPECT_EQ(buffer.length(), 0);
|
|
|
|
EXPECT_EQ(cord, std::string(449, 'x'));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordAppendBufferTest, GetAppendBufferOnSharedCord) {
|
|
|
|
// Create a shared cord with a single flat and extra capacity
|
|
|
|
absl::Cord cord;
|
|
|
|
absl::CordBuffer buffer = absl::CordBuffer::CreateWithDefaultLimit(500);
|
|
|
|
buffer.SetLength(3);
|
|
|
|
memcpy(buffer.data(), "Abc", 3);
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
absl::Cord shared_cord = cord;
|
|
|
|
|
|
|
|
// Deny on flat
|
|
|
|
buffer = GetAppendBuffer(cord, 6);
|
|
|
|
EXPECT_EQ(buffer.length(), 0);
|
|
|
|
EXPECT_EQ(cord, "Abc");
|
|
|
|
|
|
|
|
buffer = absl::CordBuffer::CreateWithDefaultLimit(500);
|
|
|
|
buffer.SetLength(3);
|
|
|
|
memcpy(buffer.data(), "def", 3);
|
|
|
|
cord.Append(std::move(buffer));
|
|
|
|
shared_cord = cord;
|
|
|
|
|
|
|
|
// Deny on tree
|
|
|
|
buffer = GetAppendBuffer(cord, 6);
|
|
|
|
EXPECT_EQ(buffer.length(), 0);
|
|
|
|
EXPECT_EQ(cord, "Abcdef");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, TryFlatEmpty) {
|
|
|
|
absl::Cord c;
|
|
|
|
EXPECT_EQ(c.TryFlat(), "");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, TryFlatFlat) {
|
|
|
|
absl::Cord c("hello");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
EXPECT_EQ(c.TryFlat(), "hello");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, TryFlatSubstrInlined) {
|
|
|
|
absl::Cord c("hello");
|
|
|
|
c.RemovePrefix(1);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
EXPECT_EQ(c.TryFlat(), "ello");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, TryFlatSubstrFlat) {
|
|
|
|
absl::Cord c("longer than 15 bytes");
|
|
|
|
absl::Cord sub = absl::CordTestPeer::MakeSubstring(c, 1, c.size() - 1);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(sub);
|
|
|
|
EXPECT_EQ(sub.TryFlat(), "onger than 15 bytes");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, TryFlatConcat) {
|
|
|
|
absl::Cord c = absl::MakeFragmentedCord({"hel", "lo"});
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
EXPECT_EQ(c.TryFlat(), absl::nullopt);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, TryFlatExternal) {
|
|
|
|
absl::Cord c = absl::MakeCordFromExternal("hell", [](absl::string_view) {});
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
EXPECT_EQ(c.TryFlat(), "hell");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, TryFlatSubstrExternal) {
|
|
|
|
absl::Cord c = absl::MakeCordFromExternal("hell", [](absl::string_view) {});
|
|
|
|
absl::Cord sub = absl::CordTestPeer::MakeSubstring(c, 1, c.size() - 1);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(sub);
|
|
|
|
EXPECT_EQ(sub.TryFlat(), "ell");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, TryFlatCommonlyAssumedInvariants) {
|
|
|
|
// The behavior tested below is not part of the API contract of Cord, but it's
|
|
|
|
// something we intend to be true in our current implementation. This test
|
|
|
|
// exists to detect and prevent accidental breakage of the implementation.
|
|
|
|
absl::string_view fragments[] = {"A fragmented test",
|
|
|
|
" cord",
|
|
|
|
" to test subcords",
|
|
|
|
" of ",
|
|
|
|
"a",
|
|
|
|
" cord for",
|
|
|
|
" each chunk "
|
|
|
|
"returned by the ",
|
|
|
|
"iterator"};
|
|
|
|
absl::Cord c = absl::MakeFragmentedCord(fragments);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
int fragment = 0;
|
|
|
|
int offset = 0;
|
|
|
|
absl::Cord::CharIterator itc = c.char_begin();
|
|
|
|
for (absl::string_view sv : c.Chunks()) {
|
|
|
|
absl::string_view expected = fragments[fragment];
|
|
|
|
absl::Cord subcord1 = c.Subcord(offset, sv.length());
|
|
|
|
absl::Cord subcord2 = absl::Cord::AdvanceAndRead(&itc, sv.size());
|
|
|
|
EXPECT_EQ(subcord1.TryFlat(), expected);
|
|
|
|
EXPECT_EQ(subcord2.TryFlat(), expected);
|
|
|
|
++fragment;
|
|
|
|
offset += sv.length();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool IsFlat(const absl::Cord& c) {
|
|
|
|
return c.chunk_begin() == c.chunk_end() || ++c.chunk_begin() == c.chunk_end();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void VerifyFlatten(absl::Cord c) {
|
|
|
|
std::string old_contents(c);
|
|
|
|
absl::string_view old_flat;
|
|
|
|
bool already_flat_and_non_empty = IsFlat(c) && !c.empty();
|
|
|
|
if (already_flat_and_non_empty) {
|
|
|
|
old_flat = *c.chunk_begin();
|
|
|
|
}
|
|
|
|
absl::string_view new_flat = c.Flatten();
|
|
|
|
|
|
|
|
// Verify that the contents of the flattened Cord are correct.
|
|
|
|
EXPECT_EQ(new_flat, old_contents);
|
|
|
|
EXPECT_EQ(std::string(c), old_contents);
|
|
|
|
|
|
|
|
// If the Cord contained data and was already flat, verify that the data
|
|
|
|
// wasn't copied.
|
|
|
|
if (already_flat_and_non_empty) {
|
|
|
|
EXPECT_EQ(old_flat.data(), new_flat.data())
|
|
|
|
<< "Allocated new memory even though the Cord was already flat.";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify that the flattened Cord is in fact flat.
|
|
|
|
EXPECT_TRUE(IsFlat(c));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, Flatten) {
|
|
|
|
VerifyFlatten(absl::Cord());
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
VerifyFlatten(MaybeHardened(absl::Cord("small cord")));
|
|
|
|
VerifyFlatten(
|
|
|
|
MaybeHardened(absl::Cord("larger than small buffer optimization")));
|
|
|
|
VerifyFlatten(MaybeHardened(
|
|
|
|
absl::MakeFragmentedCord({"small ", "fragmented ", "cord"})));
|
|
|
|
|
|
|
|
// Test with a cord that is longer than the largest flat buffer
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
VerifyFlatten(MaybeHardened(absl::Cord(RandomLowercaseString(&rng, 8192))));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test data
|
|
|
|
namespace {
|
|
|
|
class TestData {
|
|
|
|
private:
|
|
|
|
std::vector<std::string> data_;
|
|
|
|
|
|
|
|
// Return a std::string of the specified length.
|
|
|
|
static std::string MakeString(int length) {
|
|
|
|
std::string result;
|
|
|
|
char buf[30];
|
|
|
|
snprintf(buf, sizeof(buf), "(%d)", length);
|
|
|
|
while (result.size() < length) {
|
|
|
|
result += buf;
|
|
|
|
}
|
|
|
|
result.resize(length);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
TestData() {
|
|
|
|
// short strings increasing in length by one
|
|
|
|
for (int i = 0; i < 30; i++) {
|
|
|
|
data_.push_back(MakeString(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
// strings around half kMaxFlatLength
|
|
|
|
static const int kMaxFlatLength = 4096 - 9;
|
|
|
|
static const int kHalf = kMaxFlatLength / 2;
|
|
|
|
|
|
|
|
for (int i = -10; i <= +10; i++) {
|
|
|
|
data_.push_back(MakeString(kHalf + i));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = -10; i <= +10; i++) {
|
|
|
|
data_.push_back(MakeString(kMaxFlatLength + i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t size() const { return data_.size(); }
|
|
|
|
const std::string& data(size_t i) const { return data_[i]; }
|
|
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
TEST_P(CordTest, MultipleLengths) {
|
|
|
|
TestData d;
|
|
|
|
for (size_t i = 0; i < d.size(); i++) {
|
|
|
|
std::string a = d.data(i);
|
|
|
|
|
|
|
|
{ // Construct from Cord
|
|
|
|
absl::Cord tmp(a);
|
|
|
|
absl::Cord x(tmp);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
EXPECT_EQ(a, std::string(x)) << "'" << a << "'";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Construct from absl::string_view
|
|
|
|
absl::Cord x(a);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
EXPECT_EQ(a, std::string(x)) << "'" << a << "'";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Append cord to self
|
|
|
|
absl::Cord self(a);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(self);
|
|
|
|
self.Append(self);
|
|
|
|
EXPECT_EQ(a + a, std::string(self)) << "'" << a << "' + '" << a << "'";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Prepend cord to self
|
|
|
|
absl::Cord self(a);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(self);
|
|
|
|
self.Prepend(self);
|
|
|
|
EXPECT_EQ(a + a, std::string(self)) << "'" << a << "' + '" << a << "'";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to append/prepend others
|
|
|
|
for (size_t j = 0; j < d.size(); j++) {
|
|
|
|
std::string b = d.data(j);
|
|
|
|
|
|
|
|
{ // CopyFrom Cord
|
|
|
|
absl::Cord x(a);
|
|
|
|
absl::Cord y(b);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
x = y;
|
|
|
|
EXPECT_EQ(b, std::string(x)) << "'" << a << "' + '" << b << "'";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // CopyFrom absl::string_view
|
|
|
|
absl::Cord x(a);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
x = b;
|
|
|
|
EXPECT_EQ(b, std::string(x)) << "'" << a << "' + '" << b << "'";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Cord::Append(Cord)
|
|
|
|
absl::Cord x(a);
|
|
|
|
absl::Cord y(b);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
x.Append(y);
|
|
|
|
EXPECT_EQ(a + b, std::string(x)) << "'" << a << "' + '" << b << "'";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Cord::Append(absl::string_view)
|
|
|
|
absl::Cord x(a);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
x.Append(b);
|
|
|
|
EXPECT_EQ(a + b, std::string(x)) << "'" << a << "' + '" << b << "'";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Cord::Prepend(Cord)
|
|
|
|
absl::Cord x(a);
|
|
|
|
absl::Cord y(b);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
x.Prepend(y);
|
|
|
|
EXPECT_EQ(b + a, std::string(x)) << "'" << b << "' + '" << a << "'";
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Cord::Prepend(absl::string_view)
|
|
|
|
absl::Cord x(a);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(x);
|
|
|
|
x.Prepend(b);
|
|
|
|
EXPECT_EQ(b + a, std::string(x)) << "'" << b << "' + '" << a << "'";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
TEST_P(CordTest, RemoveSuffixWithExternalOrSubstring) {
|
|
|
|
absl::Cord cord = absl::MakeCordFromExternal(
|
|
|
|
"foo bar baz", [](absl::string_view s) { DoNothing(s, nullptr); });
|
|
|
|
EXPECT_EQ("foo bar baz", std::string(cord));
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
|
|
|
|
|
|
|
// This RemoveSuffix() will wrap the EXTERNAL node in a SUBSTRING node.
|
|
|
|
cord.RemoveSuffix(4);
|
|
|
|
EXPECT_EQ("foo bar", std::string(cord));
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
|
|
|
|
|
|
|
// This RemoveSuffix() will adjust the SUBSTRING node in-place.
|
|
|
|
cord.RemoveSuffix(4);
|
|
|
|
EXPECT_EQ("foo", std::string(cord));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, RemoveSuffixMakesZeroLengthNode) {
|
|
|
|
absl::Cord c;
|
|
|
|
c.Append(absl::Cord(std::string(100, 'x')));
|
|
|
|
absl::Cord other_ref = c; // Prevent inplace appends
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
c.Append(absl::Cord(std::string(200, 'y')));
|
|
|
|
c.RemoveSuffix(200);
|
|
|
|
EXPECT_EQ(std::string(100, 'x'), std::string(c));
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
// CordSpliceTest contributed by hendrie.
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
// Create a cord with an external memory block filled with 'z'
|
|
|
|
absl::Cord CordWithZedBlock(size_t size) {
|
|
|
|
char* data = new char[size];
|
|
|
|
if (size > 0) {
|
|
|
|
memset(data, 'z', size);
|
|
|
|
}
|
|
|
|
absl::Cord cord = absl::MakeCordFromExternal(
|
|
|
|
absl::string_view(data, size),
|
|
|
|
[](absl::string_view s) { delete[] s.data(); });
|
|
|
|
return cord;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Establish that ZedBlock does what we think it does.
|
|
|
|
TEST_P(CordTest, CordSpliceTestZedBlock) {
|
|
|
|
absl::Cord blob = CordWithZedBlock(10);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(blob);
|
|
|
|
EXPECT_EQ(10, blob.size());
|
|
|
|
std::string s;
|
|
|
|
absl::CopyCordToString(blob, &s);
|
|
|
|
EXPECT_EQ("zzzzzzzzzz", s);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CordSpliceTestZedBlock0) {
|
|
|
|
absl::Cord blob = CordWithZedBlock(0);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(blob);
|
|
|
|
EXPECT_EQ(0, blob.size());
|
|
|
|
std::string s;
|
|
|
|
absl::CopyCordToString(blob, &s);
|
|
|
|
EXPECT_EQ("", s);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CordSpliceTestZedBlockSuffix1) {
|
|
|
|
absl::Cord blob = CordWithZedBlock(10);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(blob);
|
|
|
|
EXPECT_EQ(10, blob.size());
|
|
|
|
absl::Cord suffix(blob);
|
|
|
|
suffix.RemovePrefix(9);
|
|
|
|
EXPECT_EQ(1, suffix.size());
|
|
|
|
std::string s;
|
|
|
|
absl::CopyCordToString(suffix, &s);
|
|
|
|
EXPECT_EQ("z", s);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove all of a prefix block
|
|
|
|
TEST_P(CordTest, CordSpliceTestZedBlockSuffix0) {
|
|
|
|
absl::Cord blob = CordWithZedBlock(10);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(blob);
|
|
|
|
EXPECT_EQ(10, blob.size());
|
|
|
|
absl::Cord suffix(blob);
|
|
|
|
suffix.RemovePrefix(10);
|
|
|
|
EXPECT_EQ(0, suffix.size());
|
|
|
|
std::string s;
|
|
|
|
absl::CopyCordToString(suffix, &s);
|
|
|
|
EXPECT_EQ("", s);
|
|
|
|
}
|
|
|
|
|
|
|
|
absl::Cord BigCord(size_t len, char v) {
|
|
|
|
std::string s(len, v);
|
|
|
|
return absl::Cord(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Splice block into cord.
|
|
|
|
absl::Cord SpliceCord(const absl::Cord& blob, int64_t offset,
|
|
|
|
const absl::Cord& block) {
|
|
|
|
ABSL_RAW_CHECK(offset >= 0, "");
|
|
|
|
ABSL_RAW_CHECK(offset + block.size() <= blob.size(), "");
|
|
|
|
absl::Cord result(blob);
|
|
|
|
result.RemoveSuffix(blob.size() - offset);
|
|
|
|
result.Append(block);
|
|
|
|
absl::Cord suffix(blob);
|
|
|
|
suffix.RemovePrefix(offset + block.size());
|
|
|
|
result.Append(suffix);
|
|
|
|
ABSL_RAW_CHECK(blob.size() == result.size(), "");
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Taking an empty suffix of a block breaks appending.
|
|
|
|
TEST_P(CordTest, CordSpliceTestRemoveEntireBlock1) {
|
|
|
|
absl::Cord zero = CordWithZedBlock(10);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(zero);
|
|
|
|
absl::Cord suffix(zero);
|
|
|
|
suffix.RemovePrefix(10);
|
|
|
|
absl::Cord result;
|
|
|
|
result.Append(suffix);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CordSpliceTestRemoveEntireBlock2) {
|
|
|
|
absl::Cord zero = CordWithZedBlock(10);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(zero);
|
|
|
|
absl::Cord prefix(zero);
|
|
|
|
prefix.RemoveSuffix(10);
|
|
|
|
absl::Cord suffix(zero);
|
|
|
|
suffix.RemovePrefix(10);
|
|
|
|
absl::Cord result(prefix);
|
|
|
|
result.Append(suffix);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CordSpliceTestRemoveEntireBlock3) {
|
|
|
|
absl::Cord blob = CordWithZedBlock(10);
|
|
|
|
absl::Cord block = BigCord(10, 'b');
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(blob);
|
|
|
|
MaybeHarden(block);
|
|
|
|
blob = SpliceCord(blob, 0, block);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct CordCompareTestCase {
|
|
|
|
template <typename LHS, typename RHS>
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
CordCompareTestCase(const LHS& lhs, const RHS& rhs, bool use_crc)
|
|
|
|
: lhs_cord(lhs), rhs_cord(rhs) {
|
|
|
|
if (use_crc) {
|
|
|
|
lhs_cord.SetExpectedChecksum(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
absl::Cord lhs_cord;
|
|
|
|
absl::Cord rhs_cord;
|
|
|
|
};
|
|
|
|
|
|
|
|
const auto sign = [](int x) { return x == 0 ? 0 : (x > 0 ? 1 : -1); };
|
|
|
|
|
|
|
|
void VerifyComparison(const CordCompareTestCase& test_case) {
|
|
|
|
std::string lhs_string(test_case.lhs_cord);
|
|
|
|
std::string rhs_string(test_case.rhs_cord);
|
|
|
|
int expected = sign(lhs_string.compare(rhs_string));
|
|
|
|
EXPECT_EQ(expected, test_case.lhs_cord.Compare(test_case.rhs_cord))
|
|
|
|
<< "LHS=" << lhs_string << "; RHS=" << rhs_string;
|
|
|
|
EXPECT_EQ(expected, test_case.lhs_cord.Compare(rhs_string))
|
|
|
|
<< "LHS=" << lhs_string << "; RHS=" << rhs_string;
|
|
|
|
EXPECT_EQ(-expected, test_case.rhs_cord.Compare(test_case.lhs_cord))
|
|
|
|
<< "LHS=" << rhs_string << "; RHS=" << lhs_string;
|
|
|
|
EXPECT_EQ(-expected, test_case.rhs_cord.Compare(lhs_string))
|
|
|
|
<< "LHS=" << rhs_string << "; RHS=" << lhs_string;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, Compare) {
|
|
|
|
absl::Cord subcord("aaaaaBBBBBcccccDDDDD");
|
|
|
|
subcord = subcord.Subcord(3, 10);
|
|
|
|
|
|
|
|
absl::Cord tmp("aaaaaaaaaaaaaaaa");
|
|
|
|
tmp.Append("BBBBBBBBBBBBBBBB");
|
|
|
|
absl::Cord concat = absl::Cord("cccccccccccccccc");
|
|
|
|
concat.Append("DDDDDDDDDDDDDDDD");
|
|
|
|
concat.Prepend(tmp);
|
|
|
|
|
|
|
|
absl::Cord concat2("aaaaaaaaaaaaa");
|
|
|
|
concat2.Append("aaaBBBBBBBBBBBBBBBBccccc");
|
|
|
|
concat2.Append("cccccccccccDDDDDDDDDDDDDD");
|
|
|
|
concat2.Append("DD");
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
const bool use_crc = UseCrc();
|
|
|
|
|
|
|
|
std::vector<CordCompareTestCase> test_cases = {{
|
|
|
|
// Inline cords
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
{"abcdef", "abcdef", use_crc},
|
|
|
|
{"abcdef", "abcdee", use_crc},
|
|
|
|
{"abcdef", "abcdeg", use_crc},
|
|
|
|
{"bbcdef", "abcdef", use_crc},
|
|
|
|
{"bbcdef", "abcdeg", use_crc},
|
|
|
|
{"abcdefa", "abcdef", use_crc},
|
|
|
|
{"abcdef", "abcdefa", use_crc},
|
|
|
|
|
|
|
|
// Small flat cords
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
{"aaaaaBBBBBcccccDDDDD", "aaaaaBBBBBcccccDDDDD", use_crc},
|
|
|
|
{"aaaaaBBBBBcccccDDDDD", "aaaaaBBBBBxccccDDDDD", use_crc},
|
|
|
|
{"aaaaaBBBBBcxcccDDDDD", "aaaaaBBBBBcccccDDDDD", use_crc},
|
|
|
|
{"aaaaaBBBBBxccccDDDDD", "aaaaaBBBBBcccccDDDDX", use_crc},
|
|
|
|
{"aaaaaBBBBBcccccDDDDDa", "aaaaaBBBBBcccccDDDDD", use_crc},
|
|
|
|
{"aaaaaBBBBBcccccDDDDD", "aaaaaBBBBBcccccDDDDDa", use_crc},
|
|
|
|
|
|
|
|
// Subcords
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
{subcord, subcord, use_crc},
|
|
|
|
{subcord, "aaBBBBBccc", use_crc},
|
|
|
|
{subcord, "aaBBBBBccd", use_crc},
|
|
|
|
{subcord, "aaBBBBBccb", use_crc},
|
|
|
|
{subcord, "aaBBBBBxcb", use_crc},
|
|
|
|
{subcord, "aaBBBBBccca", use_crc},
|
|
|
|
{subcord, "aaBBBBBcc", use_crc},
|
|
|
|
|
|
|
|
// Concats
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
{concat, concat, use_crc},
|
|
|
|
{concat,
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
"aaaaaaaaaaaaaaaaBBBBBBBBBBBBBBBBccccccccccccccccDDDDDDDDDDDDDDDD",
|
|
|
|
use_crc},
|
|
|
|
{concat,
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
"aaaaaaaaaaaaaaaaBBBBBBBBBBBBBBBBcccccccccccccccxDDDDDDDDDDDDDDDD",
|
|
|
|
use_crc},
|
|
|
|
{concat,
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
"aaaaaaaaaaaaaaaaBBBBBBBBBBBBBBBBacccccccccccccccDDDDDDDDDDDDDDDD",
|
|
|
|
use_crc},
|
|
|
|
{concat,
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
"aaaaaaaaaaaaaaaaBBBBBBBBBBBBBBBBccccccccccccccccDDDDDDDDDDDDDDD",
|
|
|
|
use_crc},
|
|
|
|
{concat,
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
"aaaaaaaaaaaaaaaaBBBBBBBBBBBBBBBBccccccccccccccccDDDDDDDDDDDDDDDDe",
|
|
|
|
use_crc},
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
{concat, concat2, use_crc},
|
|
|
|
}};
|
|
|
|
|
|
|
|
for (const auto& tc : test_cases) {
|
|
|
|
VerifyComparison(tc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CompareAfterAssign) {
|
|
|
|
absl::Cord a("aaaaaa1111111");
|
|
|
|
absl::Cord b("aaaaaa2222222");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(a);
|
|
|
|
a = "cccccc";
|
|
|
|
b = "cccccc";
|
|
|
|
EXPECT_EQ(a, b);
|
|
|
|
EXPECT_FALSE(a < b);
|
|
|
|
|
|
|
|
a = "aaaa";
|
|
|
|
b = "bbbbb";
|
|
|
|
a = "";
|
|
|
|
b = "";
|
|
|
|
EXPECT_EQ(a, b);
|
|
|
|
EXPECT_FALSE(a < b);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test CompareTo() and ComparePrefix() against string and substring
|
|
|
|
// comparison methods from basic_string.
|
|
|
|
static void TestCompare(const absl::Cord& c, const absl::Cord& d,
|
|
|
|
RandomEngine* rng) {
|
|
|
|
typedef std::basic_string<uint8_t> ustring;
|
|
|
|
ustring cs(reinterpret_cast<const uint8_t*>(std::string(c).data()), c.size());
|
|
|
|
ustring ds(reinterpret_cast<const uint8_t*>(std::string(d).data()), d.size());
|
|
|
|
// ustring comparison is ideal because we expect Cord comparisons to be
|
|
|
|
// based on unsigned byte comparisons regardless of whether char is signed.
|
|
|
|
int expected = sign(cs.compare(ds));
|
|
|
|
EXPECT_EQ(expected, sign(c.Compare(d))) << c << ", " << d;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CompareComparisonIsUnsigned) {
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
std::uniform_int_distribution<uint32_t> uniform_uint8(0, 255);
|
|
|
|
char x = static_cast<char>(uniform_uint8(rng));
|
|
|
|
TestCompare(
|
|
|
|
absl::Cord(std::string(GetUniformRandomUpTo(&rng, 100), x)),
|
|
|
|
absl::Cord(std::string(GetUniformRandomUpTo(&rng, 100), x ^ 0x80)), &rng);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CompareRandomComparisons) {
|
|
|
|
const int kIters = 5000;
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
|
|
|
|
int n = GetUniformRandomUpTo(&rng, 5000);
|
|
|
|
absl::Cord a[] = {MakeExternalCord(n),
|
|
|
|
absl::Cord("ant"),
|
|
|
|
absl::Cord("elephant"),
|
|
|
|
absl::Cord("giraffe"),
|
|
|
|
absl::Cord(std::string(GetUniformRandomUpTo(&rng, 100),
|
|
|
|
GetUniformRandomUpTo(&rng, 100))),
|
|
|
|
absl::Cord(""),
|
|
|
|
absl::Cord("x"),
|
|
|
|
absl::Cord("A"),
|
|
|
|
absl::Cord("B"),
|
|
|
|
absl::Cord("C")};
|
|
|
|
for (int i = 0; i < kIters; i++) {
|
|
|
|
absl::Cord c, d;
|
|
|
|
for (int j = 0; j < (i % 7) + 1; j++) {
|
|
|
|
c.Append(a[GetUniformRandomUpTo(&rng, ABSL_ARRAYSIZE(a))]);
|
|
|
|
d.Append(a[GetUniformRandomUpTo(&rng, ABSL_ARRAYSIZE(a))]);
|
|
|
|
}
|
|
|
|
std::bernoulli_distribution coin_flip(0.5);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
MaybeHarden(d);
|
|
|
|
TestCompare(coin_flip(rng) ? c : absl::Cord(std::string(c)),
|
|
|
|
coin_flip(rng) ? d : absl::Cord(std::string(d)), &rng);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T1, typename T2>
|
|
|
|
void CompareOperators() {
|
|
|
|
const T1 a("a");
|
|
|
|
const T2 b("b");
|
|
|
|
|
|
|
|
EXPECT_TRUE(a == a);
|
|
|
|
// For pointer type (i.e. `const char*`), operator== compares the address
|
|
|
|
// instead of the string, so `a == const char*("a")` isn't necessarily true.
|
|
|
|
EXPECT_TRUE(std::is_pointer<T1>::value || a == T1("a"));
|
|
|
|
EXPECT_TRUE(std::is_pointer<T2>::value || a == T2("a"));
|
|
|
|
EXPECT_FALSE(a == b);
|
|
|
|
|
|
|
|
EXPECT_TRUE(a != b);
|
|
|
|
EXPECT_FALSE(a != a);
|
|
|
|
|
|
|
|
EXPECT_TRUE(a < b);
|
|
|
|
EXPECT_FALSE(b < a);
|
|
|
|
|
|
|
|
EXPECT_TRUE(b > a);
|
|
|
|
EXPECT_FALSE(a > b);
|
|
|
|
|
|
|
|
EXPECT_TRUE(a >= a);
|
|
|
|
EXPECT_TRUE(b >= a);
|
|
|
|
EXPECT_FALSE(a >= b);
|
|
|
|
|
|
|
|
EXPECT_TRUE(a <= a);
|
|
|
|
EXPECT_TRUE(a <= b);
|
|
|
|
EXPECT_FALSE(b <= a);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ComparisonOperators_Cord_Cord) {
|
|
|
|
CompareOperators<absl::Cord, absl::Cord>();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ComparisonOperators_Cord_StringPiece) {
|
|
|
|
CompareOperators<absl::Cord, absl::string_view>();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ComparisonOperators_StringPiece_Cord) {
|
|
|
|
CompareOperators<absl::string_view, absl::Cord>();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ComparisonOperators_Cord_string) {
|
|
|
|
CompareOperators<absl::Cord, std::string>();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ComparisonOperators_string_Cord) {
|
|
|
|
CompareOperators<std::string, absl::Cord>();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ComparisonOperators_stdstring_Cord) {
|
|
|
|
CompareOperators<std::string, absl::Cord>();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ComparisonOperators_Cord_stdstring) {
|
|
|
|
CompareOperators<absl::Cord, std::string>();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ComparisonOperators_charstar_Cord) {
|
|
|
|
CompareOperators<const char*, absl::Cord>();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ComparisonOperators_Cord_charstar) {
|
|
|
|
CompareOperators<absl::Cord, const char*>();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstructFromExternalReleaserInvoked) {
|
|
|
|
// Empty external memory means the releaser should be called immediately.
|
|
|
|
{
|
|
|
|
bool invoked = false;
|
|
|
|
auto releaser = [&invoked](absl::string_view) { invoked = true; };
|
|
|
|
{
|
|
|
|
auto c = absl::MakeCordFromExternal("", releaser);
|
|
|
|
EXPECT_TRUE(invoked);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the size of the data is small enough, a future constructor
|
|
|
|
// implementation may copy the bytes and immediately invoke the releaser
|
|
|
|
// instead of creating an external node. We make a large dummy std::string to
|
|
|
|
// make this test independent of such an optimization.
|
|
|
|
std::string large_dummy(2048, 'c');
|
|
|
|
{
|
|
|
|
bool invoked = false;
|
|
|
|
auto releaser = [&invoked](absl::string_view) { invoked = true; };
|
|
|
|
{
|
|
|
|
auto c = absl::MakeCordFromExternal(large_dummy, releaser);
|
|
|
|
EXPECT_FALSE(invoked);
|
|
|
|
}
|
|
|
|
EXPECT_TRUE(invoked);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
bool invoked = false;
|
|
|
|
auto releaser = [&invoked](absl::string_view) { invoked = true; };
|
|
|
|
{
|
|
|
|
absl::Cord copy;
|
|
|
|
{
|
|
|
|
auto c = absl::MakeCordFromExternal(large_dummy, releaser);
|
|
|
|
copy = c;
|
|
|
|
EXPECT_FALSE(invoked);
|
|
|
|
}
|
|
|
|
EXPECT_FALSE(invoked);
|
|
|
|
}
|
|
|
|
EXPECT_TRUE(invoked);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstructFromExternalCompareContents) {
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
|
|
|
|
for (int length = 1; length <= 2048; length *= 2) {
|
|
|
|
std::string data = RandomLowercaseString(&rng, length);
|
|
|
|
auto* external = new std::string(data);
|
|
|
|
auto cord =
|
|
|
|
absl::MakeCordFromExternal(*external, [external](absl::string_view sv) {
|
|
|
|
EXPECT_EQ(external->data(), sv.data());
|
|
|
|
EXPECT_EQ(external->size(), sv.size());
|
|
|
|
delete external;
|
|
|
|
});
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
|
|
|
EXPECT_EQ(data, cord);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstructFromExternalLargeReleaser) {
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
constexpr size_t kLength = 256;
|
|
|
|
std::string data = RandomLowercaseString(&rng, kLength);
|
|
|
|
std::array<char, kLength> data_array;
|
|
|
|
for (size_t i = 0; i < kLength; ++i) data_array[i] = data[i];
|
|
|
|
bool invoked = false;
|
|
|
|
auto releaser = [data_array, &invoked](absl::string_view data) {
|
|
|
|
EXPECT_EQ(data, absl::string_view(data_array.data(), data_array.size()));
|
|
|
|
invoked = true;
|
|
|
|
};
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal(data, releaser));
|
|
|
|
EXPECT_TRUE(invoked);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstructFromExternalFunctionPointerReleaser) {
|
|
|
|
static absl::string_view data("hello world");
|
|
|
|
static bool invoked;
|
|
|
|
auto* releaser =
|
|
|
|
static_cast<void (*)(absl::string_view)>([](absl::string_view sv) {
|
|
|
|
EXPECT_EQ(data, sv);
|
|
|
|
invoked = true;
|
|
|
|
});
|
|
|
|
invoked = false;
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal(data, releaser));
|
|
|
|
EXPECT_TRUE(invoked);
|
|
|
|
|
|
|
|
invoked = false;
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal(data, *releaser));
|
|
|
|
EXPECT_TRUE(invoked);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstructFromExternalMoveOnlyReleaser) {
|
|
|
|
struct Releaser {
|
|
|
|
explicit Releaser(bool* invoked) : invoked(invoked) {}
|
|
|
|
Releaser(Releaser&& other) noexcept : invoked(other.invoked) {}
|
|
|
|
void operator()(absl::string_view) const { *invoked = true; }
|
|
|
|
|
|
|
|
bool* invoked;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool invoked = false;
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal("dummy", Releaser(&invoked)));
|
|
|
|
EXPECT_TRUE(invoked);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstructFromExternalNoArgLambda) {
|
|
|
|
bool invoked = false;
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
(void)MaybeHardened(
|
|
|
|
absl::MakeCordFromExternal("dummy", [&invoked]() { invoked = true; }));
|
|
|
|
EXPECT_TRUE(invoked);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstructFromExternalStringViewArgLambda) {
|
|
|
|
bool invoked = false;
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal(
|
|
|
|
"dummy", [&invoked](absl::string_view) { invoked = true; }));
|
|
|
|
EXPECT_TRUE(invoked);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstructFromExternalNonTrivialReleaserDestructor) {
|
|
|
|
struct Releaser {
|
|
|
|
explicit Releaser(bool* destroyed) : destroyed(destroyed) {}
|
|
|
|
~Releaser() { *destroyed = true; }
|
|
|
|
void operator()(absl::string_view) const {}
|
|
|
|
|
|
|
|
bool* destroyed;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool destroyed = false;
|
|
|
|
Releaser releaser(&destroyed);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal("dummy", releaser));
|
|
|
|
EXPECT_TRUE(destroyed);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstructFromExternalReferenceQualifierOverloads) {
|
Export of internal Abseil changes
--
07240ca7822d007cdcc79f2c40bd58b2c2010348 by Abseil Team <absl-team@google.com>:
Correct the comment from "AlphaNum" to "Arg".
PiperOrigin-RevId: 416139192
--
adcba4a6b3763626e1db7b1e8c108b3114903557 by Martijn Vels <mvels@google.com>:
Fix NewExternalRep() to require data being non-empty, and remove nullptr return.
PiperOrigin-RevId: 416135865
--
c0d14cd918fb16f15d1d84de9284b5c5ecc1f8f2 by Abseil Team <absl-team@google.com>:
Fix doc comment for absl::ascii_isprint().
The comment was incorrectly saying that it includes all whitespace.
It doesn't; the only whitespace char it includes is ' '.
PiperOrigin-RevId: 416112524
--
d83327800159c07002b6865e21232a12463e02dd by Abseil Team <absl-team@google.com>:
Internal change
PiperOrigin-RevId: 416099978
--
baf11e9ca42ca9140cdbf8075f971db8d65b1195 by Ilya Tokar <tokarip@google.com>:
Prevent compiler from optimizing Group_Match* benchmarks away.
Currently we benchmark single store of precomputed value.
Not all affected benchmarks show performance changes:
BM_Group_Match 0.53ns ± 1% 0.53ns ± 0% -0.42% (p=0.038 n=10+10)
BM_Group_MatchEmpty 0.26ns ± 1% 0.26ns ± 1% ~ (p=1.000 n=10+10)
BM_Group_MatchEmptyOrDeleted 0.26ns ± 1% 0.26ns ± 1% ~ (p=0.121 n=10+10)
BM_Group_CountLeadingEmptyOrDeleted 0.26ns ± 1% 0.45ns ± 0% +70.05% (p=0.000 n=10+8)
BM_Group_MatchFirstEmptyOrDeleted 0.26ns ± 0% 0.44ns ± 1% +65.91% (p=0.000 n=8+9)
But inspecting the generated code shows the difference,
e. g. BM_Group_MatchFirstEmptyOrDeleted
Before:
add $0xffffffffffffffff,%rbx
jne 30
After:
pcmpeqd %xmm0,%xmm0
pcmpgtb -0x30(%rbp),%xmm0
pmovmskb %xmm0,%eax
add: 0x23$0xffffffffffffffff,%rbx
jne 40
PiperOrigin-RevId: 416083515
--
122fbff893dc4571b3e75e4b241eb4495b925610 by Abseil Team <absl-team@google.com>:
Put namespace guard in ABSL_DECLARE_FLAG to make declaring a flag in a namespace a compiler error instead of a linker error.
PiperOrigin-RevId: 416036072
--
020fd8a20f5fa319e948846e003391fcb9e03868 by Ilya Tokar <tokarip@google.com>:
Make Cord::InlineRep::set_data unconditionally zero out memory.
Currently there is a single case where we don't zero out memory
as an optimization. Unconditional zeroing doesn't show any changes
in benchmarks, except for the unrelated improvement:
BM_CordPartialCopyToCord/1M/1 12.6ns ± 4% 12.6ns ± 4% ~ (p=0.857 n=16+19)
BM_CordPartialCopyToCord/1M/128 44.9ns ± 7% 45.0ns ± 3% ~ (p=0.468 n=18+17)
BM_CordPartialCopyToCord/1M/1k 64.5ns ± 4% 61.4ns ± 4% -4.82% (p=0.000 n=19+17)
BM_CordPartialCopyToCord/1M/8k 139ns ± 3% 128ns ±15% -7.76% (p=0.009 n=17+20)
BM_CordPartialCopyToCord/1M/16k 193ns ± 6% 168ns ± 6% -13.17% (p=0.000 n=17+17)
BM_CordPartialCopyToCord/4M/16k 199ns ± 4% 177ns ± 4% -11.36% (p=0.000 n=17+18)
BM_CordPartialCopyToCord/4M/32k 275ns ± 3% 250ns ± 4% -9.00% (p=0.000 n=18+18)
BM_CordPartialCopyToCord/4M/64k 291ns ± 4% 266ns ± 5% -8.53% (p=0.000 n=18+16)
BM_CordPartialCopyToCord/4M/128k 322ns ± 5% 291ns ± 4% -9.43% (p=0.000 n=20+18)
BM_CordPartialCopyToCord/8M/32k 281ns ± 5% 251ns ± 4% -10.38% (p=0.000 n=20+16)
BM_CordPartialCopyToCord/8M/64k 293ns ± 6% 267ns ± 4% -8.87% (p=0.000 n=16+19)
BM_CordPartialCopyToCord/8M/128k 334ns ± 3% 305ns ± 2% -8.56% (p=0.000 n=17+16)
This is clearly an alignmnet effect since number of the executed instructions is the same:
M_CordPartialCopyToCord/1M/1 155 ± 0% 155 ± 0% ~ (all samples are equal)
BM_CordPartialCopyToCord/1M/128 446 ± 0% 446 ± 0% ~ (p=0.332 n=36+39)
BM_CordPartialCopyToCord/1M/1k 473 ± 0% 473 ± 0% ~ (p=0.969 n=40+40)
BM_CordPartialCopyToCord/1M/8k 808 ± 0% 808 ± 0% ~ (p=0.127 n=40+39)
BM_CordPartialCopyToCord/1M/16k 957 ± 0% 957 ± 0% ~ (p=0.532 n=40+40)
BM_CordPartialCopyToCord/4M/16k 952 ± 0% 952 ± 0% ~ (p=0.686 n=39+39)
BM_CordPartialCopyToCord/4M/32k 1.12k ± 0% 1.12k ± 0% ~ (p=0.690 n=40+40)
BM_CordPartialCopyToCord/4M/64k 1.23k ± 0% 1.23k ± 0% ~ (p=0.182 n=40+39)
BM_CordPartialCopyToCord/4M/128k 1.44k ± 0% 1.44k ± 0% ~ (p=0.711 n=40+40)
BM_CordPartialCopyToCord/8M/32k 1.12k ± 0% 1.12k ± 0% ~ (p=0.697 n=40+40)
BM_CordPartialCopyToCord/8M/64k 1.23k ± 0% 1.23k ± 0% +0.00% (p=0.049 n=40+40)
BM_CordPartialCopyToCord/8M/128k 1.44k ± 0% 1.44k ± 0% ~ (p=0.507 n=40+40)
This makes code simpler and doesn't regress performance.
PiperOrigin-RevId: 415560574
--
37305b2690b31682088749e4d62f40d7095bdc54 by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 415558737
--
86aaed569b9e743c1eb813a5f48def978a793db3 by Martijn Vels <mvels@google.com>:
Internal change
PiperOrigin-RevId: 415515201
--
6cdb8786cdcb4fa0b8a4b72fc98940877d1fdeff by Abseil Team <absl-team@google.com>:
Update SubmitMutexProfileData to accept wait_cycles instead of wait_timestamp
PiperOrigin-RevId: 415360871
--
9f979d307aa16ad09f214e04876cbe84395c0901 by Abseil Team <absl-team@google.com>:
absl::flat_hash_set compiles with -Wconversion -Wsign-compare
PiperOrigin-RevId: 415357498
--
9eceb14174708f15e61259d449b214a8a4c7f9e7 by Abseil Team <absl-team@google.com>:
Fix AddressIsReadable for the corner case of (aligned) addr == NULL.
PiperOrigin-RevId: 415307792
--
1a39ffe55898375e2d7f88c17c99db5a1b95b313 by Martijn Vels <mvels@google.com>:
Internal change
PiperOrigin-RevId: 415162872
--
64378549b110d5f5762185a5906c520fba70f0e7 by Abseil Team <absl-team@google.com>:
Fix a typo in the comments
PiperOrigin-RevId: 415088461
--
41aae8322e913b82710153c22b97c611fdb6e1fb by Abseil Team <absl-team@google.com>:
Switch from `connect` to `rt_sigreturn` -- the latter is much less problematic
for system call sandboxes.
PiperOrigin-RevId: 415073965
--
870c5e3388b6a35611bff538626fe7a1c8c87171 by Abseil Team <absl-team@google.com>:
Add ABSL_HAVE_HWADDRESS_SANITIZER and ABSL_HAVE_LEAK_SANITIZER
PiperOrigin-RevId: 414871189
--
f213ed60a66b58da7ac40555adfb1d529ff0a4db by Derek Mauro <dmauro@google.com>:
Remove reference to __SANITIZE_MEMORY__, which does not exist
It appears to have been copied by pattern matching from the ASAN/TSAN
code blocks.
https://github.com/gcc-mirror/gcc/blob/f47662204de27f7685699eeef89aa173ccf32d85/gcc/cppbuiltin.c#L79-L126
PiperOrigin-RevId: 414806587
--
b152891e73ab515f397ceb53f66c8ee2f33863ea by Abseil Team <absl-team@google.com>:
Rollback previous commit: SYS_open is not defined in certain environments.
PiperOrigin-RevId: 414521820
--
5a1cbb282331023902e1374dd0d920c4effbe47f by Abseil Team <absl-team@google.com>:
Use syscall(SYS_open, ...) instead of open() to avoid possible symbol
interposition.
Also add some warning notes.
PiperOrigin-RevId: 414508186
--
1824d6593612710aafdc599a89b0adced7d787f6 by Abseil Team <absl-team@google.com>:
Correct aarch64 macro check
The macro is __aarch64__, not __arch64__.
PiperOrigin-RevId: 414446225
--
a1536a57b64dfd53945d33a01cfc08b18c99c97b by Abseil Team <absl-team@google.com>:
Fix backwards comment in the last commit.
PiperOrigin-RevId: 414281214
--
11ac021ba779513667a31cf2563ddafc57d6d913 by Abseil Team <absl-team@google.com>:
AddressIsReadable() didn't work correctly on ARM when the given pointer was
misaligned at the end of the page.
Fix that by aligning the pointer on an 8-byte boundary before checking it.
PiperOrigin-RevId: 414203863
GitOrigin-RevId: 07240ca7822d007cdcc79f2c40bd58b2c2010348
Change-Id: If5f129194d59f5c9e5d84efd8cd9e17a70e072ab
3 years ago
|
|
|
enum InvokedAs { kMissing, kLValue, kRValue };
|
|
|
|
enum CopiedAs { kNone, kMove, kCopy };
|
|
|
|
struct Tracker {
|
|
|
|
CopiedAs copied_as = kNone;
|
|
|
|
InvokedAs invoked_as = kMissing;
|
|
|
|
|
|
|
|
void Record(InvokedAs rhs) {
|
|
|
|
ASSERT_EQ(invoked_as, kMissing);
|
|
|
|
invoked_as = rhs;
|
|
|
|
}
|
|
|
|
|
Export of internal Abseil changes
--
07240ca7822d007cdcc79f2c40bd58b2c2010348 by Abseil Team <absl-team@google.com>:
Correct the comment from "AlphaNum" to "Arg".
PiperOrigin-RevId: 416139192
--
adcba4a6b3763626e1db7b1e8c108b3114903557 by Martijn Vels <mvels@google.com>:
Fix NewExternalRep() to require data being non-empty, and remove nullptr return.
PiperOrigin-RevId: 416135865
--
c0d14cd918fb16f15d1d84de9284b5c5ecc1f8f2 by Abseil Team <absl-team@google.com>:
Fix doc comment for absl::ascii_isprint().
The comment was incorrectly saying that it includes all whitespace.
It doesn't; the only whitespace char it includes is ' '.
PiperOrigin-RevId: 416112524
--
d83327800159c07002b6865e21232a12463e02dd by Abseil Team <absl-team@google.com>:
Internal change
PiperOrigin-RevId: 416099978
--
baf11e9ca42ca9140cdbf8075f971db8d65b1195 by Ilya Tokar <tokarip@google.com>:
Prevent compiler from optimizing Group_Match* benchmarks away.
Currently we benchmark single store of precomputed value.
Not all affected benchmarks show performance changes:
BM_Group_Match 0.53ns ± 1% 0.53ns ± 0% -0.42% (p=0.038 n=10+10)
BM_Group_MatchEmpty 0.26ns ± 1% 0.26ns ± 1% ~ (p=1.000 n=10+10)
BM_Group_MatchEmptyOrDeleted 0.26ns ± 1% 0.26ns ± 1% ~ (p=0.121 n=10+10)
BM_Group_CountLeadingEmptyOrDeleted 0.26ns ± 1% 0.45ns ± 0% +70.05% (p=0.000 n=10+8)
BM_Group_MatchFirstEmptyOrDeleted 0.26ns ± 0% 0.44ns ± 1% +65.91% (p=0.000 n=8+9)
But inspecting the generated code shows the difference,
e. g. BM_Group_MatchFirstEmptyOrDeleted
Before:
add $0xffffffffffffffff,%rbx
jne 30
After:
pcmpeqd %xmm0,%xmm0
pcmpgtb -0x30(%rbp),%xmm0
pmovmskb %xmm0,%eax
add: 0x23$0xffffffffffffffff,%rbx
jne 40
PiperOrigin-RevId: 416083515
--
122fbff893dc4571b3e75e4b241eb4495b925610 by Abseil Team <absl-team@google.com>:
Put namespace guard in ABSL_DECLARE_FLAG to make declaring a flag in a namespace a compiler error instead of a linker error.
PiperOrigin-RevId: 416036072
--
020fd8a20f5fa319e948846e003391fcb9e03868 by Ilya Tokar <tokarip@google.com>:
Make Cord::InlineRep::set_data unconditionally zero out memory.
Currently there is a single case where we don't zero out memory
as an optimization. Unconditional zeroing doesn't show any changes
in benchmarks, except for the unrelated improvement:
BM_CordPartialCopyToCord/1M/1 12.6ns ± 4% 12.6ns ± 4% ~ (p=0.857 n=16+19)
BM_CordPartialCopyToCord/1M/128 44.9ns ± 7% 45.0ns ± 3% ~ (p=0.468 n=18+17)
BM_CordPartialCopyToCord/1M/1k 64.5ns ± 4% 61.4ns ± 4% -4.82% (p=0.000 n=19+17)
BM_CordPartialCopyToCord/1M/8k 139ns ± 3% 128ns ±15% -7.76% (p=0.009 n=17+20)
BM_CordPartialCopyToCord/1M/16k 193ns ± 6% 168ns ± 6% -13.17% (p=0.000 n=17+17)
BM_CordPartialCopyToCord/4M/16k 199ns ± 4% 177ns ± 4% -11.36% (p=0.000 n=17+18)
BM_CordPartialCopyToCord/4M/32k 275ns ± 3% 250ns ± 4% -9.00% (p=0.000 n=18+18)
BM_CordPartialCopyToCord/4M/64k 291ns ± 4% 266ns ± 5% -8.53% (p=0.000 n=18+16)
BM_CordPartialCopyToCord/4M/128k 322ns ± 5% 291ns ± 4% -9.43% (p=0.000 n=20+18)
BM_CordPartialCopyToCord/8M/32k 281ns ± 5% 251ns ± 4% -10.38% (p=0.000 n=20+16)
BM_CordPartialCopyToCord/8M/64k 293ns ± 6% 267ns ± 4% -8.87% (p=0.000 n=16+19)
BM_CordPartialCopyToCord/8M/128k 334ns ± 3% 305ns ± 2% -8.56% (p=0.000 n=17+16)
This is clearly an alignmnet effect since number of the executed instructions is the same:
M_CordPartialCopyToCord/1M/1 155 ± 0% 155 ± 0% ~ (all samples are equal)
BM_CordPartialCopyToCord/1M/128 446 ± 0% 446 ± 0% ~ (p=0.332 n=36+39)
BM_CordPartialCopyToCord/1M/1k 473 ± 0% 473 ± 0% ~ (p=0.969 n=40+40)
BM_CordPartialCopyToCord/1M/8k 808 ± 0% 808 ± 0% ~ (p=0.127 n=40+39)
BM_CordPartialCopyToCord/1M/16k 957 ± 0% 957 ± 0% ~ (p=0.532 n=40+40)
BM_CordPartialCopyToCord/4M/16k 952 ± 0% 952 ± 0% ~ (p=0.686 n=39+39)
BM_CordPartialCopyToCord/4M/32k 1.12k ± 0% 1.12k ± 0% ~ (p=0.690 n=40+40)
BM_CordPartialCopyToCord/4M/64k 1.23k ± 0% 1.23k ± 0% ~ (p=0.182 n=40+39)
BM_CordPartialCopyToCord/4M/128k 1.44k ± 0% 1.44k ± 0% ~ (p=0.711 n=40+40)
BM_CordPartialCopyToCord/8M/32k 1.12k ± 0% 1.12k ± 0% ~ (p=0.697 n=40+40)
BM_CordPartialCopyToCord/8M/64k 1.23k ± 0% 1.23k ± 0% +0.00% (p=0.049 n=40+40)
BM_CordPartialCopyToCord/8M/128k 1.44k ± 0% 1.44k ± 0% ~ (p=0.507 n=40+40)
This makes code simpler and doesn't regress performance.
PiperOrigin-RevId: 415560574
--
37305b2690b31682088749e4d62f40d7095bdc54 by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 415558737
--
86aaed569b9e743c1eb813a5f48def978a793db3 by Martijn Vels <mvels@google.com>:
Internal change
PiperOrigin-RevId: 415515201
--
6cdb8786cdcb4fa0b8a4b72fc98940877d1fdeff by Abseil Team <absl-team@google.com>:
Update SubmitMutexProfileData to accept wait_cycles instead of wait_timestamp
PiperOrigin-RevId: 415360871
--
9f979d307aa16ad09f214e04876cbe84395c0901 by Abseil Team <absl-team@google.com>:
absl::flat_hash_set compiles with -Wconversion -Wsign-compare
PiperOrigin-RevId: 415357498
--
9eceb14174708f15e61259d449b214a8a4c7f9e7 by Abseil Team <absl-team@google.com>:
Fix AddressIsReadable for the corner case of (aligned) addr == NULL.
PiperOrigin-RevId: 415307792
--
1a39ffe55898375e2d7f88c17c99db5a1b95b313 by Martijn Vels <mvels@google.com>:
Internal change
PiperOrigin-RevId: 415162872
--
64378549b110d5f5762185a5906c520fba70f0e7 by Abseil Team <absl-team@google.com>:
Fix a typo in the comments
PiperOrigin-RevId: 415088461
--
41aae8322e913b82710153c22b97c611fdb6e1fb by Abseil Team <absl-team@google.com>:
Switch from `connect` to `rt_sigreturn` -- the latter is much less problematic
for system call sandboxes.
PiperOrigin-RevId: 415073965
--
870c5e3388b6a35611bff538626fe7a1c8c87171 by Abseil Team <absl-team@google.com>:
Add ABSL_HAVE_HWADDRESS_SANITIZER and ABSL_HAVE_LEAK_SANITIZER
PiperOrigin-RevId: 414871189
--
f213ed60a66b58da7ac40555adfb1d529ff0a4db by Derek Mauro <dmauro@google.com>:
Remove reference to __SANITIZE_MEMORY__, which does not exist
It appears to have been copied by pattern matching from the ASAN/TSAN
code blocks.
https://github.com/gcc-mirror/gcc/blob/f47662204de27f7685699eeef89aa173ccf32d85/gcc/cppbuiltin.c#L79-L126
PiperOrigin-RevId: 414806587
--
b152891e73ab515f397ceb53f66c8ee2f33863ea by Abseil Team <absl-team@google.com>:
Rollback previous commit: SYS_open is not defined in certain environments.
PiperOrigin-RevId: 414521820
--
5a1cbb282331023902e1374dd0d920c4effbe47f by Abseil Team <absl-team@google.com>:
Use syscall(SYS_open, ...) instead of open() to avoid possible symbol
interposition.
Also add some warning notes.
PiperOrigin-RevId: 414508186
--
1824d6593612710aafdc599a89b0adced7d787f6 by Abseil Team <absl-team@google.com>:
Correct aarch64 macro check
The macro is __aarch64__, not __arch64__.
PiperOrigin-RevId: 414446225
--
a1536a57b64dfd53945d33a01cfc08b18c99c97b by Abseil Team <absl-team@google.com>:
Fix backwards comment in the last commit.
PiperOrigin-RevId: 414281214
--
11ac021ba779513667a31cf2563ddafc57d6d913 by Abseil Team <absl-team@google.com>:
AddressIsReadable() didn't work correctly on ARM when the given pointer was
misaligned at the end of the page.
Fix that by aligning the pointer on an 8-byte boundary before checking it.
PiperOrigin-RevId: 414203863
GitOrigin-RevId: 07240ca7822d007cdcc79f2c40bd58b2c2010348
Change-Id: If5f129194d59f5c9e5d84efd8cd9e17a70e072ab
3 years ago
|
|
|
void Record(CopiedAs rhs) {
|
|
|
|
if (copied_as == kNone || rhs == kCopy) copied_as = rhs;
|
|
|
|
}
|
|
|
|
} tracker;
|
|
|
|
|
Export of internal Abseil changes
--
07240ca7822d007cdcc79f2c40bd58b2c2010348 by Abseil Team <absl-team@google.com>:
Correct the comment from "AlphaNum" to "Arg".
PiperOrigin-RevId: 416139192
--
adcba4a6b3763626e1db7b1e8c108b3114903557 by Martijn Vels <mvels@google.com>:
Fix NewExternalRep() to require data being non-empty, and remove nullptr return.
PiperOrigin-RevId: 416135865
--
c0d14cd918fb16f15d1d84de9284b5c5ecc1f8f2 by Abseil Team <absl-team@google.com>:
Fix doc comment for absl::ascii_isprint().
The comment was incorrectly saying that it includes all whitespace.
It doesn't; the only whitespace char it includes is ' '.
PiperOrigin-RevId: 416112524
--
d83327800159c07002b6865e21232a12463e02dd by Abseil Team <absl-team@google.com>:
Internal change
PiperOrigin-RevId: 416099978
--
baf11e9ca42ca9140cdbf8075f971db8d65b1195 by Ilya Tokar <tokarip@google.com>:
Prevent compiler from optimizing Group_Match* benchmarks away.
Currently we benchmark single store of precomputed value.
Not all affected benchmarks show performance changes:
BM_Group_Match 0.53ns ± 1% 0.53ns ± 0% -0.42% (p=0.038 n=10+10)
BM_Group_MatchEmpty 0.26ns ± 1% 0.26ns ± 1% ~ (p=1.000 n=10+10)
BM_Group_MatchEmptyOrDeleted 0.26ns ± 1% 0.26ns ± 1% ~ (p=0.121 n=10+10)
BM_Group_CountLeadingEmptyOrDeleted 0.26ns ± 1% 0.45ns ± 0% +70.05% (p=0.000 n=10+8)
BM_Group_MatchFirstEmptyOrDeleted 0.26ns ± 0% 0.44ns ± 1% +65.91% (p=0.000 n=8+9)
But inspecting the generated code shows the difference,
e. g. BM_Group_MatchFirstEmptyOrDeleted
Before:
add $0xffffffffffffffff,%rbx
jne 30
After:
pcmpeqd %xmm0,%xmm0
pcmpgtb -0x30(%rbp),%xmm0
pmovmskb %xmm0,%eax
add: 0x23$0xffffffffffffffff,%rbx
jne 40
PiperOrigin-RevId: 416083515
--
122fbff893dc4571b3e75e4b241eb4495b925610 by Abseil Team <absl-team@google.com>:
Put namespace guard in ABSL_DECLARE_FLAG to make declaring a flag in a namespace a compiler error instead of a linker error.
PiperOrigin-RevId: 416036072
--
020fd8a20f5fa319e948846e003391fcb9e03868 by Ilya Tokar <tokarip@google.com>:
Make Cord::InlineRep::set_data unconditionally zero out memory.
Currently there is a single case where we don't zero out memory
as an optimization. Unconditional zeroing doesn't show any changes
in benchmarks, except for the unrelated improvement:
BM_CordPartialCopyToCord/1M/1 12.6ns ± 4% 12.6ns ± 4% ~ (p=0.857 n=16+19)
BM_CordPartialCopyToCord/1M/128 44.9ns ± 7% 45.0ns ± 3% ~ (p=0.468 n=18+17)
BM_CordPartialCopyToCord/1M/1k 64.5ns ± 4% 61.4ns ± 4% -4.82% (p=0.000 n=19+17)
BM_CordPartialCopyToCord/1M/8k 139ns ± 3% 128ns ±15% -7.76% (p=0.009 n=17+20)
BM_CordPartialCopyToCord/1M/16k 193ns ± 6% 168ns ± 6% -13.17% (p=0.000 n=17+17)
BM_CordPartialCopyToCord/4M/16k 199ns ± 4% 177ns ± 4% -11.36% (p=0.000 n=17+18)
BM_CordPartialCopyToCord/4M/32k 275ns ± 3% 250ns ± 4% -9.00% (p=0.000 n=18+18)
BM_CordPartialCopyToCord/4M/64k 291ns ± 4% 266ns ± 5% -8.53% (p=0.000 n=18+16)
BM_CordPartialCopyToCord/4M/128k 322ns ± 5% 291ns ± 4% -9.43% (p=0.000 n=20+18)
BM_CordPartialCopyToCord/8M/32k 281ns ± 5% 251ns ± 4% -10.38% (p=0.000 n=20+16)
BM_CordPartialCopyToCord/8M/64k 293ns ± 6% 267ns ± 4% -8.87% (p=0.000 n=16+19)
BM_CordPartialCopyToCord/8M/128k 334ns ± 3% 305ns ± 2% -8.56% (p=0.000 n=17+16)
This is clearly an alignmnet effect since number of the executed instructions is the same:
M_CordPartialCopyToCord/1M/1 155 ± 0% 155 ± 0% ~ (all samples are equal)
BM_CordPartialCopyToCord/1M/128 446 ± 0% 446 ± 0% ~ (p=0.332 n=36+39)
BM_CordPartialCopyToCord/1M/1k 473 ± 0% 473 ± 0% ~ (p=0.969 n=40+40)
BM_CordPartialCopyToCord/1M/8k 808 ± 0% 808 ± 0% ~ (p=0.127 n=40+39)
BM_CordPartialCopyToCord/1M/16k 957 ± 0% 957 ± 0% ~ (p=0.532 n=40+40)
BM_CordPartialCopyToCord/4M/16k 952 ± 0% 952 ± 0% ~ (p=0.686 n=39+39)
BM_CordPartialCopyToCord/4M/32k 1.12k ± 0% 1.12k ± 0% ~ (p=0.690 n=40+40)
BM_CordPartialCopyToCord/4M/64k 1.23k ± 0% 1.23k ± 0% ~ (p=0.182 n=40+39)
BM_CordPartialCopyToCord/4M/128k 1.44k ± 0% 1.44k ± 0% ~ (p=0.711 n=40+40)
BM_CordPartialCopyToCord/8M/32k 1.12k ± 0% 1.12k ± 0% ~ (p=0.697 n=40+40)
BM_CordPartialCopyToCord/8M/64k 1.23k ± 0% 1.23k ± 0% +0.00% (p=0.049 n=40+40)
BM_CordPartialCopyToCord/8M/128k 1.44k ± 0% 1.44k ± 0% ~ (p=0.507 n=40+40)
This makes code simpler and doesn't regress performance.
PiperOrigin-RevId: 415560574
--
37305b2690b31682088749e4d62f40d7095bdc54 by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 415558737
--
86aaed569b9e743c1eb813a5f48def978a793db3 by Martijn Vels <mvels@google.com>:
Internal change
PiperOrigin-RevId: 415515201
--
6cdb8786cdcb4fa0b8a4b72fc98940877d1fdeff by Abseil Team <absl-team@google.com>:
Update SubmitMutexProfileData to accept wait_cycles instead of wait_timestamp
PiperOrigin-RevId: 415360871
--
9f979d307aa16ad09f214e04876cbe84395c0901 by Abseil Team <absl-team@google.com>:
absl::flat_hash_set compiles with -Wconversion -Wsign-compare
PiperOrigin-RevId: 415357498
--
9eceb14174708f15e61259d449b214a8a4c7f9e7 by Abseil Team <absl-team@google.com>:
Fix AddressIsReadable for the corner case of (aligned) addr == NULL.
PiperOrigin-RevId: 415307792
--
1a39ffe55898375e2d7f88c17c99db5a1b95b313 by Martijn Vels <mvels@google.com>:
Internal change
PiperOrigin-RevId: 415162872
--
64378549b110d5f5762185a5906c520fba70f0e7 by Abseil Team <absl-team@google.com>:
Fix a typo in the comments
PiperOrigin-RevId: 415088461
--
41aae8322e913b82710153c22b97c611fdb6e1fb by Abseil Team <absl-team@google.com>:
Switch from `connect` to `rt_sigreturn` -- the latter is much less problematic
for system call sandboxes.
PiperOrigin-RevId: 415073965
--
870c5e3388b6a35611bff538626fe7a1c8c87171 by Abseil Team <absl-team@google.com>:
Add ABSL_HAVE_HWADDRESS_SANITIZER and ABSL_HAVE_LEAK_SANITIZER
PiperOrigin-RevId: 414871189
--
f213ed60a66b58da7ac40555adfb1d529ff0a4db by Derek Mauro <dmauro@google.com>:
Remove reference to __SANITIZE_MEMORY__, which does not exist
It appears to have been copied by pattern matching from the ASAN/TSAN
code blocks.
https://github.com/gcc-mirror/gcc/blob/f47662204de27f7685699eeef89aa173ccf32d85/gcc/cppbuiltin.c#L79-L126
PiperOrigin-RevId: 414806587
--
b152891e73ab515f397ceb53f66c8ee2f33863ea by Abseil Team <absl-team@google.com>:
Rollback previous commit: SYS_open is not defined in certain environments.
PiperOrigin-RevId: 414521820
--
5a1cbb282331023902e1374dd0d920c4effbe47f by Abseil Team <absl-team@google.com>:
Use syscall(SYS_open, ...) instead of open() to avoid possible symbol
interposition.
Also add some warning notes.
PiperOrigin-RevId: 414508186
--
1824d6593612710aafdc599a89b0adced7d787f6 by Abseil Team <absl-team@google.com>:
Correct aarch64 macro check
The macro is __aarch64__, not __arch64__.
PiperOrigin-RevId: 414446225
--
a1536a57b64dfd53945d33a01cfc08b18c99c97b by Abseil Team <absl-team@google.com>:
Fix backwards comment in the last commit.
PiperOrigin-RevId: 414281214
--
11ac021ba779513667a31cf2563ddafc57d6d913 by Abseil Team <absl-team@google.com>:
AddressIsReadable() didn't work correctly on ARM when the given pointer was
misaligned at the end of the page.
Fix that by aligning the pointer on an 8-byte boundary before checking it.
PiperOrigin-RevId: 414203863
GitOrigin-RevId: 07240ca7822d007cdcc79f2c40bd58b2c2010348
Change-Id: If5f129194d59f5c9e5d84efd8cd9e17a70e072ab
3 years ago
|
|
|
class Releaser {
|
|
|
|
public:
|
|
|
|
explicit Releaser(Tracker* tracker) : tr_(tracker) { *tracker = Tracker(); }
|
|
|
|
Releaser(Releaser&& rhs) : tr_(rhs.tr_) { tr_->Record(kMove); }
|
|
|
|
Releaser(const Releaser& rhs) : tr_(rhs.tr_) { tr_->Record(kCopy); }
|
|
|
|
|
Export of internal Abseil changes
--
07240ca7822d007cdcc79f2c40bd58b2c2010348 by Abseil Team <absl-team@google.com>:
Correct the comment from "AlphaNum" to "Arg".
PiperOrigin-RevId: 416139192
--
adcba4a6b3763626e1db7b1e8c108b3114903557 by Martijn Vels <mvels@google.com>:
Fix NewExternalRep() to require data being non-empty, and remove nullptr return.
PiperOrigin-RevId: 416135865
--
c0d14cd918fb16f15d1d84de9284b5c5ecc1f8f2 by Abseil Team <absl-team@google.com>:
Fix doc comment for absl::ascii_isprint().
The comment was incorrectly saying that it includes all whitespace.
It doesn't; the only whitespace char it includes is ' '.
PiperOrigin-RevId: 416112524
--
d83327800159c07002b6865e21232a12463e02dd by Abseil Team <absl-team@google.com>:
Internal change
PiperOrigin-RevId: 416099978
--
baf11e9ca42ca9140cdbf8075f971db8d65b1195 by Ilya Tokar <tokarip@google.com>:
Prevent compiler from optimizing Group_Match* benchmarks away.
Currently we benchmark single store of precomputed value.
Not all affected benchmarks show performance changes:
BM_Group_Match 0.53ns ± 1% 0.53ns ± 0% -0.42% (p=0.038 n=10+10)
BM_Group_MatchEmpty 0.26ns ± 1% 0.26ns ± 1% ~ (p=1.000 n=10+10)
BM_Group_MatchEmptyOrDeleted 0.26ns ± 1% 0.26ns ± 1% ~ (p=0.121 n=10+10)
BM_Group_CountLeadingEmptyOrDeleted 0.26ns ± 1% 0.45ns ± 0% +70.05% (p=0.000 n=10+8)
BM_Group_MatchFirstEmptyOrDeleted 0.26ns ± 0% 0.44ns ± 1% +65.91% (p=0.000 n=8+9)
But inspecting the generated code shows the difference,
e. g. BM_Group_MatchFirstEmptyOrDeleted
Before:
add $0xffffffffffffffff,%rbx
jne 30
After:
pcmpeqd %xmm0,%xmm0
pcmpgtb -0x30(%rbp),%xmm0
pmovmskb %xmm0,%eax
add: 0x23$0xffffffffffffffff,%rbx
jne 40
PiperOrigin-RevId: 416083515
--
122fbff893dc4571b3e75e4b241eb4495b925610 by Abseil Team <absl-team@google.com>:
Put namespace guard in ABSL_DECLARE_FLAG to make declaring a flag in a namespace a compiler error instead of a linker error.
PiperOrigin-RevId: 416036072
--
020fd8a20f5fa319e948846e003391fcb9e03868 by Ilya Tokar <tokarip@google.com>:
Make Cord::InlineRep::set_data unconditionally zero out memory.
Currently there is a single case where we don't zero out memory
as an optimization. Unconditional zeroing doesn't show any changes
in benchmarks, except for the unrelated improvement:
BM_CordPartialCopyToCord/1M/1 12.6ns ± 4% 12.6ns ± 4% ~ (p=0.857 n=16+19)
BM_CordPartialCopyToCord/1M/128 44.9ns ± 7% 45.0ns ± 3% ~ (p=0.468 n=18+17)
BM_CordPartialCopyToCord/1M/1k 64.5ns ± 4% 61.4ns ± 4% -4.82% (p=0.000 n=19+17)
BM_CordPartialCopyToCord/1M/8k 139ns ± 3% 128ns ±15% -7.76% (p=0.009 n=17+20)
BM_CordPartialCopyToCord/1M/16k 193ns ± 6% 168ns ± 6% -13.17% (p=0.000 n=17+17)
BM_CordPartialCopyToCord/4M/16k 199ns ± 4% 177ns ± 4% -11.36% (p=0.000 n=17+18)
BM_CordPartialCopyToCord/4M/32k 275ns ± 3% 250ns ± 4% -9.00% (p=0.000 n=18+18)
BM_CordPartialCopyToCord/4M/64k 291ns ± 4% 266ns ± 5% -8.53% (p=0.000 n=18+16)
BM_CordPartialCopyToCord/4M/128k 322ns ± 5% 291ns ± 4% -9.43% (p=0.000 n=20+18)
BM_CordPartialCopyToCord/8M/32k 281ns ± 5% 251ns ± 4% -10.38% (p=0.000 n=20+16)
BM_CordPartialCopyToCord/8M/64k 293ns ± 6% 267ns ± 4% -8.87% (p=0.000 n=16+19)
BM_CordPartialCopyToCord/8M/128k 334ns ± 3% 305ns ± 2% -8.56% (p=0.000 n=17+16)
This is clearly an alignmnet effect since number of the executed instructions is the same:
M_CordPartialCopyToCord/1M/1 155 ± 0% 155 ± 0% ~ (all samples are equal)
BM_CordPartialCopyToCord/1M/128 446 ± 0% 446 ± 0% ~ (p=0.332 n=36+39)
BM_CordPartialCopyToCord/1M/1k 473 ± 0% 473 ± 0% ~ (p=0.969 n=40+40)
BM_CordPartialCopyToCord/1M/8k 808 ± 0% 808 ± 0% ~ (p=0.127 n=40+39)
BM_CordPartialCopyToCord/1M/16k 957 ± 0% 957 ± 0% ~ (p=0.532 n=40+40)
BM_CordPartialCopyToCord/4M/16k 952 ± 0% 952 ± 0% ~ (p=0.686 n=39+39)
BM_CordPartialCopyToCord/4M/32k 1.12k ± 0% 1.12k ± 0% ~ (p=0.690 n=40+40)
BM_CordPartialCopyToCord/4M/64k 1.23k ± 0% 1.23k ± 0% ~ (p=0.182 n=40+39)
BM_CordPartialCopyToCord/4M/128k 1.44k ± 0% 1.44k ± 0% ~ (p=0.711 n=40+40)
BM_CordPartialCopyToCord/8M/32k 1.12k ± 0% 1.12k ± 0% ~ (p=0.697 n=40+40)
BM_CordPartialCopyToCord/8M/64k 1.23k ± 0% 1.23k ± 0% +0.00% (p=0.049 n=40+40)
BM_CordPartialCopyToCord/8M/128k 1.44k ± 0% 1.44k ± 0% ~ (p=0.507 n=40+40)
This makes code simpler and doesn't regress performance.
PiperOrigin-RevId: 415560574
--
37305b2690b31682088749e4d62f40d7095bdc54 by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 415558737
--
86aaed569b9e743c1eb813a5f48def978a793db3 by Martijn Vels <mvels@google.com>:
Internal change
PiperOrigin-RevId: 415515201
--
6cdb8786cdcb4fa0b8a4b72fc98940877d1fdeff by Abseil Team <absl-team@google.com>:
Update SubmitMutexProfileData to accept wait_cycles instead of wait_timestamp
PiperOrigin-RevId: 415360871
--
9f979d307aa16ad09f214e04876cbe84395c0901 by Abseil Team <absl-team@google.com>:
absl::flat_hash_set compiles with -Wconversion -Wsign-compare
PiperOrigin-RevId: 415357498
--
9eceb14174708f15e61259d449b214a8a4c7f9e7 by Abseil Team <absl-team@google.com>:
Fix AddressIsReadable for the corner case of (aligned) addr == NULL.
PiperOrigin-RevId: 415307792
--
1a39ffe55898375e2d7f88c17c99db5a1b95b313 by Martijn Vels <mvels@google.com>:
Internal change
PiperOrigin-RevId: 415162872
--
64378549b110d5f5762185a5906c520fba70f0e7 by Abseil Team <absl-team@google.com>:
Fix a typo in the comments
PiperOrigin-RevId: 415088461
--
41aae8322e913b82710153c22b97c611fdb6e1fb by Abseil Team <absl-team@google.com>:
Switch from `connect` to `rt_sigreturn` -- the latter is much less problematic
for system call sandboxes.
PiperOrigin-RevId: 415073965
--
870c5e3388b6a35611bff538626fe7a1c8c87171 by Abseil Team <absl-team@google.com>:
Add ABSL_HAVE_HWADDRESS_SANITIZER and ABSL_HAVE_LEAK_SANITIZER
PiperOrigin-RevId: 414871189
--
f213ed60a66b58da7ac40555adfb1d529ff0a4db by Derek Mauro <dmauro@google.com>:
Remove reference to __SANITIZE_MEMORY__, which does not exist
It appears to have been copied by pattern matching from the ASAN/TSAN
code blocks.
https://github.com/gcc-mirror/gcc/blob/f47662204de27f7685699eeef89aa173ccf32d85/gcc/cppbuiltin.c#L79-L126
PiperOrigin-RevId: 414806587
--
b152891e73ab515f397ceb53f66c8ee2f33863ea by Abseil Team <absl-team@google.com>:
Rollback previous commit: SYS_open is not defined in certain environments.
PiperOrigin-RevId: 414521820
--
5a1cbb282331023902e1374dd0d920c4effbe47f by Abseil Team <absl-team@google.com>:
Use syscall(SYS_open, ...) instead of open() to avoid possible symbol
interposition.
Also add some warning notes.
PiperOrigin-RevId: 414508186
--
1824d6593612710aafdc599a89b0adced7d787f6 by Abseil Team <absl-team@google.com>:
Correct aarch64 macro check
The macro is __aarch64__, not __arch64__.
PiperOrigin-RevId: 414446225
--
a1536a57b64dfd53945d33a01cfc08b18c99c97b by Abseil Team <absl-team@google.com>:
Fix backwards comment in the last commit.
PiperOrigin-RevId: 414281214
--
11ac021ba779513667a31cf2563ddafc57d6d913 by Abseil Team <absl-team@google.com>:
AddressIsReadable() didn't work correctly on ARM when the given pointer was
misaligned at the end of the page.
Fix that by aligning the pointer on an 8-byte boundary before checking it.
PiperOrigin-RevId: 414203863
GitOrigin-RevId: 07240ca7822d007cdcc79f2c40bd58b2c2010348
Change-Id: If5f129194d59f5c9e5d84efd8cd9e17a70e072ab
3 years ago
|
|
|
void operator()(absl::string_view) & { tr_->Record(kLValue); }
|
|
|
|
void operator()(absl::string_view) && { tr_->Record(kRValue); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Tracker* tr_;
|
|
|
|
};
|
|
|
|
|
|
|
|
const Releaser releaser1(&tracker);
|
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal("", releaser1));
|
|
|
|
EXPECT_EQ(tracker.copied_as, kCopy);
|
|
|
|
EXPECT_EQ(tracker.invoked_as, kRValue);
|
|
|
|
|
|
|
|
const Releaser releaser2(&tracker);
|
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal("", releaser2));
|
|
|
|
EXPECT_EQ(tracker.copied_as, kCopy);
|
|
|
|
EXPECT_EQ(tracker.invoked_as, kRValue);
|
|
|
|
|
|
|
|
Releaser releaser3(&tracker);
|
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal("", std::move(releaser3)));
|
|
|
|
EXPECT_EQ(tracker.copied_as, kMove);
|
|
|
|
EXPECT_EQ(tracker.invoked_as, kRValue);
|
|
|
|
|
|
|
|
Releaser releaser4(&tracker);
|
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal("dummy", releaser4));
|
|
|
|
EXPECT_EQ(tracker.copied_as, kCopy);
|
|
|
|
EXPECT_EQ(tracker.invoked_as, kRValue);
|
|
|
|
|
|
|
|
const Releaser releaser5(&tracker);
|
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal("dummy", releaser5));
|
|
|
|
EXPECT_EQ(tracker.copied_as, kCopy);
|
|
|
|
EXPECT_EQ(tracker.invoked_as, kRValue);
|
|
|
|
|
|
|
|
Releaser releaser6(&tracker);
|
|
|
|
(void)MaybeHardened(absl::MakeCordFromExternal("foo", std::move(releaser6)));
|
|
|
|
EXPECT_EQ(tracker.copied_as, kMove);
|
|
|
|
EXPECT_EQ(tracker.invoked_as, kRValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ExternalMemoryBasicUsage) {
|
|
|
|
static const char* strings[] = {"", "hello", "there"};
|
|
|
|
for (const char* str : strings) {
|
|
|
|
absl::Cord dst("(prefix)");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(dst);
|
|
|
|
AddExternalMemory(str, &dst);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(dst);
|
|
|
|
dst.Append("(suffix)");
|
|
|
|
EXPECT_EQ((std::string("(prefix)") + str + std::string("(suffix)")),
|
|
|
|
std::string(dst));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ExternalMemoryRemovePrefixSuffix) {
|
|
|
|
// Exhaustively try all sub-strings.
|
|
|
|
absl::Cord cord = MakeComposite();
|
|
|
|
std::string s = std::string(cord);
|
|
|
|
for (int offset = 0; offset <= s.size(); offset++) {
|
|
|
|
for (int length = 0; length <= s.size() - offset; length++) {
|
|
|
|
absl::Cord result(cord);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(result);
|
|
|
|
result.RemovePrefix(offset);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(result);
|
|
|
|
result.RemoveSuffix(result.size() - length);
|
|
|
|
EXPECT_EQ(s.substr(offset, length), std::string(result))
|
|
|
|
<< offset << " " << length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ExternalMemoryGet) {
|
|
|
|
absl::Cord cord("hello");
|
|
|
|
AddExternalMemory(" world!", &cord);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
|
|
|
AddExternalMemory(" how are ", &cord);
|
|
|
|
cord.Append(" you?");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
|
|
|
std::string s = std::string(cord);
|
|
|
|
for (int i = 0; i < s.size(); i++) {
|
|
|
|
EXPECT_EQ(s[i], cord[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CordMemoryUsage tests verify the correctness of the EstimatedMemoryUsage()
|
|
|
|
// We use whiteboxed expectations based on our knowledge of the layout and size
|
|
|
|
// of empty and inlined cords, and flat nodes.
|
|
|
|
|
|
|
|
constexpr auto kFairShare = absl::CordMemoryAccounting::kFairShare;
|
|
|
|
|
|
|
|
// Creates a cord of `n` `c` values, making sure no string stealing occurs.
|
|
|
|
absl::Cord MakeCord(size_t n, char c) {
|
|
|
|
const std::string s(n, c);
|
|
|
|
return absl::Cord(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordTest, CordMemoryUsageEmpty) {
|
|
|
|
absl::Cord cord;
|
|
|
|
EXPECT_EQ(sizeof(absl::Cord), cord.EstimatedMemoryUsage());
|
|
|
|
EXPECT_EQ(sizeof(absl::Cord), cord.EstimatedMemoryUsage(kFairShare));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordTest, CordMemoryUsageInlined) {
|
|
|
|
absl::Cord a("hello");
|
|
|
|
EXPECT_EQ(a.EstimatedMemoryUsage(), sizeof(absl::Cord));
|
|
|
|
EXPECT_EQ(a.EstimatedMemoryUsage(kFairShare), sizeof(absl::Cord));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordTest, CordMemoryUsageExternalMemory) {
|
|
|
|
absl::Cord cord;
|
|
|
|
AddExternalMemory(std::string(1000, 'x'), &cord);
|
|
|
|
const size_t expected =
|
|
|
|
sizeof(absl::Cord) + 1000 + sizeof(CordRepExternal) + sizeof(intptr_t);
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(), expected);
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(kFairShare), expected);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordTest, CordMemoryUsageFlat) {
|
|
|
|
absl::Cord cord = MakeCord(1000, 'a');
|
|
|
|
const size_t flat_size =
|
|
|
|
absl::CordTestPeer::Tree(cord)->flat()->AllocatedSize();
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(), sizeof(absl::Cord) + flat_size);
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(kFairShare),
|
|
|
|
sizeof(absl::Cord) + flat_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordTest, CordMemoryUsageSubStringSharedFlat) {
|
|
|
|
absl::Cord flat = MakeCord(2000, 'a');
|
|
|
|
const size_t flat_size =
|
|
|
|
absl::CordTestPeer::Tree(flat)->flat()->AllocatedSize();
|
|
|
|
absl::Cord cord = flat.Subcord(500, 1000);
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(),
|
|
|
|
sizeof(absl::Cord) + sizeof(CordRepSubstring) + flat_size);
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(kFairShare),
|
|
|
|
sizeof(absl::Cord) + sizeof(CordRepSubstring) + flat_size / 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordTest, CordMemoryUsageFlatShared) {
|
|
|
|
absl::Cord shared = MakeCord(1000, 'a');
|
|
|
|
absl::Cord cord(shared);
|
|
|
|
const size_t flat_size =
|
|
|
|
absl::CordTestPeer::Tree(cord)->flat()->AllocatedSize();
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(), sizeof(absl::Cord) + flat_size);
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(kFairShare),
|
|
|
|
sizeof(absl::Cord) + flat_size / 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordTest, CordMemoryUsageFlatHardenedAndShared) {
|
|
|
|
absl::Cord shared = MakeCord(1000, 'a');
|
|
|
|
absl::Cord cord(shared);
|
|
|
|
const size_t flat_size =
|
|
|
|
absl::CordTestPeer::Tree(cord)->flat()->AllocatedSize();
|
|
|
|
cord.SetExpectedChecksum(1);
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(),
|
|
|
|
sizeof(absl::Cord) + sizeof(CordRepCrc) + flat_size);
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(kFairShare),
|
|
|
|
sizeof(absl::Cord) + sizeof(CordRepCrc) + flat_size / 2);
|
|
|
|
|
|
|
|
absl::Cord cord2(cord);
|
|
|
|
EXPECT_EQ(cord2.EstimatedMemoryUsage(),
|
|
|
|
sizeof(absl::Cord) + sizeof(CordRepCrc) + flat_size);
|
|
|
|
EXPECT_EQ(cord2.EstimatedMemoryUsage(kFairShare),
|
|
|
|
sizeof(absl::Cord) + (sizeof(CordRepCrc) + flat_size / 2) / 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(CordTest, CordMemoryUsageBTree) {
|
|
|
|
absl::Cord cord1;
|
|
|
|
size_t flats1_size = 0;
|
|
|
|
absl::Cord flats1[4] = {MakeCord(1000, 'a'), MakeCord(1100, 'a'),
|
|
|
|
MakeCord(1200, 'a'), MakeCord(1300, 'a')};
|
|
|
|
for (absl::Cord flat : flats1) {
|
|
|
|
flats1_size += absl::CordTestPeer::Tree(flat)->flat()->AllocatedSize();
|
|
|
|
cord1.Append(std::move(flat));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure the created cord is a BTREE tree. Under some builds such as
|
|
|
|
// windows DLL, we may have ODR like effects on the flag, meaning the DLL
|
|
|
|
// code will run with the picked up default.
|
|
|
|
if (!absl::CordTestPeer::Tree(cord1)->IsBtree()) {
|
|
|
|
ABSL_RAW_LOG(WARNING, "Cord library code not respecting btree flag");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t rep1_size = sizeof(CordRepBtree) + flats1_size;
|
|
|
|
size_t rep1_shared_size = sizeof(CordRepBtree) + flats1_size / 2;
|
|
|
|
|
|
|
|
EXPECT_EQ(cord1.EstimatedMemoryUsage(), sizeof(absl::Cord) + rep1_size);
|
|
|
|
EXPECT_EQ(cord1.EstimatedMemoryUsage(kFairShare),
|
|
|
|
sizeof(absl::Cord) + rep1_shared_size);
|
|
|
|
|
|
|
|
absl::Cord cord2;
|
|
|
|
size_t flats2_size = 0;
|
|
|
|
absl::Cord flats2[4] = {MakeCord(600, 'a'), MakeCord(700, 'a'),
|
|
|
|
MakeCord(800, 'a'), MakeCord(900, 'a')};
|
|
|
|
for (absl::Cord& flat : flats2) {
|
|
|
|
flats2_size += absl::CordTestPeer::Tree(flat)->flat()->AllocatedSize();
|
|
|
|
cord2.Append(std::move(flat));
|
|
|
|
}
|
|
|
|
size_t rep2_size = sizeof(CordRepBtree) + flats2_size;
|
|
|
|
|
|
|
|
EXPECT_EQ(cord2.EstimatedMemoryUsage(), sizeof(absl::Cord) + rep2_size);
|
|
|
|
EXPECT_EQ(cord2.EstimatedMemoryUsage(kFairShare),
|
|
|
|
sizeof(absl::Cord) + rep2_size);
|
|
|
|
|
|
|
|
absl::Cord cord(cord1);
|
|
|
|
cord.Append(std::move(cord2));
|
|
|
|
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(),
|
|
|
|
sizeof(absl::Cord) + sizeof(CordRepBtree) + rep1_size + rep2_size);
|
|
|
|
EXPECT_EQ(cord.EstimatedMemoryUsage(kFairShare),
|
|
|
|
sizeof(absl::Cord) + sizeof(CordRepBtree) + rep1_shared_size / 2 +
|
|
|
|
rep2_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Regtest for a change that had to be rolled back because it expanded out
|
|
|
|
// of the InlineRep too soon, which was observable through MemoryUsage().
|
|
|
|
TEST_P(CordTest, CordMemoryUsageInlineRep) {
|
|
|
|
constexpr size_t kMaxInline = 15; // Cord::InlineRep::N
|
|
|
|
const std::string small_string(kMaxInline, 'x');
|
|
|
|
absl::Cord c1(small_string);
|
|
|
|
|
|
|
|
absl::Cord c2;
|
|
|
|
c2.Append(small_string);
|
|
|
|
EXPECT_EQ(c1, c2);
|
|
|
|
EXPECT_EQ(c1.EstimatedMemoryUsage(), c2.EstimatedMemoryUsage());
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
// Regtest for 7510292 (fix a bug introduced by 7465150)
|
|
|
|
TEST_P(CordTest, Concat_Append) {
|
|
|
|
// Create a rep of type CONCAT
|
|
|
|
absl::Cord s1("foobarbarbarbarbar");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(s1);
|
|
|
|
s1.Append("abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg");
|
|
|
|
size_t size = s1.size();
|
|
|
|
|
|
|
|
// Create a copy of s1 and append to it.
|
|
|
|
absl::Cord s2 = s1;
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(s2);
|
|
|
|
s2.Append("x");
|
|
|
|
|
|
|
|
// 7465150 modifies s1 when it shouldn't.
|
|
|
|
EXPECT_EQ(s1.size(), size);
|
|
|
|
EXPECT_EQ(s2.size(), size + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, DiabolicalGrowth) {
|
|
|
|
// This test exercises a diabolical Append(<one char>) on a cord, making the
|
|
|
|
// cord shared before each Append call resulting in a terribly fragmented
|
|
|
|
// resulting cord.
|
|
|
|
// TODO(b/183983616): Apply some minimum compaction when copying a shared
|
|
|
|
// source cord into a mutable copy for updates in CordRepRing.
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
const std::string expected = RandomLowercaseString(&rng, 5000);
|
|
|
|
absl::Cord cord;
|
|
|
|
for (char c : expected) {
|
|
|
|
absl::Cord shared(cord);
|
|
|
|
cord.Append(absl::string_view(&c, 1));
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
|
|
|
}
|
|
|
|
std::string value;
|
|
|
|
absl::CopyCordToString(cord, &value);
|
|
|
|
EXPECT_EQ(value, expected);
|
|
|
|
ABSL_RAW_LOG(INFO, "Diabolical size allocated = %zu",
|
|
|
|
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");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
|
|
|
|
|
|
|
const size_t acceptable_delta =
|
|
|
|
100 + (UseCrc() ? sizeof(absl::cord_internal::CordRepCrc) : 0);
|
|
|
|
EXPECT_LE(cord.size(), cord.EstimatedMemoryUsage());
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
EXPECT_GE(cord.size() + acceptable_delta, cord.EstimatedMemoryUsage());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tests that Append() works ok when handed a self reference
|
|
|
|
TEST_P(CordTest, AppendSelf) {
|
|
|
|
// Test the empty case.
|
|
|
|
absl::Cord empty;
|
|
|
|
MaybeHarden(empty);
|
|
|
|
empty.Append(empty);
|
|
|
|
ASSERT_EQ(empty, "");
|
|
|
|
|
|
|
|
// 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) {
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(data);
|
|
|
|
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"});
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(fragmented);
|
|
|
|
|
|
|
|
EXPECT_EQ("A fragmented Cord", fragmented);
|
|
|
|
|
|
|
|
auto chunk_it = fragmented.chunk_begin();
|
|
|
|
|
|
|
|
ASSERT_TRUE(chunk_it != fragmented.chunk_end());
|
|
|
|
EXPECT_EQ("A ", *chunk_it);
|
|
|
|
|
|
|
|
ASSERT_TRUE(++chunk_it != fragmented.chunk_end());
|
|
|
|
EXPECT_EQ("fragmented ", *chunk_it);
|
|
|
|
|
|
|
|
ASSERT_TRUE(++chunk_it != fragmented.chunk_end());
|
|
|
|
EXPECT_EQ("Cord", *chunk_it);
|
|
|
|
|
|
|
|
ASSERT_TRUE(++chunk_it == fragmented.chunk_end());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, MakeFragmentedCordFromVector) {
|
|
|
|
std::vector<absl::string_view> chunks = {"A ", "fragmented ", "Cord"};
|
|
|
|
absl::Cord fragmented = absl::MakeFragmentedCord(chunks);
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(fragmented);
|
|
|
|
|
|
|
|
EXPECT_EQ("A fragmented Cord", fragmented);
|
|
|
|
|
|
|
|
auto chunk_it = fragmented.chunk_begin();
|
|
|
|
|
|
|
|
ASSERT_TRUE(chunk_it != fragmented.chunk_end());
|
|
|
|
EXPECT_EQ("A ", *chunk_it);
|
|
|
|
|
|
|
|
ASSERT_TRUE(++chunk_it != fragmented.chunk_end());
|
|
|
|
EXPECT_EQ("fragmented ", *chunk_it);
|
|
|
|
|
|
|
|
ASSERT_TRUE(++chunk_it != fragmented.chunk_end());
|
|
|
|
EXPECT_EQ("Cord", *chunk_it);
|
|
|
|
|
|
|
|
ASSERT_TRUE(++chunk_it == fragmented.chunk_end());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CordChunkIteratorTraits) {
|
|
|
|
static_assert(std::is_copy_constructible<absl::Cord::ChunkIterator>::value,
|
|
|
|
"");
|
|
|
|
static_assert(std::is_copy_assignable<absl::Cord::ChunkIterator>::value, "");
|
|
|
|
|
|
|
|
// Move semantics to satisfy swappable via std::swap
|
|
|
|
static_assert(std::is_move_constructible<absl::Cord::ChunkIterator>::value,
|
|
|
|
"");
|
|
|
|
static_assert(std::is_move_assignable<absl::Cord::ChunkIterator>::value, "");
|
|
|
|
|
|
|
|
static_assert(
|
|
|
|
std::is_same<
|
|
|
|
std::iterator_traits<absl::Cord::ChunkIterator>::iterator_category,
|
|
|
|
std::input_iterator_tag>::value,
|
|
|
|
"");
|
|
|
|
static_assert(
|
|
|
|
std::is_same<std::iterator_traits<absl::Cord::ChunkIterator>::value_type,
|
|
|
|
absl::string_view>::value,
|
|
|
|
"");
|
|
|
|
static_assert(
|
|
|
|
std::is_same<
|
|
|
|
std::iterator_traits<absl::Cord::ChunkIterator>::difference_type,
|
|
|
|
ptrdiff_t>::value,
|
|
|
|
"");
|
|
|
|
static_assert(
|
|
|
|
std::is_same<std::iterator_traits<absl::Cord::ChunkIterator>::pointer,
|
|
|
|
const absl::string_view*>::value,
|
|
|
|
"");
|
|
|
|
static_assert(
|
|
|
|
std::is_same<std::iterator_traits<absl::Cord::ChunkIterator>::reference,
|
|
|
|
absl::string_view>::value,
|
|
|
|
"");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void VerifyChunkIterator(const absl::Cord& cord,
|
|
|
|
size_t expected_chunks) {
|
|
|
|
EXPECT_EQ(cord.chunk_begin() == cord.chunk_end(), cord.empty()) << cord;
|
|
|
|
EXPECT_EQ(cord.chunk_begin() != cord.chunk_end(), !cord.empty());
|
|
|
|
|
|
|
|
absl::Cord::ChunkRange range = cord.Chunks();
|
|
|
|
EXPECT_EQ(range.begin() == range.end(), cord.empty());
|
|
|
|
EXPECT_EQ(range.begin() != range.end(), !cord.empty());
|
|
|
|
|
|
|
|
std::string content(cord);
|
|
|
|
size_t pos = 0;
|
|
|
|
auto pre_iter = cord.chunk_begin(), post_iter = cord.chunk_begin();
|
|
|
|
size_t n_chunks = 0;
|
|
|
|
while (pre_iter != cord.chunk_end() && post_iter != cord.chunk_end()) {
|
|
|
|
EXPECT_FALSE(pre_iter == cord.chunk_end()); // NOLINT: explicitly test ==
|
|
|
|
EXPECT_FALSE(post_iter == cord.chunk_end()); // NOLINT
|
|
|
|
|
|
|
|
EXPECT_EQ(pre_iter, post_iter);
|
|
|
|
EXPECT_EQ(*pre_iter, *post_iter);
|
|
|
|
|
|
|
|
EXPECT_EQ(pre_iter->data(), (*pre_iter).data());
|
|
|
|
EXPECT_EQ(pre_iter->size(), (*pre_iter).size());
|
|
|
|
|
|
|
|
absl::string_view chunk = *pre_iter;
|
|
|
|
EXPECT_FALSE(chunk.empty());
|
|
|
|
EXPECT_LE(pos + chunk.size(), content.size());
|
|
|
|
EXPECT_EQ(absl::string_view(content.c_str() + pos, chunk.size()), chunk);
|
|
|
|
|
|
|
|
int n_equal_iterators = 0;
|
|
|
|
for (absl::Cord::ChunkIterator it = range.begin(); it != range.end();
|
|
|
|
++it) {
|
|
|
|
n_equal_iterators += static_cast<int>(it == pre_iter);
|
|
|
|
}
|
|
|
|
EXPECT_EQ(n_equal_iterators, 1);
|
|
|
|
|
|
|
|
++pre_iter;
|
|
|
|
EXPECT_EQ(*post_iter++, chunk);
|
|
|
|
|
|
|
|
pos += chunk.size();
|
|
|
|
++n_chunks;
|
|
|
|
}
|
|
|
|
EXPECT_EQ(expected_chunks, n_chunks);
|
|
|
|
EXPECT_EQ(pos, content.size());
|
|
|
|
EXPECT_TRUE(pre_iter == cord.chunk_end()); // NOLINT: explicitly test ==
|
|
|
|
EXPECT_TRUE(post_iter == cord.chunk_end()); // NOLINT
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CordChunkIteratorOperations) {
|
|
|
|
absl::Cord empty_cord;
|
|
|
|
VerifyChunkIterator(empty_cord, 0);
|
|
|
|
|
|
|
|
absl::Cord small_buffer_cord("small cord");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(small_buffer_cord);
|
|
|
|
VerifyChunkIterator(small_buffer_cord, 1);
|
|
|
|
|
|
|
|
absl::Cord flat_node_cord("larger than small buffer optimization");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(flat_node_cord);
|
|
|
|
VerifyChunkIterator(flat_node_cord, 1);
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
VerifyChunkIterator(MaybeHardened(absl::MakeFragmentedCord(
|
|
|
|
{"a ", "small ", "fragmented ", "cord ", "for ",
|
|
|
|
"testing ", "chunk ", "iterations."})),
|
|
|
|
8);
|
|
|
|
|
|
|
|
absl::Cord reused_nodes_cord(std::string(40, 'c'));
|
|
|
|
reused_nodes_cord.Prepend(absl::Cord(std::string(40, 'b')));
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(reused_nodes_cord);
|
|
|
|
reused_nodes_cord.Prepend(absl::Cord(std::string(40, 'a')));
|
|
|
|
size_t expected_chunks = 3;
|
|
|
|
for (int i = 0; i < 8; ++i) {
|
|
|
|
reused_nodes_cord.Prepend(reused_nodes_cord);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(reused_nodes_cord);
|
|
|
|
expected_chunks *= 2;
|
|
|
|
VerifyChunkIterator(reused_nodes_cord, expected_chunks);
|
|
|
|
}
|
|
|
|
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
absl::Cord flat_cord(RandomLowercaseString(&rng, 256));
|
|
|
|
absl::Cord subcords;
|
|
|
|
for (int i = 0; i < 128; ++i) subcords.Prepend(flat_cord.Subcord(i, 128));
|
|
|
|
VerifyChunkIterator(subcords, 128);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST_P(CordTest, AdvanceAndReadOnDataEdge) {
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
const std::string data = RandomLowercaseString(&rng, 2000);
|
|
|
|
for (bool as_flat : {true, false}) {
|
|
|
|
SCOPED_TRACE(as_flat ? "Flat" : "External");
|
|
|
|
|
|
|
|
absl::Cord cord =
|
|
|
|
as_flat ? absl::Cord(data)
|
|
|
|
: absl::MakeCordFromExternal(data, [](absl::string_view) {});
|
|
|
|
auto it = cord.Chars().begin();
|
|
|
|
#if !defined(NDEBUG) || ABSL_OPTION_HARDENED
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(cord.AdvanceAndRead(&it, 2001), ".*");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
it = cord.Chars().begin();
|
|
|
|
absl::Cord frag = cord.AdvanceAndRead(&it, 2000);
|
|
|
|
EXPECT_EQ(frag, data);
|
|
|
|
EXPECT_TRUE(it == cord.Chars().end());
|
|
|
|
|
|
|
|
it = cord.Chars().begin();
|
|
|
|
frag = cord.AdvanceAndRead(&it, 200);
|
|
|
|
EXPECT_EQ(frag, data.substr(0, 200));
|
|
|
|
EXPECT_FALSE(it == cord.Chars().end());
|
|
|
|
|
|
|
|
frag = cord.AdvanceAndRead(&it, 1500);
|
|
|
|
EXPECT_EQ(frag, data.substr(200, 1500));
|
|
|
|
EXPECT_FALSE(it == cord.Chars().end());
|
|
|
|
|
|
|
|
frag = cord.AdvanceAndRead(&it, 300);
|
|
|
|
EXPECT_EQ(frag, data.substr(1700, 300));
|
|
|
|
EXPECT_TRUE(it == cord.Chars().end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, AdvanceAndReadOnSubstringDataEdge) {
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
const std::string data = RandomLowercaseString(&rng, 2500);
|
|
|
|
for (bool as_flat : {true, false}) {
|
|
|
|
SCOPED_TRACE(as_flat ? "Flat" : "External");
|
|
|
|
|
|
|
|
absl::Cord cord =
|
|
|
|
as_flat ? absl::Cord(data)
|
|
|
|
: absl::MakeCordFromExternal(data, [](absl::string_view) {});
|
|
|
|
cord = cord.Subcord(200, 2000);
|
|
|
|
const std::string substr = data.substr(200, 2000);
|
|
|
|
|
|
|
|
auto it = cord.Chars().begin();
|
|
|
|
#if !defined(NDEBUG) || ABSL_OPTION_HARDENED
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(cord.AdvanceAndRead(&it, 2001), ".*");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
it = cord.Chars().begin();
|
|
|
|
absl::Cord frag = cord.AdvanceAndRead(&it, 2000);
|
|
|
|
EXPECT_EQ(frag, substr);
|
|
|
|
EXPECT_TRUE(it == cord.Chars().end());
|
|
|
|
|
|
|
|
it = cord.Chars().begin();
|
|
|
|
frag = cord.AdvanceAndRead(&it, 200);
|
|
|
|
EXPECT_EQ(frag, substr.substr(0, 200));
|
|
|
|
EXPECT_FALSE(it == cord.Chars().end());
|
|
|
|
|
|
|
|
frag = cord.AdvanceAndRead(&it, 1500);
|
|
|
|
EXPECT_EQ(frag, substr.substr(200, 1500));
|
|
|
|
EXPECT_FALSE(it == cord.Chars().end());
|
|
|
|
|
|
|
|
frag = cord.AdvanceAndRead(&it, 300);
|
|
|
|
EXPECT_EQ(frag, substr.substr(1700, 300));
|
|
|
|
EXPECT_TRUE(it == cord.Chars().end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CharIteratorTraits) {
|
|
|
|
static_assert(std::is_copy_constructible<absl::Cord::CharIterator>::value,
|
|
|
|
"");
|
|
|
|
static_assert(std::is_copy_assignable<absl::Cord::CharIterator>::value, "");
|
|
|
|
|
|
|
|
// Move semantics to satisfy swappable via std::swap
|
|
|
|
static_assert(std::is_move_constructible<absl::Cord::CharIterator>::value,
|
|
|
|
"");
|
|
|
|
static_assert(std::is_move_assignable<absl::Cord::CharIterator>::value, "");
|
|
|
|
|
|
|
|
static_assert(
|
|
|
|
std::is_same<
|
|
|
|
std::iterator_traits<absl::Cord::CharIterator>::iterator_category,
|
|
|
|
std::input_iterator_tag>::value,
|
|
|
|
"");
|
|
|
|
static_assert(
|
|
|
|
std::is_same<std::iterator_traits<absl::Cord::CharIterator>::value_type,
|
|
|
|
char>::value,
|
|
|
|
"");
|
|
|
|
static_assert(
|
|
|
|
std::is_same<
|
|
|
|
std::iterator_traits<absl::Cord::CharIterator>::difference_type,
|
|
|
|
ptrdiff_t>::value,
|
|
|
|
"");
|
|
|
|
static_assert(
|
|
|
|
std::is_same<std::iterator_traits<absl::Cord::CharIterator>::pointer,
|
|
|
|
const char*>::value,
|
|
|
|
"");
|
|
|
|
static_assert(
|
|
|
|
std::is_same<std::iterator_traits<absl::Cord::CharIterator>::reference,
|
|
|
|
const char&>::value,
|
|
|
|
"");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void VerifyCharIterator(const absl::Cord& cord) {
|
|
|
|
EXPECT_EQ(cord.char_begin() == cord.char_end(), cord.empty());
|
|
|
|
EXPECT_EQ(cord.char_begin() != cord.char_end(), !cord.empty());
|
|
|
|
|
|
|
|
absl::Cord::CharRange range = cord.Chars();
|
|
|
|
EXPECT_EQ(range.begin() == range.end(), cord.empty());
|
|
|
|
EXPECT_EQ(range.begin() != range.end(), !cord.empty());
|
|
|
|
|
|
|
|
size_t i = 0;
|
|
|
|
absl::Cord::CharIterator pre_iter = cord.char_begin();
|
|
|
|
absl::Cord::CharIterator post_iter = cord.char_begin();
|
|
|
|
std::string content(cord);
|
|
|
|
while (pre_iter != cord.char_end() && post_iter != cord.char_end()) {
|
|
|
|
EXPECT_FALSE(pre_iter == cord.char_end()); // NOLINT: explicitly test ==
|
|
|
|
EXPECT_FALSE(post_iter == cord.char_end()); // NOLINT
|
|
|
|
|
|
|
|
EXPECT_LT(i, cord.size());
|
|
|
|
EXPECT_EQ(content[i], *pre_iter);
|
|
|
|
|
|
|
|
EXPECT_EQ(pre_iter, post_iter);
|
|
|
|
EXPECT_EQ(*pre_iter, *post_iter);
|
|
|
|
EXPECT_EQ(&*pre_iter, &*post_iter);
|
|
|
|
|
|
|
|
EXPECT_EQ(&*pre_iter, pre_iter.operator->());
|
|
|
|
|
|
|
|
const char* character_address = &*pre_iter;
|
|
|
|
absl::Cord::CharIterator copy = pre_iter;
|
|
|
|
++copy;
|
|
|
|
EXPECT_EQ(character_address, &*pre_iter);
|
|
|
|
|
|
|
|
int n_equal_iterators = 0;
|
|
|
|
for (absl::Cord::CharIterator it = range.begin(); it != range.end(); ++it) {
|
|
|
|
n_equal_iterators += static_cast<int>(it == pre_iter);
|
|
|
|
}
|
|
|
|
EXPECT_EQ(n_equal_iterators, 1);
|
|
|
|
|
|
|
|
absl::Cord::CharIterator advance_iter = range.begin();
|
|
|
|
absl::Cord::Advance(&advance_iter, i);
|
|
|
|
EXPECT_EQ(pre_iter, advance_iter);
|
|
|
|
|
|
|
|
advance_iter = range.begin();
|
|
|
|
EXPECT_EQ(absl::Cord::AdvanceAndRead(&advance_iter, i), cord.Subcord(0, i));
|
|
|
|
EXPECT_EQ(pre_iter, advance_iter);
|
|
|
|
|
|
|
|
advance_iter = pre_iter;
|
|
|
|
absl::Cord::Advance(&advance_iter, cord.size() - i);
|
|
|
|
EXPECT_EQ(range.end(), advance_iter);
|
|
|
|
|
|
|
|
advance_iter = pre_iter;
|
|
|
|
EXPECT_EQ(absl::Cord::AdvanceAndRead(&advance_iter, cord.size() - i),
|
|
|
|
cord.Subcord(i, cord.size() - i));
|
|
|
|
EXPECT_EQ(range.end(), advance_iter);
|
|
|
|
|
|
|
|
++i;
|
|
|
|
++pre_iter;
|
|
|
|
post_iter++;
|
|
|
|
}
|
|
|
|
EXPECT_EQ(i, cord.size());
|
|
|
|
EXPECT_TRUE(pre_iter == cord.char_end()); // NOLINT: explicitly test ==
|
|
|
|
EXPECT_TRUE(post_iter == cord.char_end()); // NOLINT
|
|
|
|
|
|
|
|
absl::Cord::CharIterator zero_advanced_end = cord.char_end();
|
|
|
|
absl::Cord::Advance(&zero_advanced_end, 0);
|
|
|
|
EXPECT_EQ(zero_advanced_end, cord.char_end());
|
|
|
|
|
|
|
|
absl::Cord::CharIterator it = cord.char_begin();
|
|
|
|
for (absl::string_view chunk : cord.Chunks()) {
|
|
|
|
while (!chunk.empty()) {
|
|
|
|
EXPECT_EQ(absl::Cord::ChunkRemaining(it), chunk);
|
|
|
|
chunk.remove_prefix(1);
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CharIteratorOperations) {
|
|
|
|
absl::Cord empty_cord;
|
|
|
|
VerifyCharIterator(empty_cord);
|
|
|
|
|
|
|
|
absl::Cord small_buffer_cord("small cord");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(small_buffer_cord);
|
|
|
|
VerifyCharIterator(small_buffer_cord);
|
|
|
|
|
|
|
|
absl::Cord flat_node_cord("larger than small buffer optimization");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(flat_node_cord);
|
|
|
|
VerifyCharIterator(flat_node_cord);
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
VerifyCharIterator(MaybeHardened(
|
|
|
|
absl::MakeFragmentedCord({"a ", "small ", "fragmented ", "cord ", "for ",
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
"testing ", "character ", "iteration."})));
|
|
|
|
|
|
|
|
absl::Cord reused_nodes_cord("ghi");
|
|
|
|
reused_nodes_cord.Prepend(absl::Cord("def"));
|
|
|
|
reused_nodes_cord.Prepend(absl::Cord("abc"));
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
reused_nodes_cord.Prepend(reused_nodes_cord);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(reused_nodes_cord);
|
|
|
|
VerifyCharIterator(reused_nodes_cord);
|
|
|
|
}
|
|
|
|
|
|
|
|
RandomEngine rng(GTEST_FLAG_GET(random_seed));
|
|
|
|
absl::Cord flat_cord(RandomLowercaseString(&rng, 256));
|
|
|
|
absl::Cord subcords;
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
subcords.Prepend(flat_cord.Subcord(16 * i, 128));
|
|
|
|
MaybeHarden(subcords);
|
|
|
|
}
|
|
|
|
VerifyCharIterator(subcords);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, CharIteratorAdvanceAndRead) {
|
|
|
|
// Create a Cord holding 6 flats of 2500 bytes each, and then iterate over it
|
|
|
|
// reading 150, 1500, 2500 and 3000 bytes. This will result in all possible
|
|
|
|
// partial, full and straddled read combinations including reads below
|
|
|
|
// kMaxBytesToCopy. b/197776822 surfaced a bug for a specific partial, small
|
|
|
|
// read 'at end' on Cord which caused a failure on attempting to read past the
|
|
|
|
// end in CordRepBtreeReader which was not covered by any existing test.
|
|
|
|
constexpr int kBlocks = 6;
|
|
|
|
constexpr size_t kBlockSize = 2500;
|
|
|
|
constexpr size_t kChunkSize1 = 1500;
|
|
|
|
constexpr size_t kChunkSize2 = 2500;
|
|
|
|
constexpr size_t kChunkSize3 = 3000;
|
|
|
|
constexpr size_t kChunkSize4 = 150;
|
|
|
|
RandomEngine rng;
|
|
|
|
std::string data = RandomLowercaseString(&rng, kBlocks * kBlockSize);
|
|
|
|
absl::Cord cord;
|
|
|
|
for (int i = 0; i < kBlocks; ++i) {
|
|
|
|
const std::string block = data.substr(i * kBlockSize, kBlockSize);
|
|
|
|
cord.Append(absl::Cord(block));
|
|
|
|
}
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
|
|
|
|
|
|
|
for (size_t chunk_size :
|
|
|
|
{kChunkSize1, kChunkSize2, kChunkSize3, kChunkSize4}) {
|
|
|
|
absl::Cord::CharIterator it = cord.char_begin();
|
|
|
|
size_t offset = 0;
|
|
|
|
while (offset < data.length()) {
|
|
|
|
const size_t n = std::min<size_t>(data.length() - offset, chunk_size);
|
|
|
|
absl::Cord chunk = cord.AdvanceAndRead(&it, n);
|
|
|
|
ASSERT_EQ(chunk.size(), n);
|
|
|
|
ASSERT_EQ(chunk.Compare(data.substr(offset, n)), 0);
|
|
|
|
offset += n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, StreamingOutput) {
|
|
|
|
absl::Cord c =
|
|
|
|
absl::MakeFragmentedCord({"A ", "small ", "fragmented ", "Cord", "."});
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
std::stringstream output;
|
|
|
|
output << c;
|
|
|
|
EXPECT_EQ("A small fragmented Cord.", output.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, ForEachChunk) {
|
|
|
|
for (int num_elements : {1, 10, 200}) {
|
|
|
|
SCOPED_TRACE(num_elements);
|
|
|
|
std::vector<std::string> cord_chunks;
|
|
|
|
for (int i = 0; i < num_elements; ++i) {
|
|
|
|
cord_chunks.push_back(absl::StrCat("[", i, "]"));
|
|
|
|
}
|
|
|
|
absl::Cord c = absl::MakeFragmentedCord(cord_chunks);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
|
|
|
|
std::vector<std::string> iterated_chunks;
|
|
|
|
absl::CordTestPeer::ForEachChunk(c,
|
|
|
|
[&iterated_chunks](absl::string_view sv) {
|
|
|
|
iterated_chunks.emplace_back(sv);
|
|
|
|
});
|
|
|
|
EXPECT_EQ(iterated_chunks, cord_chunks);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, SmallBufferAssignFromOwnData) {
|
|
|
|
constexpr size_t kMaxInline = 15;
|
|
|
|
std::string contents = "small buff cord";
|
|
|
|
EXPECT_EQ(contents.size(), kMaxInline);
|
|
|
|
for (size_t pos = 0; pos < contents.size(); ++pos) {
|
|
|
|
for (size_t count = contents.size() - pos; count > 0; --count) {
|
|
|
|
absl::Cord c(contents);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
absl::string_view flat = c.Flatten();
|
|
|
|
c = flat.substr(pos, count);
|
|
|
|
EXPECT_EQ(c, contents.substr(pos, count))
|
|
|
|
<< "pos = " << pos << "; count = " << count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, Format) {
|
|
|
|
absl::Cord c;
|
|
|
|
absl::Format(&c, "There were %04d little %s.", 3, "pigs");
|
|
|
|
EXPECT_EQ(c, "There were 0003 little pigs.");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
absl::Format(&c, "And %-3llx bad wolf!", 1);
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(c);
|
|
|
|
EXPECT_EQ(c, "There were 0003 little pigs.And 1 bad wolf!");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_P(CordTest, Hardening) {
|
|
|
|
absl::Cord cord("hello");
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
|
|
|
|
|
|
|
// These statement should abort the program in all builds modes.
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(cord.RemovePrefix(6), "");
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(cord.RemoveSuffix(6), "");
|
|
|
|
|
|
|
|
bool test_hardening = false;
|
|
|
|
ABSL_HARDENING_ASSERT([&]() {
|
|
|
|
// This only runs when ABSL_HARDENING_ASSERT is active.
|
|
|
|
test_hardening = true;
|
|
|
|
return true;
|
|
|
|
}());
|
|
|
|
if (!test_hardening) return;
|
|
|
|
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(cord[5], "");
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(*cord.chunk_end(), "");
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(static_cast<void>(cord.chunk_end()->empty()), "");
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(++cord.chunk_end(), "");
|
|
|
|
}
|
|
|
|
|
Export of internal Abseil changes
--
f49e405201d2ffd5955503fa8ad0f08ec0cdfb2b by Martijn Vels <mvels@google.com>:
Add common [container.requirements] type definitions to `CharRange` and `ChunkRange`
The presence of these allow these range classes to be used in various utility functions which require some minimum type of container. For example, this change allows tests to use `EXPECT_THAT(cord.Chunks(), ElementsAre(...))`
PiperOrigin-RevId: 406941278
--
0c195f073632e21d9a4bce158047b2ba8551c2d1 by Evan Brown <ezb@google.com>:
Use explicit exponential growth in SubstituteAndAppendArray.
PiperOrigin-RevId: 406931952
--
afb043bccd809a55cab78abadb7548a057d9eda0 by Jorg Brown <jorg@google.com>:
Use longer var names in macro to avoid clang-tidy warning
PiperOrigin-RevId: 406930978
--
80397e2604e6b3d929a34742c3a32581b34d3ac4 by Martijn Vels <mvels@google.com>:
Add future kAppendBuffer and kPrependBuffer API trackers for Cordz sampling
PiperOrigin-RevId: 406912759
--
e910ce919ef83933f08a690e8b7325c7cc5b6d5d by Martijn Vels <mvels@google.com>:
Implement Prepend(string_view) in terms of PrependArray(string_view, MethodIdentifier).
PiperOrigin-RevId: 406891665
--
c9cff43d4c0568ed01f2fca0f6ef038ae03112b5 by Martijn Vels <mvels@google.com>:
Add 'Rebuild' logic to CordRepBtree
There are btree hostile scenarios where an application could perform repeated split/insert/merge operations on a cord leading to a tree exceeding the maximum height. While this should be rare in practice, this change adds a Rebuild() method that will rebuild a tree with a 100% fill factor, and we will invoke this rebuild when a tree exceeds the maximum height. This basically follows the similar 'balance' logic in Concat trees (although the latter is common in Concat uses)
PiperOrigin-RevId: 406875739
--
5b2b8fb88f1ebfdc1c670088152da2cb2ea4c376 by Martijn Vels <mvels@google.com>:
Add 'in place' enabled RemoveSuffix
An in-place RemoveSuffix is more efficient than SubTree() as it can directly modify privately owned nodes and flats allowing easy re-use of free capacity in right-most flats that may turn into Substring edges when using SubTree.
PiperOrigin-RevId: 406431230
--
f09903c0a3d7344f59aaf1380a16ea10829217d4 by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 406430373
--
9957af575c33bb18dc170572a4ee8cc5901df6b2 by Greg Falcon <gfalcon@google.com>:
Initial groundwork to allow storing checksum data inside CordRep instances.
This uses a RefcountAndFlags bit that was reserved for this purpose, and will be leveraged in a follow-up change to allow attaching checksums to a Cord's value.
This change splits RefcountAndFlags::IsOne() into two distinct operations:
* IsOne(): This returns true when the associated CordRep is not shared with other threads. This is useful for functions that consume CordRep instances; for example, code that consumes an unshared CordRep can assume ownership of its children without modifying those refcounts.
* IsMutable(): This returns true when the associated CordRep reference is not shared with other threads, *and* does not store an associated checksum value. This is useful for functions that modify a CordRep's contents: code may modify the bytes of a mutable-unshared CordRep without fear of races with other threads, or of invalidating a stored checksum.
The tricky part of this CL is ensuring that the correct choice between IsMutable() and IsOne() was made at each point. An incorrect application of IsOne() could lead to correctness bugs in the future. Code conditioned on IsOne() may delete the CordRep in question, or assume ownership of its children, but must not modify the CordRep's data without explicitly adjusting the CRC.
PiperOrigin-RevId: 406191103
--
686544814079e5ab6d4593cca0c068b510be400a by Martijn Vels <mvels@google.com>:
Reduce the size in the LargeString test when running with Sanitizers
PiperOrigin-RevId: 406186945
--
735b4490bdb695c35731f06ce4b8de14ce2be6ed by Alex Strelnikov <strel@google.com>:
Release absl::SimpleHexAtoi.
PiperOrigin-RevId: 406143188
GitOrigin-RevId: f49e405201d2ffd5955503fa8ad0f08ec0cdfb2b
Change-Id: Ic6527ac40fa03ea02ca813e8bb7868a219544de4
3 years ago
|
|
|
// This test mimics a specific (and rare) application repeatedly splitting a
|
|
|
|
// cord, inserting (overwriting) a string value, and composing a new cord from
|
|
|
|
// the three pieces. This is hostile towards a Btree implementation: A split of
|
|
|
|
// a node at any level is likely to have the right-most edge of the left split,
|
|
|
|
// and the left-most edge of the right split shared. For example, splitting a
|
|
|
|
// leaf node with 6 edges will result likely in a 1-6, 2-5, 3-4, etc. split,
|
|
|
|
// sharing the 'split node'. When recomposing such nodes, we 'injected' an edge
|
|
|
|
// in that node. As this happens with some probability on each level of the
|
|
|
|
// tree, this will quickly grow the tree until it reaches maximum height.
|
|
|
|
TEST_P(CordTest, BtreeHostileSplitInsertJoin) {
|
|
|
|
absl::BitGen bitgen;
|
|
|
|
|
|
|
|
// Start with about 1GB of data
|
|
|
|
std::string data(1 << 10, 'x');
|
|
|
|
absl::Cord buffer(data);
|
|
|
|
absl::Cord cord;
|
|
|
|
for (int i = 0; i < 1000000; ++i) {
|
|
|
|
cord.Append(buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int j = 0; j < 1000; ++j) {
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
MaybeHarden(cord);
|
Export of internal Abseil changes
--
f49e405201d2ffd5955503fa8ad0f08ec0cdfb2b by Martijn Vels <mvels@google.com>:
Add common [container.requirements] type definitions to `CharRange` and `ChunkRange`
The presence of these allow these range classes to be used in various utility functions which require some minimum type of container. For example, this change allows tests to use `EXPECT_THAT(cord.Chunks(), ElementsAre(...))`
PiperOrigin-RevId: 406941278
--
0c195f073632e21d9a4bce158047b2ba8551c2d1 by Evan Brown <ezb@google.com>:
Use explicit exponential growth in SubstituteAndAppendArray.
PiperOrigin-RevId: 406931952
--
afb043bccd809a55cab78abadb7548a057d9eda0 by Jorg Brown <jorg@google.com>:
Use longer var names in macro to avoid clang-tidy warning
PiperOrigin-RevId: 406930978
--
80397e2604e6b3d929a34742c3a32581b34d3ac4 by Martijn Vels <mvels@google.com>:
Add future kAppendBuffer and kPrependBuffer API trackers for Cordz sampling
PiperOrigin-RevId: 406912759
--
e910ce919ef83933f08a690e8b7325c7cc5b6d5d by Martijn Vels <mvels@google.com>:
Implement Prepend(string_view) in terms of PrependArray(string_view, MethodIdentifier).
PiperOrigin-RevId: 406891665
--
c9cff43d4c0568ed01f2fca0f6ef038ae03112b5 by Martijn Vels <mvels@google.com>:
Add 'Rebuild' logic to CordRepBtree
There are btree hostile scenarios where an application could perform repeated split/insert/merge operations on a cord leading to a tree exceeding the maximum height. While this should be rare in practice, this change adds a Rebuild() method that will rebuild a tree with a 100% fill factor, and we will invoke this rebuild when a tree exceeds the maximum height. This basically follows the similar 'balance' logic in Concat trees (although the latter is common in Concat uses)
PiperOrigin-RevId: 406875739
--
5b2b8fb88f1ebfdc1c670088152da2cb2ea4c376 by Martijn Vels <mvels@google.com>:
Add 'in place' enabled RemoveSuffix
An in-place RemoveSuffix is more efficient than SubTree() as it can directly modify privately owned nodes and flats allowing easy re-use of free capacity in right-most flats that may turn into Substring edges when using SubTree.
PiperOrigin-RevId: 406431230
--
f09903c0a3d7344f59aaf1380a16ea10829217d4 by Derek Mauro <dmauro@google.com>:
Internal change
PiperOrigin-RevId: 406430373
--
9957af575c33bb18dc170572a4ee8cc5901df6b2 by Greg Falcon <gfalcon@google.com>:
Initial groundwork to allow storing checksum data inside CordRep instances.
This uses a RefcountAndFlags bit that was reserved for this purpose, and will be leveraged in a follow-up change to allow attaching checksums to a Cord's value.
This change splits RefcountAndFlags::IsOne() into two distinct operations:
* IsOne(): This returns true when the associated CordRep is not shared with other threads. This is useful for functions that consume CordRep instances; for example, code that consumes an unshared CordRep can assume ownership of its children without modifying those refcounts.
* IsMutable(): This returns true when the associated CordRep reference is not shared with other threads, *and* does not store an associated checksum value. This is useful for functions that modify a CordRep's contents: code may modify the bytes of a mutable-unshared CordRep without fear of races with other threads, or of invalidating a stored checksum.
The tricky part of this CL is ensuring that the correct choice between IsMutable() and IsOne() was made at each point. An incorrect application of IsOne() could lead to correctness bugs in the future. Code conditioned on IsOne() may delete the CordRep in question, or assume ownership of its children, but must not modify the CordRep's data without explicitly adjusting the CRC.
PiperOrigin-RevId: 406191103
--
686544814079e5ab6d4593cca0c068b510be400a by Martijn Vels <mvels@google.com>:
Reduce the size in the LargeString test when running with Sanitizers
PiperOrigin-RevId: 406186945
--
735b4490bdb695c35731f06ce4b8de14ce2be6ed by Alex Strelnikov <strel@google.com>:
Release absl::SimpleHexAtoi.
PiperOrigin-RevId: 406143188
GitOrigin-RevId: f49e405201d2ffd5955503fa8ad0f08ec0cdfb2b
Change-Id: Ic6527ac40fa03ea02ca813e8bb7868a219544de4
3 years ago
|
|
|
size_t offset = absl::Uniform(bitgen, 0u, cord.size());
|
|
|
|
size_t length = absl::Uniform(bitgen, 100u, data.size());
|
|
|
|
if (cord.size() == offset) {
|
|
|
|
cord.Append(absl::string_view(data.data(), length));
|
|
|
|
} else {
|
|
|
|
absl::Cord suffix;
|
|
|
|
if (offset + length < cord.size()) {
|
|
|
|
suffix = cord;
|
|
|
|
suffix.RemovePrefix(offset + length);
|
|
|
|
}
|
|
|
|
if (cord.size() > offset) {
|
|
|
|
cord.RemoveSuffix(cord.size() - offset);
|
|
|
|
}
|
|
|
|
cord.Append(absl::string_view(data.data(), length));
|
|
|
|
if (!suffix.empty()) {
|
|
|
|
cord.Append(suffix);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class AfterExitCordTester {
|
|
|
|
public:
|
|
|
|
bool Set(absl::Cord* cord, absl::string_view expected) {
|
|
|
|
cord_ = cord;
|
|
|
|
expected_ = expected;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
~AfterExitCordTester() {
|
|
|
|
EXPECT_EQ(*cord_, expected_);
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
absl::Cord* cord_;
|
|
|
|
absl::string_view expected_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Deliberately prevents the destructor for an absl::Cord from running. The cord
|
|
|
|
// is accessible via the cord member during the lifetime of the CordLeaker.
|
|
|
|
// After the CordLeaker is destroyed, pointers to the cord will remain valid
|
|
|
|
// until the CordLeaker's memory is deallocated.
|
|
|
|
struct CordLeaker {
|
|
|
|
union {
|
|
|
|
absl::Cord cord;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename Str>
|
|
|
|
constexpr explicit CordLeaker(const Str& str) : cord(str) {}
|
|
|
|
|
|
|
|
~CordLeaker() {
|
|
|
|
// Don't do anything, including running cord's destructor. (cord's
|
|
|
|
// destructor won't run automatically because cord is hidden inside a
|
|
|
|
// union.)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename Str>
|
|
|
|
void TestConstinitConstructor(Str) {
|
|
|
|
const auto expected = Str::value;
|
|
|
|
// Defined before `cord` to be destroyed after it.
|
|
|
|
static AfterExitCordTester exit_tester; // NOLINT
|
|
|
|
ABSL_CONST_INIT static CordLeaker cord_leaker(Str{}); // NOLINT
|
|
|
|
// cord_leaker is static, so this reference will remain valid through the end
|
|
|
|
// of program execution.
|
|
|
|
static absl::Cord& cord = cord_leaker.cord;
|
|
|
|
static bool init_exit_tester = exit_tester.Set(&cord, expected);
|
|
|
|
(void)init_exit_tester;
|
|
|
|
|
|
|
|
EXPECT_EQ(cord, expected);
|
|
|
|
// Copy the object and test the copy, and the original.
|
|
|
|
{
|
|
|
|
absl::Cord copy = cord;
|
|
|
|
EXPECT_EQ(copy, expected);
|
|
|
|
}
|
|
|
|
// The original still works
|
|
|
|
EXPECT_EQ(cord, expected);
|
|
|
|
|
|
|
|
// Try making adding more structure to the tree.
|
|
|
|
{
|
|
|
|
absl::Cord copy = cord;
|
|
|
|
std::string expected_copy(expected);
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
|
|
copy.Append(cord);
|
|
|
|
absl::StrAppend(&expected_copy, expected);
|
|
|
|
EXPECT_EQ(copy, expected_copy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure we are using the right branch during constant evaluation.
|
|
|
|
EXPECT_EQ(absl::CordTestPeer::IsTree(cord), cord.size() >= 16);
|
|
|
|
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
|
|
// Make a few more Cords from the same global rep.
|
|
|
|
// This tests what happens when the refcount for it gets below 1.
|
|
|
|
EXPECT_EQ(expected, absl::Cord(Str{}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr int SimpleStrlen(const char* p) {
|
|
|
|
return *p ? 1 + SimpleStrlen(p + 1) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ShortView {
|
|
|
|
constexpr absl::string_view operator()() const {
|
|
|
|
return absl::string_view("SSO string", SimpleStrlen("SSO string"));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LongView {
|
|
|
|
constexpr absl::string_view operator()() const {
|
|
|
|
return absl::string_view("String that does not fit SSO.",
|
|
|
|
SimpleStrlen("String that does not fit SSO."));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
TEST_P(CordTest, ConstinitConstructor) {
|
|
|
|
TestConstinitConstructor(
|
|
|
|
absl::strings_internal::MakeStringConstant(ShortView{}));
|
|
|
|
TestConstinitConstructor(
|
|
|
|
absl::strings_internal::MakeStringConstant(LongView{}));
|
|
|
|
}
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
// Test helper that generates a populated cord for future manipulation.
|
|
|
|
//
|
|
|
|
// By test convention, all generated cords begin with the characters "abcde" at
|
|
|
|
// the start of the first chunk.
|
|
|
|
class PopulatedCordFactory {
|
|
|
|
public:
|
|
|
|
constexpr PopulatedCordFactory(absl::string_view name,
|
|
|
|
absl::Cord (*generator)())
|
|
|
|
: name_(name), generator_(generator) {}
|
|
|
|
|
|
|
|
absl::string_view Name() const { return name_; }
|
|
|
|
absl::Cord Generate() const { return generator_(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
absl::string_view name_;
|
|
|
|
absl::Cord (*generator_)();
|
|
|
|
};
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
// This array is constant-initialized in conformant compilers.
|
|
|
|
PopulatedCordFactory cord_factories[] = {
|
|
|
|
{"sso", [] { return absl::Cord("abcde"); }},
|
|
|
|
{"flat", [] {
|
|
|
|
// Too large to live in SSO space, but small enough to be a simple FLAT.
|
|
|
|
absl::Cord flat(absl::StrCat("abcde", std::string(1000, 'x')));
|
|
|
|
flat.Flatten();
|
|
|
|
return flat;
|
|
|
|
}},
|
|
|
|
{"external", [] {
|
|
|
|
// A cheat: we are using a string literal as the external storage, so a
|
|
|
|
// no-op releaser is correct here.
|
|
|
|
return absl::MakeCordFromExternal("abcde External!", []{});
|
|
|
|
}},
|
|
|
|
{"external substring", [] {
|
|
|
|
// A cheat: we are using a string literal as the external storage, so a
|
|
|
|
// no-op releaser is correct here.
|
|
|
|
absl::Cord ext = absl::MakeCordFromExternal("-abcde External!", []{});
|
|
|
|
return absl::CordTestPeer::MakeSubstring(ext, 1, ext.size() - 1);
|
|
|
|
}},
|
|
|
|
{"substring", [] {
|
|
|
|
absl::Cord flat(absl::StrCat("-abcde", std::string(1000, 'x')));
|
|
|
|
flat.Flatten();
|
|
|
|
return flat.Subcord(1, 998);
|
|
|
|
}},
|
|
|
|
{"fragmented", [] {
|
|
|
|
std::string fragment = absl::StrCat("abcde", std::string(195, 'x'));
|
|
|
|
std::vector<std::string> fragments(200, fragment);
|
|
|
|
absl::Cord cord = absl::MakeFragmentedCord(fragments);
|
|
|
|
assert(cord.size() == 40000);
|
|
|
|
return cord;
|
|
|
|
}},
|
|
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
// Test helper that can mutate a cord, and possibly undo the mutation, for
|
|
|
|
// testing.
|
|
|
|
class CordMutator {
|
|
|
|
public:
|
|
|
|
constexpr CordMutator(absl::string_view name, void (*mutate)(absl::Cord&),
|
|
|
|
void (*undo)(absl::Cord&) = nullptr)
|
|
|
|
: name_(name), mutate_(mutate), undo_(undo) {}
|
|
|
|
|
|
|
|
absl::string_view Name() const { return name_; }
|
|
|
|
void Mutate(absl::Cord& cord) const { mutate_(cord); }
|
|
|
|
bool CanUndo() const { return undo_ != nullptr; }
|
|
|
|
void Undo(absl::Cord& cord) const { undo_(cord); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
absl::string_view name_;
|
|
|
|
void (*mutate_)(absl::Cord&);
|
|
|
|
void (*undo_)(absl::Cord&);
|
|
|
|
};
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
// This array is constant-initialized in conformant compilers.
|
|
|
|
CordMutator cord_mutators[] = {
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
{"clear", [](absl::Cord& c) { c.Clear(); }},
|
|
|
|
{"overwrite", [](absl::Cord& c) { c = "overwritten"; }},
|
|
|
|
{
|
|
|
|
"append string",
|
|
|
|
[](absl::Cord& c) { c.Append("0123456789"); },
|
|
|
|
[](absl::Cord& c) { c.RemoveSuffix(10); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"append cord",
|
|
|
|
[](absl::Cord& c) {
|
|
|
|
c.Append(absl::MakeFragmentedCord({"12345", "67890"}));
|
|
|
|
},
|
|
|
|
[](absl::Cord& c) { c.RemoveSuffix(10); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"append checksummed cord",
|
|
|
|
[](absl::Cord& c) {
|
|
|
|
absl::Cord to_append = absl::MakeFragmentedCord({"12345", "67890"});
|
|
|
|
to_append.SetExpectedChecksum(999);
|
|
|
|
c.Append(to_append);
|
|
|
|
},
|
|
|
|
[](absl::Cord& c) { c.RemoveSuffix(10); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"append self",
|
|
|
|
[](absl::Cord& c) { c.Append(c); },
|
|
|
|
[](absl::Cord& c) { c.RemoveSuffix(c.size() / 2); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"append empty string",
|
|
|
|
[](absl::Cord& c) { c.Append(""); },
|
|
|
|
[](absl::Cord& c) { }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"append empty cord",
|
|
|
|
[](absl::Cord& c) { c.Append(absl::Cord()); },
|
|
|
|
[](absl::Cord& c) { }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"append empty checksummed cord",
|
|
|
|
[](absl::Cord& c) {
|
|
|
|
absl::Cord to_append;
|
|
|
|
to_append.SetExpectedChecksum(999);
|
|
|
|
c.Append(to_append);
|
|
|
|
},
|
|
|
|
[](absl::Cord& c) { }
|
|
|
|
},
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
{
|
|
|
|
"prepend string",
|
|
|
|
[](absl::Cord& c) { c.Prepend("9876543210"); },
|
|
|
|
[](absl::Cord& c) { c.RemovePrefix(10); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"prepend cord",
|
|
|
|
[](absl::Cord& c) {
|
|
|
|
c.Prepend(absl::MakeFragmentedCord({"98765", "43210"}));
|
|
|
|
},
|
|
|
|
[](absl::Cord& c) { c.RemovePrefix(10); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"prepend checksummed cord",
|
|
|
|
[](absl::Cord& c) {
|
|
|
|
absl::Cord to_prepend = absl::MakeFragmentedCord({"98765", "43210"});
|
|
|
|
to_prepend.SetExpectedChecksum(999);
|
|
|
|
c.Prepend(to_prepend);
|
|
|
|
},
|
|
|
|
[](absl::Cord& c) { c.RemovePrefix(10); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"prepend empty string",
|
|
|
|
[](absl::Cord& c) { c.Prepend(""); },
|
|
|
|
[](absl::Cord& c) { }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"prepend empty cord",
|
|
|
|
[](absl::Cord& c) { c.Prepend(absl::Cord()); },
|
|
|
|
[](absl::Cord& c) { }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"prepend empty checksummed cord",
|
|
|
|
[](absl::Cord& c) {
|
|
|
|
absl::Cord to_prepend;
|
|
|
|
to_prepend.SetExpectedChecksum(999);
|
|
|
|
c.Prepend(to_prepend);
|
|
|
|
},
|
|
|
|
[](absl::Cord& c) { }
|
|
|
|
},
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
{
|
|
|
|
"prepend self",
|
|
|
|
[](absl::Cord& c) { c.Prepend(c); },
|
|
|
|
[](absl::Cord& c) { c.RemovePrefix(c.size() / 2); }
|
|
|
|
},
|
|
|
|
{"remove prefix", [](absl::Cord& c) { c.RemovePrefix(c.size() / 2); }},
|
|
|
|
{"remove suffix", [](absl::Cord& c) { c.RemoveSuffix(c.size() / 2); }},
|
|
|
|
{"remove 0-prefix", [](absl::Cord& c) { c.RemovePrefix(0); }},
|
|
|
|
{"remove 0-suffix", [](absl::Cord& c) { c.RemoveSuffix(0); }},
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
{"subcord", [](absl::Cord& c) { c = c.Subcord(1, c.size() - 2); }},
|
|
|
|
{
|
|
|
|
"swap inline",
|
|
|
|
[](absl::Cord& c) {
|
|
|
|
absl::Cord other("swap");
|
|
|
|
c.swap(other);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"swap tree",
|
|
|
|
[](absl::Cord& c) {
|
|
|
|
absl::Cord other(std::string(10000, 'x'));
|
|
|
|
c.swap(other);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
TEST_P(CordTest, ExpectedChecksum) {
|
|
|
|
for (const PopulatedCordFactory& factory : cord_factories) {
|
|
|
|
SCOPED_TRACE(factory.Name());
|
|
|
|
for (bool shared : {false, true}) {
|
|
|
|
SCOPED_TRACE(shared);
|
|
|
|
|
|
|
|
absl::Cord shared_cord_source = factory.Generate();
|
|
|
|
auto make_instance = [=] {
|
|
|
|
return shared ? shared_cord_source : factory.Generate();
|
|
|
|
};
|
|
|
|
|
|
|
|
const absl::Cord base_value = factory.Generate();
|
|
|
|
const std::string base_value_as_string(factory.Generate().Flatten());
|
|
|
|
|
|
|
|
absl::Cord c1 = make_instance();
|
|
|
|
EXPECT_FALSE(c1.ExpectedChecksum().has_value());
|
|
|
|
|
|
|
|
// Setting an expected checksum works, and retains the cord's bytes
|
|
|
|
c1.SetExpectedChecksum(12345);
|
|
|
|
EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
EXPECT_EQ(c1, base_value);
|
|
|
|
|
|
|
|
// Test that setting an expected checksum again doesn't crash or leak
|
|
|
|
// memory.
|
|
|
|
c1.SetExpectedChecksum(12345);
|
|
|
|
EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
EXPECT_EQ(c1, base_value);
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
// CRC persists through copies, assignments, and moves:
|
|
|
|
absl::Cord c1_copy_construct = c1;
|
|
|
|
EXPECT_EQ(c1_copy_construct.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
|
|
|
|
absl::Cord c1_copy_assign;
|
|
|
|
c1_copy_assign = c1;
|
|
|
|
EXPECT_EQ(c1_copy_assign.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
|
|
|
|
absl::Cord c1_move(std::move(c1_copy_assign));
|
|
|
|
EXPECT_EQ(c1_move.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
|
|
|
|
EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
|
|
|
|
// A CRC Cord compares equal to its non-CRC value.
|
|
|
|
EXPECT_EQ(c1, make_instance());
|
|
|
|
|
|
|
|
for (const CordMutator& mutator : cord_mutators) {
|
|
|
|
SCOPED_TRACE(mutator.Name());
|
|
|
|
|
|
|
|
// Test that mutating a cord removes its stored checksum
|
|
|
|
absl::Cord c2 = make_instance();
|
|
|
|
c2.SetExpectedChecksum(24680);
|
|
|
|
|
|
|
|
mutator.Mutate(c2);
|
|
|
|
|
|
|
|
if (c1 == c2) {
|
|
|
|
// Not a mutation (for example, appending the empty string).
|
|
|
|
// Whether the checksum is removed is not defined.
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
Export of internal Abseil changes
--
83e4cdf03a4d702b30e69204060de09e462e23c6 by Greg Falcon <gfalcon@google.com>:
Revert the crc addition to RefcountAndFlags, and restore related comments to their original state.
In development, the implementation of SetExpectedCrc() changed, and there is no longer a need to track the CRC status in the refcount.
Since the distinction between IsOne() and IsMutable() is subtle *and unused*, removing it now can help avoid subtle bugs in the future. This distinction can always be added back later, if it proves necessary.
Keep the reserved bit for now; all it costs is one extra mask instruction in the refcount checks, and space for extra state in Cord is always hard to find.
PiperOrigin-RevId: 408647038
--
ee67585cf66954176615271f50f8b278119dd138 by Greg Falcon <gfalcon@google.com>:
Implement Cord::SetExpectedChecksum() and Cord::ExpectedChecksum().
SetExpectedChecksum() will store a uint32_t out-of-band alongside a Cord's data. This value persists through copies and assignments. Mutating operations on a Cord cause the value to be forgotten. ExpectedChecksum() retrieves the stored value, if present.
This API is intended for storing a CRC32C checksum alongside data, allowing checksums to be passed through dataflows and validated at the final step. However, this API is agnostic to the meaning of the stored value. No CRC32C validation is performed by these new APIs.
This implementation adds a new CordRep node, CordRepCrc. A CordRepCrc may (currently) only live at the top of a tree. This allows traversal logic to be agnostic to these nodes, instead putting the needed branches at the mutation level. This also implements the property requested from API review, that any mutation is guaranteed to permanently forget the stored CRC.
PiperOrigin-RevId: 408611221
--
a86f592402b37c854ebdc77d2b9b425451a7a675 by Martijn Vels <mvels@google.com>:
Move 'ExtractResult' into CordRep
The result of an extract operation is logically identical for any tree implementation, and having a single type makes 'tree independent' implementation in cord.cc more concise.
PiperOrigin-RevId: 408332408
--
baa7647e21db59a87f75af9cac62172ce38a0f71 by Abseil Team <absl-team@google.com>:
Replace usages of `assert` macros with `ABSL_HARDENING_ASSERT`.
PiperOrigin-RevId: 408272133
--
c7658133d8662c39fa5035fc93a364c7c3d327e0 by Martijn Vels <mvels@google.com>:
Add CordRepBtree::ExtractAppendBuffer
PiperOrigin-RevId: 407944179
--
5775100363b5890ebfe710fadebf040445eab991 by Martijn Vels <mvels@google.com>:
Add CordRepConcat::ExtractAppendBuffer
PiperOrigin-RevId: 407932968
--
9f520ba1600a93352c78f644a369c7c76195ee86 by Greg Falcon <gfalcon@google.com>:
Add cordz tracking for crc nodes.
This also adds a new kSetExpectedChecksum method to the list of tracked methods. This is presently unused but will be used soon.
PiperOrigin-RevId: 407884120
GitOrigin-RevId: 83e4cdf03a4d702b30e69204060de09e462e23c6
Change-Id: I134ace2d87215813eaa60a282996a33884676c06
3 years ago
|
|
|
EXPECT_EQ(c2.ExpectedChecksum(), absl::nullopt);
|
|
|
|
|
|
|
|
if (mutator.CanUndo()) {
|
|
|
|
// Undoing an operation should not restore the checksum
|
|
|
|
mutator.Undo(c2);
|
|
|
|
EXPECT_EQ(c2, base_value);
|
|
|
|
EXPECT_EQ(c2.ExpectedChecksum(), absl::nullopt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
absl::Cord c3 = make_instance();
|
|
|
|
c3.SetExpectedChecksum(999);
|
|
|
|
const absl::Cord& cc3 = c3;
|
|
|
|
|
|
|
|
// Test that all cord reading operations function in the face of an
|
|
|
|
// expected checksum.
|
|
|
|
|
|
|
|
// Test data precondition
|
|
|
|
ASSERT_TRUE(cc3.StartsWith("abcde"));
|
|
|
|
|
|
|
|
EXPECT_EQ(cc3.size(), base_value_as_string.size());
|
|
|
|
EXPECT_FALSE(cc3.empty());
|
|
|
|
EXPECT_EQ(cc3.Compare(base_value), 0);
|
|
|
|
EXPECT_EQ(cc3.Compare(base_value_as_string), 0);
|
|
|
|
EXPECT_EQ(cc3.Compare("wxyz"), -1);
|
|
|
|
EXPECT_EQ(cc3.Compare(absl::Cord("wxyz")), -1);
|
|
|
|
EXPECT_EQ(cc3.Compare("aaaa"), 1);
|
|
|
|
EXPECT_EQ(cc3.Compare(absl::Cord("aaaa")), 1);
|
|
|
|
EXPECT_EQ(absl::Cord("wxyz").Compare(cc3), 1);
|
|
|
|
EXPECT_EQ(absl::Cord("aaaa").Compare(cc3), -1);
|
|
|
|
EXPECT_TRUE(cc3.StartsWith("abcd"));
|
|
|
|
EXPECT_EQ(std::string(cc3), base_value_as_string);
|
|
|
|
|
|
|
|
std::string dest;
|
|
|
|
absl::CopyCordToString(cc3, &dest);
|
|
|
|
EXPECT_EQ(dest, base_value_as_string);
|
|
|
|
|
|
|
|
bool first_pass = true;
|
|
|
|
for (absl::string_view chunk : cc3.Chunks()) {
|
|
|
|
if (first_pass) {
|
|
|
|
EXPECT_TRUE(absl::StartsWith(chunk, "abcde"));
|
|
|
|
}
|
|
|
|
first_pass = false;
|
|
|
|
}
|
|
|
|
first_pass = true;
|
|
|
|
for (char ch : cc3.Chars()) {
|
|
|
|
if (first_pass) {
|
|
|
|
EXPECT_EQ(ch, 'a');
|
|
|
|
}
|
|
|
|
first_pass = false;
|
|
|
|
}
|
|
|
|
EXPECT_TRUE(absl::StartsWith(*cc3.chunk_begin(), "abcde"));
|
|
|
|
EXPECT_EQ(*cc3.char_begin(), 'a');
|
|
|
|
|
|
|
|
auto char_it = cc3.char_begin();
|
|
|
|
absl::Cord::Advance(&char_it, 2);
|
|
|
|
EXPECT_EQ(absl::Cord::AdvanceAndRead(&char_it, 2), "cd");
|
|
|
|
EXPECT_EQ(*char_it, 'e');
|
|
|
|
char_it = cc3.char_begin();
|
|
|
|
absl::Cord::Advance(&char_it, 2);
|
|
|
|
EXPECT_TRUE(absl::StartsWith(absl::Cord::ChunkRemaining(char_it), "cde"));
|
|
|
|
|
|
|
|
EXPECT_EQ(cc3[0], 'a');
|
|
|
|
EXPECT_EQ(cc3[4], 'e');
|
|
|
|
EXPECT_EQ(absl::HashOf(cc3), absl::HashOf(base_value));
|
|
|
|
EXPECT_EQ(absl::HashOf(cc3), absl::HashOf(base_value_as_string));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test the special cases encountered with an empty checksummed cord.
|
|
|
|
TEST_P(CordTest, ChecksummedEmptyCord) {
|
|
|
|
absl::Cord c1;
|
|
|
|
EXPECT_FALSE(c1.ExpectedChecksum().has_value());
|
|
|
|
|
|
|
|
// Setting an expected checksum works.
|
|
|
|
c1.SetExpectedChecksum(12345);
|
|
|
|
EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
EXPECT_EQ(c1, "");
|
|
|
|
EXPECT_TRUE(c1.empty());
|
|
|
|
|
|
|
|
// Test that setting an expected checksum again doesn't crash or leak memory.
|
|
|
|
c1.SetExpectedChecksum(12345);
|
|
|
|
EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
EXPECT_EQ(c1, "");
|
|
|
|
EXPECT_TRUE(c1.empty());
|
|
|
|
|
|
|
|
// CRC persists through copies, assignments, and moves:
|
|
|
|
absl::Cord c1_copy_construct = c1;
|
|
|
|
EXPECT_EQ(c1_copy_construct.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
|
|
|
|
absl::Cord c1_copy_assign;
|
|
|
|
c1_copy_assign = c1;
|
|
|
|
EXPECT_EQ(c1_copy_assign.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
|
|
|
|
absl::Cord c1_move(std::move(c1_copy_assign));
|
|
|
|
EXPECT_EQ(c1_move.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
|
|
|
|
EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345);
|
|
|
|
|
|
|
|
// A CRC Cord compares equal to its non-CRC value.
|
|
|
|
EXPECT_EQ(c1, absl::Cord());
|
|
|
|
|
|
|
|
for (const CordMutator& mutator : cord_mutators) {
|
|
|
|
SCOPED_TRACE(mutator.Name());
|
|
|
|
|
|
|
|
// Exercise mutating an empty checksummed cord to catch crashes and exercise
|
|
|
|
// memory sanitizers.
|
|
|
|
absl::Cord c2;
|
|
|
|
c2.SetExpectedChecksum(24680);
|
|
|
|
mutator.Mutate(c2);
|
|
|
|
|
|
|
|
if (c2.empty()) {
|
|
|
|
// Not a mutation
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
EXPECT_EQ(c2.ExpectedChecksum(), absl::nullopt);
|
|
|
|
|
|
|
|
if (mutator.CanUndo()) {
|
|
|
|
mutator.Undo(c2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
absl::Cord c3;
|
|
|
|
c3.SetExpectedChecksum(999);
|
|
|
|
const absl::Cord& cc3 = c3;
|
|
|
|
|
|
|
|
// Test that all cord reading operations function in the face of an
|
|
|
|
// expected checksum.
|
|
|
|
EXPECT_TRUE(cc3.StartsWith(""));
|
|
|
|
EXPECT_TRUE(cc3.EndsWith(""));
|
|
|
|
EXPECT_TRUE(cc3.empty());
|
|
|
|
EXPECT_EQ(cc3, "");
|
|
|
|
EXPECT_EQ(cc3, absl::Cord());
|
|
|
|
EXPECT_EQ(cc3.size(), 0);
|
|
|
|
EXPECT_EQ(cc3.Compare(absl::Cord()), 0);
|
|
|
|
EXPECT_EQ(cc3.Compare(c1), 0);
|
|
|
|
EXPECT_EQ(cc3.Compare(cc3), 0);
|
|
|
|
EXPECT_EQ(cc3.Compare(""), 0);
|
|
|
|
EXPECT_EQ(cc3.Compare("wxyz"), -1);
|
|
|
|
EXPECT_EQ(cc3.Compare(absl::Cord("wxyz")), -1);
|
|
|
|
EXPECT_EQ(absl::Cord("wxyz").Compare(cc3), 1);
|
|
|
|
EXPECT_EQ(std::string(cc3), "");
|
|
|
|
|
|
|
|
std::string dest;
|
|
|
|
absl::CopyCordToString(cc3, &dest);
|
|
|
|
EXPECT_EQ(dest, "");
|
|
|
|
|
|
|
|
for (absl::string_view chunk : cc3.Chunks()) { // NOLINT(unreachable loop)
|
|
|
|
static_cast<void>(chunk);
|
|
|
|
GTEST_FAIL() << "no chunks expected";
|
|
|
|
}
|
|
|
|
EXPECT_TRUE(cc3.chunk_begin() == cc3.chunk_end());
|
|
|
|
|
|
|
|
for (char ch : cc3.Chars()) { // NOLINT(unreachable loop)
|
|
|
|
static_cast<void>(ch);
|
|
|
|
GTEST_FAIL() << "no chars expected";
|
|
|
|
}
|
|
|
|
EXPECT_TRUE(cc3.char_begin() == cc3.char_end());
|
|
|
|
|
|
|
|
EXPECT_EQ(cc3.TryFlat(), "");
|
|
|
|
EXPECT_EQ(absl::HashOf(c3), absl::HashOf(absl::Cord()));
|
|
|
|
EXPECT_EQ(absl::HashOf(c3), absl::HashOf(absl::string_view()));
|
|
|
|
}
|