-- ed829ac612f090375427c3488827c6e74deb2e3f by Derek Mauro <dmauro@google.com>: Update latest GCC/Clang Linux tests to Bazel 5.0.0 and CMake 3.22.2 PiperOrigin-RevId: 429369775 -- 76952303c4d942288c4e7657ffb5893cec54a132 by Martijn Vels <mvels@google.com>: Optimize Cord::ChunkIterator now that CordRepConcat is removed PiperOrigin-RevId: 429321455 -- dcd0d287793649aba9b98268c5783e449a34749f by Martijn Vels <mvels@google.com>: Add IsDataEdge() and DataEdgeValue() helper functions. This moves repetitive logic accessing data edges into its own header, and more strongly defines the notion of what a data edge is, enforcing the internal invariants. This will also be incorporated in optimized Cord iteration logic once CordRepConcat is totally removed from the Cord code. PiperOrigin-RevId: 429307248 -- 6a0903962155988085bf8656743fda9c4cdcba6c by Abseil Team <absl-team@google.com>: Make it clear that the probability function given for the zipf distribution is unnormalized, i.e., sum(p(x) for x = 0..k) != 100%. Quoting Section 7 of the paper cited in the comments, where this formula comes from (emphasis mine): "We will consider the two parameter generalization as defined in Dagpunar [1988] with the *unnormalized* probability function ..." PiperOrigin-RevId: 429068258 -- 3899ff6d444ba755148bc521a6ee031d9e9d4485 by Abseil Team <absl-team@google.com>: Internal Changes PiperOrigin-RevId: 428644856 -- 319de702d2b537cbb76c4c71277ae89b349b162e by Benjamin Barenblat <bbaren@google.com>: Support symbolization on PA-RISC Null out supervisor bits in PA-RISC addresses before symbolizing, and handle function descriptor tables correctly. Change symbolize_test.cc to use 32-bit aligned addresses, allowing that test to pass on PA-RISC. PiperOrigin-RevId: 428590564 GitOrigin-RevId: ed829ac612f090375427c3488827c6e74deb2e3f Change-Id: Ie01ff3b9365fd45e5a55f858038552679f3180d3pull/1110/head
parent
c2ef703338
commit
7f850b3167
19 changed files with 427 additions and 263 deletions
@ -0,0 +1,63 @@ |
||||
// Copyright 2022 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_DATA_EDGE_H_ |
||||
#define ABSL_STRINGS_INTERNAL_CORD_DATA_EDGE_H_ |
||||
|
||||
#include <cassert> |
||||
#include <cstddef> |
||||
|
||||
#include "absl/base/config.h" |
||||
#include "absl/strings/internal/cord_internal.h" |
||||
#include "absl/strings/internal/cord_rep_flat.h" |
||||
#include "absl/strings/string_view.h" |
||||
|
||||
namespace absl { |
||||
ABSL_NAMESPACE_BEGIN |
||||
namespace cord_internal { |
||||
|
||||
// Returns true if the provided rep is a FLAT, EXTERNAL or a SUBSTRING node
|
||||
// holding a FLAT or EXTERNAL child rep. Requires `rep != nullptr`.
|
||||
inline bool IsDataEdge(const CordRep* edge) { |
||||
assert(edge != nullptr); |
||||
|
||||
// The fast path is that `edge` is an EXTERNAL or FLAT node, making the below
|
||||
// if a single, well predicted branch. We then repeat the FLAT or EXTERNAL
|
||||
// check in the slow path of the SUBSTRING check to optimize for the hot path.
|
||||
if (edge->tag == EXTERNAL || edge->tag >= FLAT) return true; |
||||
if (edge->tag == SUBSTRING) edge = edge->substring()->child; |
||||
return edge->tag == EXTERNAL || edge->tag >= FLAT; |
||||
} |
||||
|
||||
// Returns the `absl::string_view` data reference for the provided data edge.
|
||||
// Requires 'IsDataEdge(edge) == true`.
|
||||
inline absl::string_view EdgeData(const CordRep* edge) { |
||||
assert(IsDataEdge(edge)); |
||||
|
||||
size_t offset = 0; |
||||
const size_t length = edge->length; |
||||
if (edge->IsSubstring()) { |
||||
offset = edge->substring()->start; |
||||
edge = edge->substring()->child; |
||||
} |
||||
return edge->tag >= FLAT |
||||
? absl::string_view{edge->flat()->Data() + offset, length} |
||||
: absl::string_view{edge->external()->base + offset, length}; |
||||
} |
||||
|
||||
} // namespace cord_internal
|
||||
ABSL_NAMESPACE_END |
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_STRINGS_INTERNAL_CORD_DATA_EDGE_H_
|
@ -0,0 +1,130 @@ |
||||
// Copyright 2022 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_data_edge.h" |
||||
|
||||
#include "gmock/gmock.h" |
||||
#include "gtest/gtest.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::MakeExternal; |
||||
using ::absl::cordrep_testing::MakeFlat; |
||||
using ::absl::cordrep_testing::MakeSubstring; |
||||
|
||||
TEST(CordDataEdgeTest, IsDataEdgeOnFlat) { |
||||
CordRep* rep = MakeFlat("Lorem ipsum dolor sit amet, consectetur ..."); |
||||
EXPECT_TRUE(IsDataEdge(rep)); |
||||
CordRep::Unref(rep); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, IsDataEdgeOnExternal) { |
||||
CordRep* rep = MakeExternal("Lorem ipsum dolor sit amet, consectetur ..."); |
||||
EXPECT_TRUE(IsDataEdge(rep)); |
||||
CordRep::Unref(rep); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, IsDataEdgeOnSubstringOfFlat) { |
||||
CordRep* rep = MakeFlat("Lorem ipsum dolor sit amet, consectetur ..."); |
||||
CordRep* substr = MakeSubstring(1, 20, rep); |
||||
EXPECT_TRUE(IsDataEdge(substr)); |
||||
CordRep::Unref(substr); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, IsDataEdgeOnSubstringOfExternal) { |
||||
CordRep* rep = MakeExternal("Lorem ipsum dolor sit amet, consectetur ..."); |
||||
CordRep* substr = MakeSubstring(1, 20, rep); |
||||
EXPECT_TRUE(IsDataEdge(substr)); |
||||
CordRep::Unref(substr); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, IsDataEdgeOnBtree) { |
||||
CordRep* rep = MakeFlat("Lorem ipsum dolor sit amet, consectetur ..."); |
||||
CordRepBtree* tree = CordRepBtree::New(rep); |
||||
EXPECT_FALSE(IsDataEdge(tree)); |
||||
CordRep::Unref(tree); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, IsDataEdgeOnBadSubstr) { |
||||
CordRep* rep = MakeFlat("Lorem ipsum dolor sit amet, consectetur ..."); |
||||
CordRep* substr = MakeSubstring(1, 18, MakeSubstring(1, 20, rep)); |
||||
EXPECT_FALSE(IsDataEdge(substr)); |
||||
CordRep::Unref(substr); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, EdgeDataOnFlat) { |
||||
absl::string_view value = "Lorem ipsum dolor sit amet, consectetur ..."; |
||||
CordRep* rep = MakeFlat(value); |
||||
EXPECT_EQ(EdgeData(rep), value); |
||||
CordRep::Unref(rep); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, EdgeDataOnExternal) { |
||||
absl::string_view value = "Lorem ipsum dolor sit amet, consectetur ..."; |
||||
CordRep* rep = MakeExternal(value); |
||||
EXPECT_EQ(EdgeData(rep), value); |
||||
CordRep::Unref(rep); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, EdgeDataOnSubstringOfFlat) { |
||||
absl::string_view value = "Lorem ipsum dolor sit amet, consectetur ..."; |
||||
CordRep* rep = MakeFlat(value); |
||||
CordRep* substr = MakeSubstring(1, 20, rep); |
||||
EXPECT_EQ(EdgeData(substr), value.substr(1, 20)); |
||||
CordRep::Unref(substr); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, EdgeDataOnSubstringOfExternal) { |
||||
absl::string_view value = "Lorem ipsum dolor sit amet, consectetur ..."; |
||||
CordRep* rep = MakeExternal(value); |
||||
CordRep* substr = MakeSubstring(1, 20, rep); |
||||
EXPECT_EQ(EdgeData(substr), value.substr(1, 20)); |
||||
CordRep::Unref(substr); |
||||
} |
||||
|
||||
#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) |
||||
|
||||
TEST(CordDataEdgeTest, IsDataEdgeOnNullPtr) { |
||||
EXPECT_DEATH(IsDataEdge(nullptr), ".*"); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, EdgeDataOnNullPtr) { |
||||
EXPECT_DEATH(EdgeData(nullptr), ".*"); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, EdgeDataOnBtree) { |
||||
CordRep* rep = MakeFlat("Lorem ipsum dolor sit amet, consectetur ..."); |
||||
CordRepBtree* tree = CordRepBtree::New(rep); |
||||
EXPECT_DEATH(EdgeData(tree), ".*"); |
||||
CordRep::Unref(tree); |
||||
} |
||||
|
||||
TEST(CordDataEdgeTest, EdgeDataOnBadSubstr) { |
||||
CordRep* rep = MakeFlat("Lorem ipsum dolor sit amet, consectetur ..."); |
||||
CordRep* substr = MakeSubstring(1, 18, MakeSubstring(1, 20, rep)); |
||||
EXPECT_DEATH(EdgeData(substr), ".*"); |
||||
CordRep::Unref(substr); |
||||
} |
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST && !NDEBUG
|
||||
|
||||
} // namespace
|
||||
} // namespace cord_internal
|
||||
ABSL_NAMESPACE_END |
||||
} // namespace absl
|
Loading…
Reference in new issue