Commit 73316fc3 by Abseil Team Committed by Andy Getz

Export of internal Abseil changes

--
262f6992ee0553782531ad58dd7d8bcd6d0b7bb7 by Martijn Vels <mvels@google.com>:

Remove CordRepConcat uses in tests and CONCAT constants.

This change removes the creation and uses of CordRepConcat in unit tests, and replaces some remaining CONCAT constants with IsConcat() to make subsequent teardown of CordrepConcat uses easier.

PiperOrigin-RevId: 426932694

--
fd590f7e849ba8c5395c589ed3f762cd00affdc8 by Abseil Team <absl-team@google.com>:

Replace NULL and 0 with nullptr.

PiperOrigin-RevId: 426912932

--
183e5babc478748023f732a1608745a2a544c996 by Abseil Team <absl-team@google.com>:

Replace "span of time" with "amount of time" in the first comment line, to make it clearer that we're not talking about a duration that starts at a specific time.

PiperOrigin-RevId: 426691794

--
e28ca760f21505f1be55c7af336eb61d2f1b7fea by Martijn Vels <mvels@google.com>:

Add extra assertions on CordRepSubstring child nodes

PiperOrigin-RevId: 426369104
GitOrigin-RevId: 262f6992ee0553782531ad58dd7d8bcd6d0b7bb7
Change-Id: I7ffdaa2dc999a2117944c9abdb1565b6b6f48b59
parent 36db0e4b
......@@ -86,7 +86,7 @@ static void Test(bool use_new_arena, bool call_malloc_hook, int n) {
AllocMap::iterator it;
BlockDesc block_desc;
int rnd;
LowLevelAlloc::Arena *arena = 0;
LowLevelAlloc::Arena *arena = nullptr;
if (use_new_arena) {
int32_t flags = call_malloc_hook ? LowLevelAlloc::kCallMallocHook : 0;
arena = LowLevelAlloc::NewArena(flags);
......@@ -101,11 +101,10 @@ static void Test(bool use_new_arena, bool call_malloc_hook, int n) {
case 0: // coin came up heads: add a block
using_low_level_alloc = true;
block_desc.len = rand() & 0x3fff;
block_desc.ptr =
reinterpret_cast<char *>(
arena == 0
? LowLevelAlloc::Alloc(block_desc.len)
: LowLevelAlloc::AllocWithArena(block_desc.len, arena));
block_desc.ptr = reinterpret_cast<char *>(
arena == nullptr
? LowLevelAlloc::Alloc(block_desc.len)
: LowLevelAlloc::AllocWithArena(block_desc.len, arena));
using_low_level_alloc = false;
RandomizeBlockDesc(&block_desc);
rnd = rand();
......
......@@ -309,20 +309,6 @@ cc_library(
)
cc_test(
name = "cord_rep_concat_test",
size = "small",
srcs = ["internal/cord_rep_concat_test.cc"],
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
":cord_internal",
":cord_rep_test_util",
"//absl/base:config",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "cord_rep_btree_test",
size = "medium",
srcs = ["internal/cord_rep_btree_test.cc"],
......@@ -759,22 +745,6 @@ cc_test(
)
cc_test(
name = "cord_rep_consume_test",
size = "medium",
srcs = ["internal/cord_rep_consume_test.cc"],
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
":cord_internal",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/debugging:leak_check",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "cord_ring_test",
size = "medium",
srcs = ["cord_ring_test.cc"],
......
......@@ -935,40 +935,6 @@ absl_cc_test(
absl_cc_test(
NAME
cord_rep_consume_test
SRCS
"internal/cord_rep_consume_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::config
absl::cord_internal
absl::core_headers
absl::function_ref
absl::raw_logging_internal
absl::strings
GTest::gmock_main
)
absl_cc_test(
NAME
cord_rep_concat_test
SRCS
"internal/cord_rep_concat_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::config
absl::cord_internal
absl::cord_rep_test_util
absl::core_headers
GTest::gmock_main
)
absl_cc_test(
NAME
cord_rep_btree_test
SRCS
"internal/cord_rep_btree_test.cc"
......
......@@ -211,7 +211,7 @@ size_t GetEstimatedUsage(const CordRep* rep) {
AnalyzeDataEdge(repref, raw_usage);
} else if (repref.rep->tag == BTREE) {
AnalyzeBtree(repref, raw_usage);
} else if (repref.rep->tag == CONCAT) {
} else if (repref.rep->IsConcat()) {
AnalyzeConcat(repref, raw_usage);
} else if (repref.rep->tag == RING) {
AnalyzeRing(repref, raw_usage);
......
......@@ -44,7 +44,6 @@ using ::absl::cord_internal::CordRepFlat;
using ::absl::cord_internal::CordRepRing;
using ::absl::cord_internal::CordRepSubstring;
using ::absl::cord_internal::CONCAT;
using ::absl::cord_internal::EXTERNAL;
using ::absl::cord_internal::SUBSTRING;
......@@ -262,16 +261,6 @@ CordRepSubstring* RemoveSuffix(size_t length, CordRep* rep) {
return MakeSubstring(0, rep->length - length, rep);
}
CordRepConcat* MakeConcat(CordRep* left, CordRep* right, int depth = 0) {
auto* concat = new CordRepConcat;
concat->tag = CONCAT;
concat->length = left->length + right->length;
concat->left = left;
concat->right = right;
concat->set_depth(depth);
return concat;
}
enum Composition { kMix, kAppend, kPrepend };
Composition RandomComposition() {
......@@ -296,7 +285,6 @@ constexpr const char* kFox = "The quick brown fox jumps over the lazy dog";
constexpr const char* kFoxFlats[] = {"The ", "quick ", "brown ",
"fox ", "jumps ", "over ",
"the ", "lazy ", "dog"};
constexpr const char* kAlphabet = "abcdefghijklmnopqrstuvwxyz";
CordRepRing* FromFlats(Span<const char* const> flats,
Composition composition = kAppend) {
......@@ -594,35 +582,6 @@ TEST_P(CordRingCreateFromTreeTest, CreateFromSubstringOfLargeExternal) {
EXPECT_THAT(ToRawFlats(result), ElementsAre(str));
}
TEST_P(CordRingBuildInputTest, CreateFromConcat) {
CordRep* flats[] = {MakeFlat("abcdefgh"), MakeFlat("ijklm"),
MakeFlat("nopqrstuv"), MakeFlat("wxyz")};
auto* left = MakeConcat(RefIfInputSharedIndirect(flats[0]), flats[1]);
auto* right = MakeConcat(flats[2], RefIfInputSharedIndirect(flats[3]));
auto* concat = RefIfInputShared(MakeConcat(left, right));
CordRepRing* result = NeedsUnref(CordRepRing::Create(concat));
ASSERT_THAT(result, IsValidRingBuffer());
EXPECT_THAT(result->length, Eq(26));
EXPECT_THAT(ToString(result), Eq(kAlphabet));
}
TEST_P(CordRingBuildInputTest, CreateFromSubstringConcat) {
for (size_t off = 0; off < 26; ++off) {
for (size_t len = 1; len < 26 - off; ++len) {
CordRep* flats[] = {MakeFlat("abcdefgh"), MakeFlat("ijklm"),
MakeFlat("nopqrstuv"), MakeFlat("wxyz")};
auto* left = MakeConcat(RefIfInputSharedIndirect(flats[0]), flats[1]);
auto* right = MakeConcat(flats[2], RefIfInputSharedIndirect(flats[3]));
auto* concat = MakeConcat(left, right);
auto* child = RefIfInputShared(MakeSubstring(off, len, concat));
CordRepRing* result = NeedsUnref(CordRepRing::Create(child));
ASSERT_THAT(result, IsValidRingBuffer());
ASSERT_THAT(result->length, Eq(len));
ASSERT_THAT(ToString(result), string_view(kAlphabet).substr(off, len));
}
}
}
TEST_P(CordRingCreateTest, Properties) {
absl::string_view str1 = "abcdefghijklmnopqrstuvwxyz";
CordRepRing* result = NeedsUnref(CordRepRing::Create(MakeFlat(str1), 120));
......
......@@ -39,7 +39,7 @@ void CordRep::Destroy(CordRep* rep) {
absl::InlinedVector<CordRep*, Constants::kInlinedVectorSize> pending;
while (true) {
assert(!rep->refcount.IsImmortal());
if (rep->tag == CONCAT) {
if (rep->IsConcat()) {
CordRepConcat* rep_concat = rep->concat();
CordRep* right = rep_concat->right;
if (!right->refcount.Decrement()) {
......
......@@ -119,6 +119,7 @@ CordRepSubstring* CreateSubstring(CordRep* rep, size_t offset, size_t n) {
rep = CordRep::Ref(substring->child);
CordRep::Unref(substring);
}
assert(rep->IsExternal() || rep->IsFlat());
CordRepSubstring* substring = new CordRepSubstring();
substring->length = n;
substring->tag = SUBSTRING;
......
......@@ -49,6 +49,7 @@ inline CordRep* Substring(CordRep* rep, size_t offset, size_t n) {
rep = rep->substring()->child;
}
assert(rep->IsExternal() || rep->IsFlat());
CordRepSubstring* substring = new CordRepSubstring();
substring->length = n;
substring->tag = SUBSTRING;
......
......@@ -52,7 +52,6 @@ using ::absl::cordrep_testing::CordToString;
using ::absl::cordrep_testing::CordVisitReps;
using ::absl::cordrep_testing::CreateFlatsFromString;
using ::absl::cordrep_testing::CreateRandomString;
using ::absl::cordrep_testing::MakeConcat;
using ::absl::cordrep_testing::MakeExternal;
using ::absl::cordrep_testing::MakeFlat;
using ::absl::cordrep_testing::MakeSubstring;
......@@ -322,7 +321,6 @@ TEST(CordRepBtreeTest, EdgeData) {
CordRepExternal* external = MakeExternal("Hello external");
CordRep* substr1 = MakeSubstring(1, 6, CordRep::Ref(flat));
CordRep* substr2 = MakeSubstring(1, 6, CordRep::Ref(external));
CordRep* concat = MakeConcat(CordRep::Ref(flat), CordRep::Ref(external));
CordRep* bad_substr = MakeSubstring(1, 2, CordRep::Ref(substr1));
EXPECT_TRUE(CordRepBtree::IsDataEdge(flat));
......@@ -345,17 +343,13 @@ TEST(CordRepBtreeTest, EdgeData) {
TypedEq<const void*>(external->base + 1));
EXPECT_THAT(CordRepBtree::EdgeData(substr2), Eq("ello e"));
EXPECT_FALSE(CordRepBtree::IsDataEdge(concat));
EXPECT_FALSE(CordRepBtree::IsDataEdge(bad_substr));
#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
EXPECT_DEATH(CordRepBtree::EdgeData(concat), ".*");
EXPECT_DEATH(CordRepBtree::EdgeDataPtr(concat), ".*");
EXPECT_DEATH(CordRepBtree::EdgeData(bad_substr), ".*");
EXPECT_DEATH(CordRepBtree::EdgeDataPtr(bad_substr), ".*");
#endif
CordRep::Unref(bad_substr);
CordRep::Unref(concat);
CordRep::Unref(substr2);
CordRep::Unref(substr1);
CordRep::Unref(external);
......@@ -1006,50 +1000,6 @@ TEST_P(CordRepBtreeTest, AddLargeDataToLeaf) {
}
}
TEST_P(CordRepBtreeDualTest, CreateFromConcat) {
AutoUnref refs;
CordRep* flats[] = {MakeFlat("abcdefgh"), MakeFlat("ijklm"),
MakeFlat("nopqrstuv"), MakeFlat("wxyz")};
auto* left = MakeConcat(flats[0], flats[1]);
auto* right = MakeConcat(flats[2], refs.RefIf(first_shared(), flats[3]));
auto* concat = refs.RefIf(second_shared(), MakeConcat(left, right));
CordRepBtree* result = CordRepBtree::Create(concat);
ASSERT_TRUE(CordRepBtree::IsValid(result));
EXPECT_THAT(result->length, Eq(26));
EXPECT_THAT(CordToString(result), Eq("abcdefghijklmnopqrstuvwxyz"));
CordRep::Unref(result);
}
TEST_P(CordRepBtreeDualTest, AppendConcat) {
AutoUnref refs;
CordRep* flats[] = {MakeFlat("defgh"), MakeFlat("ijklm"),
MakeFlat("nopqrstuv"), MakeFlat("wxyz")};
auto* left = MakeConcat(flats[0], flats[1]);
auto* right = MakeConcat(flats[2], refs.RefIf(first_shared(), flats[3]));
auto* concat = refs.RefIf(second_shared(), MakeConcat(left, right));
CordRepBtree* result = CordRepBtree::Create(MakeFlat("abc"));
result = CordRepBtree::Append(result, concat);
ASSERT_TRUE(CordRepBtree::IsValid(result));
EXPECT_THAT(result->length, Eq(26));
EXPECT_THAT(CordToString(result), Eq("abcdefghijklmnopqrstuvwxyz"));
CordRep::Unref(result);
}
TEST_P(CordRepBtreeDualTest, PrependConcat) {
AutoUnref refs;
CordRep* flats[] = {MakeFlat("abcdefgh"), MakeFlat("ijklm"),
MakeFlat("nopqrstuv"), MakeFlat("wx")};
auto* left = MakeConcat(flats[0], flats[1]);
auto* right = MakeConcat(flats[2], refs.RefIf(first_shared(), flats[3]));
auto* concat = refs.RefIf(second_shared(), MakeConcat(left, right));
CordRepBtree* result = CordRepBtree::Create(MakeFlat("yz"));
result = CordRepBtree::Prepend(result, concat);
ASSERT_TRUE(CordRepBtree::IsValid(result));
EXPECT_THAT(result->length, Eq(26));
EXPECT_THAT(CordToString(result), Eq("abcdefghijklmnopqrstuvwxyz"));
CordRep::Unref(result);
}
TEST_P(CordRepBtreeTest, CreateFromTreeReturnsTree) {
AutoUnref refs;
CordRepBtree* leaf = CordRepBtree::Create(MakeFlat("Hello world"));
......
// Copyright 2021 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 <cstdint>
#include <utility>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_test_util.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {
namespace {
using ::absl::cordrep_testing::MakeFlat;
using ::absl::cordrep_testing::MakeSubstring;
using ::testing::Eq;
MATCHER_P2(EqExtractResult, tree, rep, "Equals ExtractResult") {
if (arg.tree != tree || arg.extracted != rep) {
*result_listener << "Expected {" << static_cast<const void*>(tree) << ", "
<< static_cast<const void*>(rep) << "}, got {" << arg.tree
<< ", " << arg.extracted << "}";
return false;
}
return true;
}
CordRepConcat* MakeConcat(CordRep* left, CordRep* right, int depth) {
CordRepConcat* concat = new CordRepConcat;
concat->tag = CONCAT;
concat->set_depth(depth);
concat->length = left->length + right->length;
concat->left = left;
concat->right = right;
return concat;
}
CordRepConcat::ExtractResult ExtractLast(CordRepConcat* concat,
size_t extra_capacity = 1) {
return CordRepConcat::ExtractAppendBuffer(concat, extra_capacity);
}
TEST(CordRepConcatTest, ExtractAppendBufferTwoFlats) {
CordRepFlat* flat1 = MakeFlat("abc");
CordRepFlat* flat2 = MakeFlat("defg");
CordRepConcat* concat = MakeConcat(flat1, flat2, 0);
EXPECT_THAT(ExtractLast(concat), EqExtractResult(flat1, flat2));
CordRep::Unref(flat1);
CordRep::Unref(flat2);
}
TEST(CordRepConcatTest, ExtractAppendBufferThreeFlatsOne) {
CordRepFlat* flat1 = MakeFlat("abc");
CordRepFlat* flat2 = MakeFlat("defg");
CordRepFlat* flat3 = MakeFlat("hijkl");
CordRepConcat* lconcat = MakeConcat(flat1, flat2, 0);
CordRepConcat* concat = MakeConcat(lconcat, flat3, 1);
EXPECT_THAT(ExtractLast(concat), EqExtractResult(lconcat, flat3));
ASSERT_THAT(lconcat->length, Eq(7));
CordRep::Unref(lconcat);
CordRep::Unref(flat3);
}
TEST(CordRepConcatTest, ExtractAppendBufferThreeFlatsTwo) {
CordRepFlat* flat1 = MakeFlat("hijkl");
CordRepFlat* flat2 = MakeFlat("abc");
CordRepFlat* flat3 = MakeFlat("defg");
CordRepConcat* rconcat = MakeConcat(flat2, flat3, 0);
CordRepConcat* concat = MakeConcat(flat1, rconcat, 1);
EXPECT_THAT(ExtractLast(concat), EqExtractResult(concat, flat3));
ASSERT_THAT(concat->length, Eq(8));
CordRep::Unref(concat);
CordRep::Unref(flat3);
}
TEST(CordRepConcatTest, ExtractAppendBufferShared) {
CordRepFlat* flat1 = MakeFlat("hijkl");
CordRepFlat* flat2 = MakeFlat("abc");
CordRepFlat* flat3 = MakeFlat("defg");
CordRepConcat* rconcat = MakeConcat(flat2, flat3, 0);
CordRepConcat* concat = MakeConcat(flat1, rconcat, 1);
CordRep::Ref(concat);
EXPECT_THAT(ExtractLast(concat), EqExtractResult(concat, nullptr));
CordRep::Unref(concat);
CordRep::Ref(rconcat);
EXPECT_THAT(ExtractLast(concat), EqExtractResult(concat, nullptr));
CordRep::Unref(rconcat);
CordRep::Ref(flat3);
EXPECT_THAT(ExtractLast(concat), EqExtractResult(concat, nullptr));
CordRep::Unref(flat3);
CordRep::Unref(concat);
}
TEST(CordRepConcatTest, ExtractAppendBufferNotFlat) {
CordRepFlat* flat1 = MakeFlat("hijkl");
CordRepFlat* flat2 = MakeFlat("abc");
CordRepFlat* flat3 = MakeFlat("defg");
auto substr = MakeSubstring(1, 2, flat3);
CordRepConcat* rconcat = MakeConcat(flat2, substr, 0);
CordRepConcat* concat = MakeConcat(flat1, rconcat, 1);
EXPECT_THAT(ExtractLast(concat), EqExtractResult(concat, nullptr));
CordRep::Unref(concat);
}
TEST(CordRepConcatTest, ExtractAppendBufferNoCapacity) {
CordRepFlat* flat1 = MakeFlat("hijkl");
CordRepFlat* flat2 = MakeFlat("abc");
CordRepFlat* flat3 = MakeFlat("defg");
size_t avail = flat3->Capacity() - flat3->length;
CordRepConcat* rconcat = MakeConcat(flat2, flat3, 0);
CordRepConcat* concat = MakeConcat(flat1, rconcat, 1);
// Should fail if 1 byte over, success if exactly matching
EXPECT_THAT(ExtractLast(concat, avail + 1), EqExtractResult(concat, nullptr));
EXPECT_THAT(ExtractLast(concat, avail), EqExtractResult(concat, flat3));
CordRep::Unref(concat);
CordRep::Unref(flat3);
}
} // namespace
} // namespace cord_internal
ABSL_NAMESPACE_END
} // namespace absl
......@@ -66,7 +66,7 @@ void Consume(bool forward, CordRep* rep, ConsumeFn consume_fn) {
absl::InlinedVector<Entry, 40> stack;
for (;;) {
if (rep->tag == CONCAT) {
if (rep->IsConcat()) {
std::array<CordRep*, 2> res = ClipConcat(rep->concat());
CordRep* left = res[0];
CordRep* right = res[1];
......
// Copyright 2021 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/internal/cord_rep_consume.h"
#include <functional>
#include <utility>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_flat.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {
namespace {
using testing::InSequence;
using testing::MockFunction;
// Returns the depth of a node
int Depth(const CordRep* rep) {
return (rep->tag == CONCAT) ? rep->concat()->depth() : 0;
}
// Creates a concatenation of the specified nodes.
CordRepConcat* CreateConcat(CordRep* left, CordRep* right) {
auto* concat = new CordRepConcat();
concat->tag = CONCAT;
concat->left = left;
concat->right = right;
concat->length = left->length + right->length;
concat->set_depth(1 + (std::max)(Depth(left), Depth(right)));
return concat;
}
// Creates a flat with the length set to `length`
CordRepFlat* CreateFlatWithLength(size_t length) {
auto* flat = CordRepFlat::New(length);
flat->length = length;
return flat;
}
// Creates a substring node on the specified child.
CordRepSubstring* CreateSubstring(CordRep* child, size_t start, size_t length) {
auto* rep = new CordRepSubstring();
rep->length = length;
rep->tag = SUBSTRING;
rep->start = start;
rep->child = child;
return rep;
}
// Flats we use in the tests
CordRep* flat[6];
// Creates a test tree
CordRep* CreateTestTree() {
flat[0] = CreateFlatWithLength(1);
flat[1] = CreateFlatWithLength(7);
CordRepConcat* left = CreateConcat(flat[0], CreateSubstring(flat[1], 2, 4));
flat[2] = CreateFlatWithLength(9);
flat[3] = CreateFlatWithLength(13);
CordRepConcat* right1 = CreateConcat(flat[2], flat[3]);
flat[4] = CreateFlatWithLength(15);
flat[5] = CreateFlatWithLength(19);
CordRepConcat* right2 = CreateConcat(flat[4], flat[5]);
CordRepConcat* right = CreateConcat(right1, CreateSubstring(right2, 5, 17));
return CreateConcat(left, right);
}
TEST(CordRepConsumeTest, Consume) {
InSequence in_sequence;
CordRep* tree = CreateTestTree();
MockFunction<void(CordRep*, size_t, size_t)> consume;
EXPECT_CALL(consume, Call(flat[0], 0, 1));
EXPECT_CALL(consume, Call(flat[1], 2, 4));
EXPECT_CALL(consume, Call(flat[2], 0, 9));
EXPECT_CALL(consume, Call(flat[3], 0, 13));
EXPECT_CALL(consume, Call(flat[4], 5, 10));
EXPECT_CALL(consume, Call(flat[5], 0, 7));
Consume(tree, consume.AsStdFunction());
for (CordRep* rep : flat) {
EXPECT_TRUE(rep->refcount.IsOne());
CordRep::Unref(rep);
}
}
TEST(CordRepConsumeTest, ConsumeShared) {
InSequence in_sequence;
CordRep* tree = CreateTestTree();
MockFunction<void(CordRep*, size_t, size_t)> consume;
EXPECT_CALL(consume, Call(flat[0], 0, 1));
EXPECT_CALL(consume, Call(flat[1], 2, 4));
EXPECT_CALL(consume, Call(flat[2], 0, 9));
EXPECT_CALL(consume, Call(flat[3], 0, 13));
EXPECT_CALL(consume, Call(flat[4], 5, 10));
EXPECT_CALL(consume, Call(flat[5], 0, 7));
Consume(CordRep::Ref(tree), consume.AsStdFunction());
for (CordRep* rep : flat) {
EXPECT_FALSE(rep->refcount.IsOne());
CordRep::Unref(rep);
}
CordRep::Unref(tree);
}
TEST(CordRepConsumeTest, Reverse) {
InSequence in_sequence;
CordRep* tree = CreateTestTree();
MockFunction<void(CordRep*, size_t, size_t)> consume;
EXPECT_CALL(consume, Call(flat[5], 0, 7));
EXPECT_CALL(consume, Call(flat[4], 5, 10));
EXPECT_CALL(consume, Call(flat[3], 0, 13));
EXPECT_CALL(consume, Call(flat[2], 0, 9));
EXPECT_CALL(consume, Call(flat[1], 2, 4));
EXPECT_CALL(consume, Call(flat[0], 0, 1));
ReverseConsume(tree, consume.AsStdFunction());
for (CordRep* rep : flat) {
EXPECT_TRUE(rep->refcount.IsOne());
CordRep::Unref(rep);
}
}
TEST(CordRepConsumeTest, ReverseShared) {
InSequence in_sequence;
CordRep* tree = CreateTestTree();
MockFunction<void(CordRep*, size_t, size_t)> consume;
EXPECT_CALL(consume, Call(flat[5], 0, 7));
EXPECT_CALL(consume, Call(flat[4], 5, 10));
EXPECT_CALL(consume, Call(flat[3], 0, 13));
EXPECT_CALL(consume, Call(flat[2], 0, 9));
EXPECT_CALL(consume, Call(flat[1], 2, 4));
EXPECT_CALL(consume, Call(flat[0], 0, 1));
ReverseConsume(CordRep::Ref(tree), consume.AsStdFunction());
for (CordRep* rep : flat) {
EXPECT_FALSE(rep->refcount.IsOne());
CordRep::Unref(rep);
}
CordRep::Unref(tree);
}
TEST(CordRepConsumeTest, UnreachableFlat) {
InSequence in_sequence;
CordRepFlat* flat1 = CreateFlatWithLength(10);
CordRepFlat* flat2 = CreateFlatWithLength(20);
CordRepConcat* concat = CreateConcat(flat1, flat2);
CordRepSubstring* tree = CreateSubstring(concat, 15, 10);
MockFunction<void(CordRep*, size_t, size_t)> consume;
EXPECT_CALL(consume, Call(flat2, 5, 10));
Consume(tree, consume.AsStdFunction());
EXPECT_TRUE(flat2->refcount.IsOne());
CordRep::Unref(flat2);
}
} // namespace
} // namespace cord_internal
ABSL_NAMESPACE_END
} // namespace absl
......@@ -42,18 +42,6 @@ inline cord_internal::CordRepSubstring* MakeSubstring(
return sub;
}
inline cord_internal::CordRepConcat* MakeConcat(cord_internal::CordRep* left,
cord_internal::CordRep* right,
int depth = 0) {
auto* concat = new cord_internal::CordRepConcat;
concat->tag = cord_internal::CONCAT;
concat->length = left->length + right->length;
concat->left = left;
concat->right = right;
concat->set_depth(depth);
return concat;
}
inline cord_internal::CordRepFlat* MakeFlat(absl::string_view value) {
assert(value.length() <= cord_internal::kMaxFlatLength);
auto* flat = cord_internal::CordRepFlat::New(value.length());
......@@ -126,7 +114,7 @@ inline void CordVisitReps(cord_internal::CordRep* rep, Fn&& fn) {
for (cord_internal::CordRep* edge : rep->btree()->Edges()) {
CordVisitReps(edge, fn);
}
} else if (rep->tag == cord_internal::CONCAT) {
} else if (rep->IsConcat()) {
CordVisitReps(rep->concat()->left, fn);
CordVisitReps(rep->concat()->right, fn);
}
......
......@@ -98,7 +98,7 @@ class CordRepAnalyzer {
AnalyzeRing(repref);
} else if (repref.rep->tag == BTREE) {
AnalyzeBtree(repref);
} else if (repref.rep->tag == CONCAT) {
} else if (repref.rep->IsConcat()) {
AnalyzeConcat(repref);
} else {
// We should have either a concat, btree, or ring node if not null.
......@@ -145,8 +145,8 @@ class CordRepAnalyzer {
// Asserts that `rr.rep` is a concat node or null.
static RepRef AssertConcat(RepRef repref) {
const CordRep* rep = repref.rep;
assert(rep == nullptr || rep->tag == CONCAT);
return (rep != nullptr && rep->tag == CONCAT) ? repref : RepRef{nullptr, 0};
assert(rep == nullptr || rep->IsConcat());
return (rep != nullptr && rep->IsConcat()) ? repref : RepRef{nullptr, 0};
}
// Counts a flat of the provide allocated size
......
......@@ -76,16 +76,6 @@ CordRepSubstring* Substring(CordRep* rep) {
return substring;
}
// Creates a concat on the provided reps
CordRepConcat* Concat(CordRep* left, CordRep* right) {
auto* concat = new CordRepConcat;
concat->length = left->length + right->length;
concat->tag = CONCAT;
concat->left = left;
concat->right = right;
return concat;
}
// Reference count helper
struct RefHelper {
std::vector<CordRep*> refs;
......@@ -158,7 +148,7 @@ double FairShareImpl(CordRep* rep, size_t ref) {
rep->ring()->ForEach([&](CordRepRing::index_type i) {
self += FairShareImpl(rep->ring()->entry_child(i), 1);
});
} else if (rep->tag == CONCAT) {
} else if (rep->IsConcat()) {
self = SizeOf(rep->concat());
children = FairShareImpl(rep->concat()->left, ref) +
FairShareImpl(rep->concat()->right, ref);
......@@ -307,80 +297,6 @@ TEST(CordzInfoStatisticsTest, SharedSubstring) {
EXPECT_THAT(SampleCord(substring), EqStatistics(expected));
}
TEST(CordzInfoStatisticsTest, Concat) {
RefHelper ref;
auto* flat1 = Flat(300);
auto* flat2 = Flat(2000);
auto* concat = ref.NeedsUnref(Concat(flat1, flat2));
CordzStatistics expected;
expected.size = concat->length;
expected.estimated_memory_usage =
SizeOf(concat) + SizeOf(flat1) + SizeOf(flat2);
expected.estimated_fair_share_memory_usage = expected.estimated_memory_usage;
expected.node_count = 3;
expected.node_counts.flat = 2;
expected.node_counts.flat_512 = 1;
expected.node_counts.concat = 1;
EXPECT_THAT(SampleCord(concat), EqStatistics(expected));
}
TEST(CordzInfoStatisticsTest, DeepConcat) {
RefHelper ref;
auto* flat1 = Flat(300);
auto* flat2 = Flat(2000);
auto* flat3 = Flat(400);
auto* external = External(3000);
auto* substring = Substring(external);
auto* concat1 = Concat(flat1, flat2);
auto* concat2 = Concat(flat3, substring);
auto* concat = ref.NeedsUnref(Concat(concat1, concat2));
CordzStatistics expected;
expected.size = concat->length;
expected.estimated_memory_usage = SizeOf(concat) * 3 + SizeOf(flat1) +
SizeOf(flat2) + SizeOf(flat3) +
SizeOf(external) + SizeOf(substring);
expected.estimated_fair_share_memory_usage = expected.estimated_memory_usage;
expected.node_count = 8;
expected.node_counts.flat = 3;
expected.node_counts.flat_512 = 2;
expected.node_counts.external = 1;
expected.node_counts.concat = 3;
expected.node_counts.substring = 1;
EXPECT_THAT(SampleCord(concat), EqStatistics(expected));
}
TEST(CordzInfoStatisticsTest, DeepSharedConcat) {
RefHelper ref;
auto* flat1 = Flat(40);
auto* flat2 = ref.Ref(Flat(2000), 4);
auto* flat3 = Flat(70);
auto* external = ref.Ref(External(3000));
auto* substring = ref.Ref(Substring(external), 3);
auto* concat1 = Concat(flat1, flat2);
auto* concat2 = Concat(flat3, substring);
auto* concat = ref.Ref(ref.NeedsUnref(Concat(concat1, concat2)));
CordzStatistics expected;
expected.size = concat->length;
expected.estimated_memory_usage = SizeOf(concat) * 3 + SizeOf(flat1) +
SizeOf(flat2) + SizeOf(flat3) +
SizeOf(external) + SizeOf(substring);
expected.estimated_fair_share_memory_usage = FairShare(concat);
expected.node_count = 8;
expected.node_counts.flat = 3;
expected.node_counts.flat_64 = 1;
expected.node_counts.flat_128 = 1;
expected.node_counts.external = 1;
expected.node_counts.concat = 3;
expected.node_counts.substring = 1;
EXPECT_THAT(SampleCord(concat), EqStatistics(expected));
}
TEST(CordzInfoStatisticsTest, Ring) {
RefHelper ref;
......@@ -539,19 +455,15 @@ TEST(CordzInfoStatisticsTest, BtreeNodeShared) {
TEST(CordzInfoStatisticsTest, Crc) {
RefHelper ref;
auto* left = Flat(1000);
auto* right = Flat(1000);
auto* concat = Concat(left, right);
auto* crc = ref.NeedsUnref(CordRepCrc::New(concat, 12345));
auto* crc = ref.NeedsUnref(CordRepCrc::New(left, 12345));
CordzStatistics expected;
expected.size = concat->length;
expected.estimated_memory_usage =
SizeOf(crc) + SizeOf(concat) + SizeOf(left) + SizeOf(right);
expected.size = left->length;
expected.estimated_memory_usage = SizeOf(crc) + SizeOf(left);
expected.estimated_fair_share_memory_usage = expected.estimated_memory_usage;
expected.node_count = 4;
expected.node_counts.flat = 2;
expected.node_counts.flat_1k = 2;
expected.node_counts.concat = 1;
expected.node_count = 2;
expected.node_counts.flat = 1;
expected.node_counts.flat_1k = 1;
expected.node_counts.crc = 1;
EXPECT_THAT(SampleCord(crc), EqStatistics(expected));
......
......@@ -120,7 +120,7 @@ using EnableIfFloat =
// Duration
//
// The `absl::Duration` class represents a signed, fixed-length span of time.
// The `absl::Duration` class represents a signed, fixed-length amount of time.
// A `Duration` is generated using a unit-specific factory function, or is
// the result of subtracting one `absl::Time` from another. Durations behave
// like unit-safe integers and they support all the natural integer-like
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment