Commit efb035a5 by Martijn Vels Committed by Copybara-Service

Remove CordRepRing experiment.

We have no intention to use it instead of the CordRepBtree implementation, so cleanup up and remove all code and references.

PiperOrigin-RevId: 563803813
Change-Id: I95a67318d0f722f3eb7ecdcc7b6c87e28f2e26dd
parent 09d29c58
...@@ -288,9 +288,6 @@ set(ABSL_INTERNAL_DLL_FILES ...@@ -288,9 +288,6 @@ set(ABSL_INTERNAL_DLL_FILES
"strings/internal/cord_rep_consume.h" "strings/internal/cord_rep_consume.h"
"strings/internal/cord_rep_consume.cc" "strings/internal/cord_rep_consume.cc"
"strings/internal/cord_rep_flat.h" "strings/internal/cord_rep_flat.h"
"strings/internal/cord_rep_ring.cc"
"strings/internal/cord_rep_ring.h"
"strings/internal/cord_rep_ring_reader.h"
"strings/internal/cordz_functions.cc" "strings/internal/cordz_functions.cc"
"strings/internal/cordz_functions.h" "strings/internal/cordz_functions.h"
"strings/internal/cordz_handle.cc" "strings/internal/cordz_handle.cc"
......
...@@ -360,7 +360,6 @@ cc_library( ...@@ -360,7 +360,6 @@ cc_library(
"internal/cord_rep_btree_reader.cc", "internal/cord_rep_btree_reader.cc",
"internal/cord_rep_consume.cc", "internal/cord_rep_consume.cc",
"internal/cord_rep_crc.cc", "internal/cord_rep_crc.cc",
"internal/cord_rep_ring.cc",
], ],
hdrs = [ hdrs = [
"internal/cord_data_edge.h", "internal/cord_data_edge.h",
...@@ -371,8 +370,6 @@ cc_library( ...@@ -371,8 +370,6 @@ cc_library(
"internal/cord_rep_consume.h", "internal/cord_rep_consume.h",
"internal/cord_rep_crc.h", "internal/cord_rep_crc.h",
"internal/cord_rep_flat.h", "internal/cord_rep_flat.h",
"internal/cord_rep_ring.h",
"internal/cord_rep_ring_reader.h",
], ],
copts = ABSL_DEFAULT_COPTS, copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
...@@ -889,41 +886,6 @@ cc_test( ...@@ -889,41 +886,6 @@ cc_test(
) )
cc_test( cc_test(
name = "cord_ring_test",
size = "medium",
srcs = ["cord_ring_test.cc"],
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
":cord_internal",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"//absl/debugging:leak_check",
"//absl/types:span",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "cord_ring_reader_test",
size = "medium",
srcs = ["cord_ring_reader_test.cc"],
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
":cord_internal",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/debugging:leak_check",
"//absl/types:span",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "substitute_test", name = "substitute_test",
size = "small", size = "small",
srcs = ["substitute_test.cc"], srcs = ["substitute_test.cc"],
......
...@@ -637,8 +637,6 @@ absl_cc_library( ...@@ -637,8 +637,6 @@ absl_cc_library(
"internal/cord_rep_crc.h" "internal/cord_rep_crc.h"
"internal/cord_rep_consume.h" "internal/cord_rep_consume.h"
"internal/cord_rep_flat.h" "internal/cord_rep_flat.h"
"internal/cord_rep_ring.h"
"internal/cord_rep_ring_reader.h"
SRCS SRCS
"internal/cord_internal.cc" "internal/cord_internal.cc"
"internal/cord_rep_btree.cc" "internal/cord_rep_btree.cc"
...@@ -646,7 +644,6 @@ absl_cc_library( ...@@ -646,7 +644,6 @@ absl_cc_library(
"internal/cord_rep_btree_reader.cc" "internal/cord_rep_btree_reader.cc"
"internal/cord_rep_crc.cc" "internal/cord_rep_crc.cc"
"internal/cord_rep_consume.cc" "internal/cord_rep_consume.cc"
"internal/cord_rep_ring.cc"
COPTS COPTS
${ABSL_DEFAULT_COPTS} ${ABSL_DEFAULT_COPTS}
DEPS DEPS
...@@ -1117,41 +1114,6 @@ absl_cc_test( ...@@ -1117,41 +1114,6 @@ absl_cc_test(
absl_cc_test( absl_cc_test(
NAME NAME
cord_ring_test
SRCS
"cord_ring_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::config
absl::cord_internal
absl::core_headers
absl::raw_logging_internal
absl::span
absl::strings
GTest::gmock_main
)
absl_cc_test(
NAME
cord_ring_reader_test
SRCS
"cord_ring_reader_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::base
absl::config
absl::cord_internal
absl::core_headers
absl::span
absl::strings
GTest::gmock_main
)
absl_cc_test(
NAME
cordz_test cordz_test
SRCS SRCS
"cordz_test.cc" "cordz_test.cc"
......
...@@ -86,7 +86,6 @@ ...@@ -86,7 +86,6 @@
#include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_btree_reader.h" #include "absl/strings/internal/cord_rep_btree_reader.h"
#include "absl/strings/internal/cord_rep_crc.h" #include "absl/strings/internal/cord_rep_crc.h"
#include "absl/strings/internal/cord_rep_ring.h"
#include "absl/strings/internal/cordz_functions.h" #include "absl/strings/internal/cordz_functions.h"
#include "absl/strings/internal/cordz_info.h" #include "absl/strings/internal/cordz_info.h"
#include "absl/strings/internal/cordz_statistics.h" #include "absl/strings/internal/cordz_statistics.h"
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "absl/strings/internal/cord_internal.h" #include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_crc.h" #include "absl/strings/internal/cord_rep_crc.h"
#include "absl/strings/internal/cord_rep_ring.h"
namespace absl { namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
...@@ -131,16 +130,6 @@ void AnalyzeDataEdge(CordRepRef<mode> rep, RawUsage<mode>& raw_usage) { ...@@ -131,16 +130,6 @@ void AnalyzeDataEdge(CordRepRef<mode> rep, RawUsage<mode>& raw_usage) {
raw_usage.Add(size, rep); raw_usage.Add(size, rep);
} }
// Computes the memory size of the provided Ring tree.
template <Mode mode>
void AnalyzeRing(CordRepRef<mode> rep, RawUsage<mode>& raw_usage) {
const CordRepRing* ring = rep.rep->ring();
raw_usage.Add(CordRepRing::AllocSize(ring->capacity()), rep);
ring->ForEach([&](CordRepRing::index_type pos) {
AnalyzeDataEdge(rep.Child(ring->entry_child(pos)), raw_usage);
});
}
// Computes the memory size of the provided Btree tree. // Computes the memory size of the provided Btree tree.
template <Mode mode> template <Mode mode>
void AnalyzeBtree(CordRepRef<mode> rep, RawUsage<mode>& raw_usage) { void AnalyzeBtree(CordRepRef<mode> rep, RawUsage<mode>& raw_usage) {
...@@ -175,8 +164,6 @@ size_t GetEstimatedUsage(const CordRep* rep) { ...@@ -175,8 +164,6 @@ size_t GetEstimatedUsage(const CordRep* rep) {
AnalyzeDataEdge(repref, raw_usage); AnalyzeDataEdge(repref, raw_usage);
} else if (repref.rep->tag == BTREE) { } else if (repref.rep->tag == BTREE) {
AnalyzeBtree(repref, raw_usage); AnalyzeBtree(repref, raw_usage);
} else if (repref.rep->tag == RING) {
AnalyzeRing(repref, raw_usage);
} else { } else {
assert(false); assert(false);
} }
......
// 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 <array>
#include <cstdlib>
#include <cstring>
#include <ctime>
#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_ring.h"
#include "absl/strings/internal/cord_rep_ring_reader.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {
namespace {
using testing::Eq;
// Creates a flat for testing
CordRep* MakeFlat(absl::string_view s) {
CordRepFlat* flat = CordRepFlat::New(s.length());
memcpy(flat->Data(), s.data(), s.length());
flat->length = s.length();
return flat;
}
CordRepRing* FromFlats(Span<absl::string_view const> flats) {
CordRepRing* ring = CordRepRing::Create(MakeFlat(flats[0]), flats.size() - 1);
for (int i = 1; i < flats.size(); ++i) {
ring = CordRepRing::Append(ring, MakeFlat(flats[i]));
}
return ring;
}
std::array<absl::string_view, 12> TestFlats() {
return {"abcdefghij", "klmnopqrst", "uvwxyz", "ABCDEFGHIJ",
"KLMNOPQRST", "UVWXYZ", "1234567890", "~!@#$%^&*()_",
"+-=", "[]\\{}|;':", ",/<>?", "."};
}
TEST(CordRingReaderTest, DefaultInstance) {
CordRepRingReader reader;
EXPECT_FALSE(static_cast<bool>(reader));
EXPECT_THAT(reader.ring(), Eq(nullptr));
#ifndef NDEBUG
EXPECT_DEATH_IF_SUPPORTED(reader.length(), ".*");
EXPECT_DEATH_IF_SUPPORTED(reader.consumed(), ".*");
EXPECT_DEATH_IF_SUPPORTED(reader.remaining(), ".*");
EXPECT_DEATH_IF_SUPPORTED(reader.Next(), ".*");
EXPECT_DEATH_IF_SUPPORTED(reader.Seek(0), ".*");
#endif
}
TEST(CordRingReaderTest, Reset) {
CordRepRingReader reader;
auto flats = TestFlats();
CordRepRing* ring = FromFlats(flats);
absl::string_view first = reader.Reset(ring);
EXPECT_THAT(first, Eq(flats[0]));
EXPECT_TRUE(static_cast<bool>(reader));
EXPECT_THAT(reader.ring(), Eq(ring));
EXPECT_THAT(reader.index(), Eq(ring->head()));
EXPECT_THAT(reader.node(), Eq(ring->entry_child(ring->head())));
EXPECT_THAT(reader.length(), Eq(ring->length));
EXPECT_THAT(reader.consumed(), Eq(flats[0].length()));
EXPECT_THAT(reader.remaining(), Eq(ring->length - reader.consumed()));
reader.Reset();
EXPECT_FALSE(static_cast<bool>(reader));
EXPECT_THAT(reader.ring(), Eq(nullptr));
CordRep::Unref(ring);
}
TEST(CordRingReaderTest, Next) {
CordRepRingReader reader;
auto flats = TestFlats();
CordRepRing* ring = FromFlats(flats);
CordRepRing::index_type head = ring->head();
reader.Reset(ring);
size_t consumed = reader.consumed();
size_t remaining = reader.remaining();
for (int i = 1; i < flats.size(); ++i) {
CordRepRing::index_type index = ring->advance(head, i);
consumed += flats[i].length();
remaining -= flats[i].length();
absl::string_view next = reader.Next();
ASSERT_THAT(next, Eq(flats[i]));
ASSERT_THAT(reader.index(), Eq(index));
ASSERT_THAT(reader.node(), Eq(ring->entry_child(index)));
ASSERT_THAT(reader.consumed(), Eq(consumed));
ASSERT_THAT(reader.remaining(), Eq(remaining));
}
#ifndef NDEBUG
EXPECT_DEATH_IF_SUPPORTED(reader.Next(), ".*");
#endif
CordRep::Unref(ring);
}
TEST(CordRingReaderTest, SeekForward) {
CordRepRingReader reader;
auto flats = TestFlats();
CordRepRing* ring = FromFlats(flats);
CordRepRing::index_type head = ring->head();
reader.Reset(ring);
size_t consumed = 0;
size_t remaining = ring->length;
for (int i = 0; i < flats.size(); ++i) {
CordRepRing::index_type index = ring->advance(head, i);
size_t offset = consumed;
consumed += flats[i].length();
remaining -= flats[i].length();
for (int off = 0; off < flats[i].length(); ++off) {
absl::string_view chunk = reader.Seek(offset + off);
ASSERT_THAT(chunk, Eq(flats[i].substr(off)));
ASSERT_THAT(reader.index(), Eq(index));
ASSERT_THAT(reader.node(), Eq(ring->entry_child(index)));
ASSERT_THAT(reader.consumed(), Eq(consumed));
ASSERT_THAT(reader.remaining(), Eq(remaining));
}
}
CordRep::Unref(ring);
}
TEST(CordRingReaderTest, SeekBackward) {
CordRepRingReader reader;
auto flats = TestFlats();
CordRepRing* ring = FromFlats(flats);
CordRepRing::index_type head = ring->head();
reader.Reset(ring);
size_t consumed = ring->length;
size_t remaining = 0;
for (int i = flats.size() - 1; i >= 0; --i) {
CordRepRing::index_type index = ring->advance(head, i);
size_t offset = consumed - flats[i].length();
for (int off = 0; off < flats[i].length(); ++off) {
absl::string_view chunk = reader.Seek(offset + off);
ASSERT_THAT(chunk, Eq(flats[i].substr(off)));
ASSERT_THAT(reader.index(), Eq(index));
ASSERT_THAT(reader.node(), Eq(ring->entry_child(index)));
ASSERT_THAT(reader.consumed(), Eq(consumed));
ASSERT_THAT(reader.remaining(), Eq(remaining));
}
consumed -= flats[i].length();
remaining += flats[i].length();
}
#ifndef NDEBUG
EXPECT_DEATH_IF_SUPPORTED(reader.Seek(ring->length), ".*");
#endif
CordRep::Unref(ring);
}
} // namespace
} // namespace cord_internal
ABSL_NAMESPACE_END
} // namespace absl
...@@ -2110,8 +2110,6 @@ TEST_P(CordTest, DiabolicalGrowth) { ...@@ -2110,8 +2110,6 @@ TEST_P(CordTest, DiabolicalGrowth) {
// This test exercises a diabolical Append(<one char>) on a cord, making the // This test exercises a diabolical Append(<one char>) on a cord, making the
// cord shared before each Append call resulting in a terribly fragmented // cord shared before each Append call resulting in a terribly fragmented
// resulting cord. // 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)); RandomEngine rng(GTEST_FLAG_GET(random_seed));
const std::string expected = RandomLowercaseString(&rng, 5000); const std::string expected = RandomLowercaseString(&rng, 5000);
absl::Cord cord; absl::Cord cord;
......
...@@ -22,15 +22,12 @@ ...@@ -22,15 +22,12 @@
#include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_crc.h" #include "absl/strings/internal/cord_rep_crc.h"
#include "absl/strings/internal/cord_rep_flat.h" #include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/internal/cord_rep_ring.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
namespace absl { namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
namespace cord_internal { namespace cord_internal {
ABSL_CONST_INIT std::atomic<bool> cord_ring_buffer_enabled(
kCordEnableRingBufferDefault);
ABSL_CONST_INIT std::atomic<bool> shallow_subcords_enabled( ABSL_CONST_INIT std::atomic<bool> shallow_subcords_enabled(
kCordShallowSubcordsDefault); kCordShallowSubcordsDefault);
...@@ -47,9 +44,6 @@ void CordRep::Destroy(CordRep* rep) { ...@@ -47,9 +44,6 @@ void CordRep::Destroy(CordRep* rep) {
if (rep->tag == BTREE) { if (rep->tag == BTREE) {
CordRepBtree::Destroy(rep->btree()); CordRepBtree::Destroy(rep->btree());
return; return;
} else if (rep->tag == RING) {
CordRepRing::Destroy(rep->ring());
return;
} else if (rep->tag == EXTERNAL) { } else if (rep->tag == EXTERNAL) {
CordRepExternal::Delete(rep); CordRepExternal::Delete(rep);
return; return;
......
...@@ -55,24 +55,15 @@ struct CordRepExternal; ...@@ -55,24 +55,15 @@ struct CordRepExternal;
struct CordRepFlat; struct CordRepFlat;
struct CordRepSubstring; struct CordRepSubstring;
struct CordRepCrc; struct CordRepCrc;
class CordRepRing;
class CordRepBtree; class CordRepBtree;
class CordzInfo; class CordzInfo;
// Default feature enable states for cord ring buffers // Default feature enable states for cord ring buffers
enum CordFeatureDefaults { enum CordFeatureDefaults { kCordShallowSubcordsDefault = false };
kCordEnableRingBufferDefault = false,
kCordShallowSubcordsDefault = false
};
extern std::atomic<bool> cord_ring_buffer_enabled;
extern std::atomic<bool> shallow_subcords_enabled; extern std::atomic<bool> shallow_subcords_enabled;
inline void enable_cord_ring_buffer(bool enable) {
cord_ring_buffer_enabled.store(enable, std::memory_order_relaxed);
}
inline void enable_shallow_subcords(bool enable) { inline void enable_shallow_subcords(bool enable) {
shallow_subcords_enabled.store(enable, std::memory_order_relaxed); shallow_subcords_enabled.store(enable, std::memory_order_relaxed);
} }
...@@ -215,7 +206,7 @@ enum CordRepKind { ...@@ -215,7 +206,7 @@ enum CordRepKind {
SUBSTRING = 1, SUBSTRING = 1,
CRC = 2, CRC = 2,
BTREE = 3, BTREE = 3,
RING = 4, UNUSED_4 = 4,
EXTERNAL = 5, EXTERNAL = 5,
// We have different tags for different sized flat arrays, // We have different tags for different sized flat arrays,
...@@ -234,12 +225,8 @@ enum CordRepKind { ...@@ -234,12 +225,8 @@ enum CordRepKind {
// There are various locations where we want to check if some rep is a 'plain' // There are various locations where we want to check if some rep is a 'plain'
// data edge, i.e. an external or flat rep. By having FLAT == EXTERNAL + 1, we // data edge, i.e. an external or flat rep. By having FLAT == EXTERNAL + 1, we
// can perform this check in a single branch as 'tag >= EXTERNAL' // can perform this check in a single branch as 'tag >= EXTERNAL'
// Likewise, we have some locations where we check for 'ring or external/flat',
// so likewise align RING to EXTERNAL.
// Note that we can leave this optimization to the compiler. The compiler will // Note that we can leave this optimization to the compiler. The compiler will
// DTRT when it sees a condition like `tag == EXTERNAL || tag >= FLAT`. // DTRT when it sees a condition like `tag == EXTERNAL || tag >= FLAT`.
static_assert(RING == BTREE + 1, "BTREE and RING not consecutive");
static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive");
static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive"); static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive");
struct CordRep { struct CordRep {
...@@ -283,15 +270,12 @@ struct CordRep { ...@@ -283,15 +270,12 @@ struct CordRep {
// # LINT.ThenChange(cord_rep_btree.h:copy_raw) // # LINT.ThenChange(cord_rep_btree.h:copy_raw)
// Returns true if this instance's tag matches the requested type. // Returns true if this instance's tag matches the requested type.
constexpr bool IsRing() const { return tag == RING; }
constexpr bool IsSubstring() const { return tag == SUBSTRING; } constexpr bool IsSubstring() const { return tag == SUBSTRING; }
constexpr bool IsCrc() const { return tag == CRC; } constexpr bool IsCrc() const { return tag == CRC; }
constexpr bool IsExternal() const { return tag == EXTERNAL; } constexpr bool IsExternal() const { return tag == EXTERNAL; }
constexpr bool IsFlat() const { return tag >= FLAT; } constexpr bool IsFlat() const { return tag >= FLAT; }
constexpr bool IsBtree() const { return tag == BTREE; } constexpr bool IsBtree() const { return tag == BTREE; }
inline CordRepRing* ring();
inline const CordRepRing* ring() const;
inline CordRepSubstring* substring(); inline CordRepSubstring* substring();
inline const CordRepSubstring* substring() const; inline const CordRepSubstring* substring() const;
inline CordRepCrc* crc(); inline CordRepCrc* crc();
......
// 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.
#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_RING_READER_H_
#define ABSL_STRINGS_INTERNAL_CORD_REP_RING_READER_H_
#include <cassert>
#include <cstddef>
#include <cstdint>
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_ring.h"
#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {
// CordRepRingReader provides basic navigation over CordRepRing data.
class CordRepRingReader {
public:
// Returns true if this instance is not empty.
explicit operator bool() const { return ring_ != nullptr; }
// Returns the ring buffer reference for this instance, or nullptr if empty.
CordRepRing* ring() const { return ring_; }
// Returns the current node index inside the ring buffer for this instance.
// The returned value is undefined if this instance is empty.
CordRepRing::index_type index() const { return index_; }
// Returns the current node inside the ring buffer for this instance.
// The returned value is undefined if this instance is empty.
CordRep* node() const { return ring_->entry_child(index_); }
// Returns the length of the referenced ring buffer.
// Requires the current instance to be non empty.
size_t length() const {
assert(ring_);
return ring_->length;
}
// Returns the end offset of the last navigated-to chunk, which represents the
// total bytes 'consumed' relative to the start of the ring. The returned
// value is never zero. For example, initializing a reader with a ring buffer
// with a first chunk of 19 bytes will return consumed() = 19.
// Requires the current instance to be non empty.
size_t consumed() const {
assert(ring_);
return ring_->entry_end_offset(index_);
}
// Returns the number of bytes remaining beyond the last navigated-to chunk.
// Requires the current instance to be non empty.
size_t remaining() const {
assert(ring_);
return length() - consumed();
}
// Resets this instance to an empty value
void Reset() { ring_ = nullptr; }
// Resets this instance to the start of `ring`. `ring` must not be null.
// Returns a reference into the first chunk of the provided ring.
absl::string_view Reset(CordRepRing* ring) {
assert(ring);
ring_ = ring;
index_ = ring_->head();
return ring_->entry_data(index_);
}
// Navigates to the next chunk inside the reference ring buffer.
// Returns a reference into the navigated-to chunk.
// Requires remaining() to be non zero.
absl::string_view Next() {
assert(remaining());
index_ = ring_->advance(index_);
return ring_->entry_data(index_);
}
// Navigates to the chunk at offset `offset`.
// Returns a reference into the navigated-to chunk, adjusted for the relative
// position of `offset` into that chunk. For example, calling Seek(13) on a
// ring buffer containing 2 chunks of 10 and 20 bytes respectively will return
// a string view into the second chunk starting at offset 3 with a size of 17.
// Requires `offset` to be less than `length()`
absl::string_view Seek(size_t offset) {
assert(offset < length());
size_t current = ring_->entry_end_offset(index_);
CordRepRing::index_type hint = (offset >= current) ? index_ : ring_->head();
const CordRepRing::Position head = ring_->Find(hint, offset);
index_ = head.index;
auto data = ring_->entry_data(head.index);
data.remove_prefix(head.offset);
return data;
}
private:
CordRepRing* ring_ = nullptr;
CordRepRing::index_type index_;
};
} // namespace cord_internal
ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_STRINGS_INTERNAL_CORD_REP_RING_READER_H_
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "absl/strings/internal/cord_internal.h" #include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_crc.h" #include "absl/strings/internal/cord_rep_crc.h"
#include "absl/strings/internal/cord_rep_ring.h"
#include "absl/strings/internal/cordz_handle.h" #include "absl/strings/internal/cordz_handle.h"
#include "absl/strings/internal/cordz_statistics.h" #include "absl/strings/internal/cordz_statistics.h"
#include "absl/strings/internal/cordz_update_tracker.h" #include "absl/strings/internal/cordz_update_tracker.h"
...@@ -97,14 +96,11 @@ class CordRepAnalyzer { ...@@ -97,14 +96,11 @@ class CordRepAnalyzer {
repref = CountLinearReps(repref, memory_usage_); repref = CountLinearReps(repref, memory_usage_);
switch (repref.tag()) { switch (repref.tag()) {
case CordRepKind::RING:
AnalyzeRing(repref);
break;
case CordRepKind::BTREE: case CordRepKind::BTREE:
AnalyzeBtree(repref); AnalyzeBtree(repref);
break; break;
default: default:
// We should have either a btree or ring node if not null. // We should have a btree node if not null.
ABSL_ASSERT(repref.tag() == CordRepKind::UNUSED_0); ABSL_ASSERT(repref.tag() == CordRepKind::UNUSED_0);
break; break;
} }
...@@ -204,17 +200,6 @@ class CordRepAnalyzer { ...@@ -204,17 +200,6 @@ class CordRepAnalyzer {
return rep; return rep;
} }
// Analyzes the provided ring.
void AnalyzeRing(RepRef rep) {
statistics_.node_count++;
statistics_.node_counts.ring++;
const CordRepRing* ring = rep.rep->ring();
memory_usage_.Add(CordRepRing::AllocSize(ring->capacity()), rep.refcount);
ring->ForEach([&](CordRepRing::index_type pos) {
CountLinearReps(rep.Child(ring->entry_child(pos)), memory_usage_);
});
}
// Analyzes the provided btree. // Analyzes the provided btree.
void AnalyzeBtree(RepRef rep) { void AnalyzeBtree(RepRef rep) {
statistics_.node_count++; statistics_.node_count++;
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_crc.h" #include "absl/strings/internal/cord_rep_crc.h"
#include "absl/strings/internal/cord_rep_flat.h" #include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/internal/cord_rep_ring.h"
#include "absl/strings/internal/cordz_info.h" #include "absl/strings/internal/cordz_info.h"
#include "absl/strings/internal/cordz_sample_token.h" #include "absl/strings/internal/cordz_sample_token.h"
#include "absl/strings/internal/cordz_statistics.h" #include "absl/strings/internal/cordz_statistics.h"
...@@ -123,11 +122,6 @@ size_t SizeOf(const CordRepExternal* rep) { ...@@ -123,11 +122,6 @@ size_t SizeOf(const CordRepExternal* rep) {
return sizeof(CordRepExternalImpl<intptr_t>) + rep->length; return sizeof(CordRepExternalImpl<intptr_t>) + rep->length;
} }
template <>
size_t SizeOf(const CordRepRing* rep) {
return CordRepRing::AllocSize(rep->capacity());
}
// Computes fair share memory used in a naive 'we dare to recurse' way. // Computes fair share memory used in a naive 'we dare to recurse' way.
double FairShareImpl(CordRep* rep, size_t ref) { double FairShareImpl(CordRep* rep, size_t ref) {
double self = 0.0, children = 0.0; double self = 0.0, children = 0.0;
...@@ -144,11 +138,6 @@ double FairShareImpl(CordRep* rep, size_t ref) { ...@@ -144,11 +138,6 @@ double FairShareImpl(CordRep* rep, size_t ref) {
for (CordRep*edge : rep->btree()->Edges()) { for (CordRep*edge : rep->btree()->Edges()) {
children += FairShareImpl(edge, ref); children += FairShareImpl(edge, ref);
} }
} else if (rep->tag == RING) {
self = SizeOf(rep->ring());
rep->ring()->ForEach([&](CordRepRing::index_type i) {
self += FairShareImpl(rep->ring()->entry_child(i), 1);
});
} else { } else {
assert(false); assert(false);
} }
...@@ -294,64 +283,6 @@ TEST(CordzInfoStatisticsTest, SharedSubstring) { ...@@ -294,64 +283,6 @@ TEST(CordzInfoStatisticsTest, SharedSubstring) {
EXPECT_THAT(SampleCord(substring), EqStatistics(expected)); EXPECT_THAT(SampleCord(substring), EqStatistics(expected));
} }
TEST(CordzInfoStatisticsTest, Ring) {
RefHelper ref;
auto* flat1 = Flat(240);
auto* flat2 = Flat(2000);
auto* flat3 = Flat(70);
auto* external = External(3000);
CordRepRing* ring = CordRepRing::Create(flat1);
ring = CordRepRing::Append(ring, flat2);
ring = CordRepRing::Append(ring, flat3);
ring = ref.NeedsUnref(CordRepRing::Append(ring, external));
CordzStatistics expected;
expected.size = ring->length;
expected.estimated_memory_usage = SizeOf(ring) + SizeOf(flat1) +
SizeOf(flat2) + SizeOf(flat3) +
SizeOf(external);
expected.estimated_fair_share_memory_usage = expected.estimated_memory_usage;
expected.node_count = 5;
expected.node_counts.flat = 3;
expected.node_counts.flat_128 = 1;
expected.node_counts.flat_256 = 1;
expected.node_counts.external = 1;
expected.node_counts.ring = 1;
EXPECT_THAT(SampleCord(ring), EqStatistics(expected));
}
TEST(CordzInfoStatisticsTest, SharedSubstringRing) {
RefHelper ref;
auto* flat1 = ref.Ref(Flat(240));
auto* flat2 = Flat(200);
auto* flat3 = Flat(70);
auto* external = ref.Ref(External(3000), 5);
CordRepRing* ring = CordRepRing::Create(flat1);
ring = CordRepRing::Append(ring, flat2);
ring = CordRepRing::Append(ring, flat3);
ring = ref.Ref(CordRepRing::Append(ring, external), 4);
auto* substring = ref.Ref(ref.NeedsUnref(Substring(ring)));
CordzStatistics expected;
expected.size = substring->length;
expected.estimated_memory_usage = SizeOf(ring) + SizeOf(flat1) +
SizeOf(flat2) + SizeOf(flat3) +
SizeOf(external) + SizeOf(substring);
expected.estimated_fair_share_memory_usage = FairShare(substring);
expected.node_count = 6;
expected.node_counts.flat = 3;
expected.node_counts.flat_128 = 1;
expected.node_counts.flat_256 = 2;
expected.node_counts.external = 1;
expected.node_counts.ring = 1;
expected.node_counts.substring = 1;
EXPECT_THAT(SampleCord(substring), EqStatistics(expected));
}
TEST(CordzInfoStatisticsTest, BtreeLeaf) { TEST(CordzInfoStatisticsTest, BtreeLeaf) {
ASSERT_THAT(CordRepBtree::kMaxCapacity, Ge(3u)); ASSERT_THAT(CordRepBtree::kMaxCapacity, Ge(3u));
RefHelper ref; RefHelper ref;
...@@ -528,14 +459,10 @@ TEST(CordzInfoStatisticsTest, ThreadSafety) { ...@@ -528,14 +459,10 @@ TEST(CordzInfoStatisticsTest, ThreadSafety) {
CordRep::Unref(cord.as_tree()); CordRep::Unref(cord.as_tree());
cord.set_inline_size(0); cord.set_inline_size(0);
} else { } else {
// Coin toss to 25% ring, 25% btree, and 50% flat. // Coin toss to 50% btree, and 50% flat.
CordRep* rep = Flat(256); CordRep* rep = Flat(256);
if (coin_toss(gen) != 0) { if (coin_toss(gen) != 0) {
if (coin_toss(gen) != 0) { rep = CordRepBtree::Create(rep);
rep = CordRepRing::Create(rep);
} else {
rep = CordRepBtree::Create(rep);
}
} }
// Maybe CRC this cord // Maybe CRC this cord
......
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