cord_rep_test_util.h
Go to the documentation of this file.
1 // Copyright 2021 The Abseil Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_
16 #define ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_
17 
18 #include <cassert>
19 #include <memory>
20 #include <random>
21 #include <string>
22 #include <vector>
23 
24 #include "absl/base/config.h"
25 #include "absl/base/internal/raw_logging.h"
26 #include "absl/strings/internal/cord_internal.h"
28 #include "absl/strings/internal/cord_rep_flat.h"
29 #include "absl/strings/string_view.h"
30 
31 namespace absl {
33 namespace cordrep_testing {
34 
36  size_t start, size_t len, cord_internal::CordRep* rep) {
37  auto* sub = new cord_internal::CordRepSubstring;
39  sub->start = start;
40  sub->length = len <= 0 ? rep->length - start + len : len;
41  sub->child = rep;
42  return sub;
43 }
44 
46  assert(value.length() <= cord_internal::kMaxFlatLength);
47  auto* flat = cord_internal::CordRepFlat::New(value.length());
48  flat->length = value.length();
49  memcpy(flat->Data(), value.data(), value.length());
50  return flat;
51 }
52 
53 // Creates an external node for testing
55  struct Rep : public cord_internal::CordRepExternal {
56  std::string s;
57  explicit Rep(absl::string_view sv) : s(sv) {
59  this->base = s.data();
60  this->length = s.length();
61  this->releaser_invoker = [](cord_internal::CordRepExternal* self) {
62  delete static_cast<Rep*>(self);
63  };
64  }
65  };
66  return new Rep(s);
67 }
68 
69 inline std::string CreateRandomString(size_t n) {
71  "abcdefghijklmnopqrstuvwxyz"
72  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
73  "0123456789~!@#$%^&*()_+=-<>?:\"{}[]|";
74  std::minstd_rand rnd;
75  std::uniform_int_distribution<size_t> dist(0, data.size() - 1);
76  std::string s(n, ' ');
77  for (size_t i = 0; i < n; ++i) {
78  s[i] = data[dist(rnd)];
79  }
80  return s;
81 }
82 
83 // Creates an array of flats from the provided string, chopping
84 // the provided string up into flats of size `chunk_size` characters
85 // resulting in roughly `data.size() / chunk_size` total flats.
86 inline std::vector<cord_internal::CordRep*> CreateFlatsFromString(
87  absl::string_view data, size_t chunk_size) {
88  assert(chunk_size > 0);
89  std::vector<cord_internal::CordRep*> flats;
90  for (absl::string_view s = data; !s.empty(); s.remove_prefix(chunk_size)) {
91  flats.push_back(MakeFlat(s.substr(0, chunk_size)));
92  }
93  return flats;
94 }
95 
98  assert(!flats.empty());
99  auto* node = cord_internal::CordRepBtree::Create(flats[0]);
100  for (size_t i = 1; i < flats.size(); ++i) {
101  node = cord_internal::CordRepBtree::Append(node, flats[i]);
102  }
103  return node;
104 }
105 
106 template <typename Fn>
108  fn(rep);
109  while (rep->tag == cord_internal::SUBSTRING) {
110  rep = rep->substring()->child;
111  fn(rep);
112  }
113  if (rep->tag == cord_internal::BTREE) {
114  for (cord_internal::CordRep* edge : rep->btree()->Edges()) {
115  CordVisitReps(edge, fn);
116  }
117  }
118 }
119 
120 template <typename Predicate>
121 inline std::vector<cord_internal::CordRep*> CordCollectRepsIf(
122  Predicate&& predicate, cord_internal::CordRep* rep) {
123  std::vector<cord_internal::CordRep*> reps;
124  CordVisitReps(rep, [&reps, &predicate](cord_internal::CordRep* rep) {
125  if (predicate(rep)) reps.push_back(rep);
126  });
127  return reps;
128 }
129 
130 inline std::vector<cord_internal::CordRep*> CordCollectReps(
132  std::vector<cord_internal::CordRep*> reps;
133  auto fn = [&reps](cord_internal::CordRep* rep) { reps.push_back(rep); };
134  CordVisitReps(rep, fn);
135  return reps;
136 }
137 
139  size_t offset = 0;
140  size_t length = rep->length;
141  while (rep->tag == cord_internal::SUBSTRING) {
142  offset += rep->substring()->start;
143  rep = rep->substring()->child;
144  }
145  if (rep->tag == cord_internal::BTREE) {
146  for (cord_internal::CordRep* edge : rep->btree()->Edges()) {
147  CordToString(edge, s);
148  }
149  } else if (rep->tag >= cord_internal::FLAT) {
150  s.append(rep->flat()->Data() + offset, length);
151  } else if (rep->tag == cord_internal::EXTERNAL) {
152  s.append(rep->external()->base + offset, length);
153  } else {
154  ABSL_RAW_LOG(FATAL, "Unsupported tag %d", rep->tag);
155  }
156 }
157 
159  std::string s;
160  s.reserve(rep->length);
161  CordToString(rep, s);
162  return s;
163 }
164 
165 // RAII Helper class to automatically unref reps on destruction.
166 class AutoUnref {
167  public:
170  }
171 
172  // Adds `rep` to the list of reps to be unreffed at destruction.
173  template <typename CordRepType>
174  CordRepType* Add(CordRepType* rep) {
175  unrefs_.push_back(rep);
176  return rep;
177  }
178 
179  // Increments the reference count of `rep` by one, and adds it to
180  // the list of reps to be unreffed at destruction.
181  template <typename CordRepType>
182  CordRepType* Ref(CordRepType* rep) {
183  unrefs_.push_back(CordRep::Ref(rep));
184  return rep;
185  }
186 
187  // Increments the reference count of `rep` by one if `condition` is true,
188  // and adds it to the list of reps to be unreffed at destruction.
189  template <typename CordRepType>
190  CordRepType* RefIf(bool condition, CordRepType* rep) {
191  if (condition) unrefs_.push_back(CordRep::Ref(rep));
192  return rep;
193  }
194 
195  private:
197 
198  std::vector<CordRep*> unrefs_;
199 };
200 
201 } // namespace cordrep_testing
203 } // namespace absl
204 
205 #endif // ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_
absl::cordrep_testing::CreateRandomString
std::string CreateRandomString(size_t n)
Definition: cord_rep_test_util.h:69
absl::cord_internal::EXTERNAL
@ EXTERNAL
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:183
absl::cordrep_testing::CordCollectRepsIf
std::vector< cord_internal::CordRep * > CordCollectRepsIf(Predicate &&predicate, cord_internal::CordRep *rep)
Definition: cord_rep_test_util.h:121
absl::cord_internal::CordRep::Unref
static void Unref(CordRep *rep)
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:642
absl::cord_internal::CordRepFlat::New
static CordRepFlat * New(size_t len)
Definition: abseil-cpp/absl/strings/internal/cord_rep_flat.h:128
absl::Span
Definition: abseil-cpp/absl/types/span.h:152
absl::cordrep_testing::AutoUnref::Ref
CordRepType * Ref(CordRepType *rep)
Definition: cord_rep_test_util.h:182
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::cord_internal::kMaxFlatLength
static constexpr size_t kMaxFlatLength
Definition: abseil-cpp/absl/strings/internal/cord_rep_flat.h:45
absl::FormatConversionChar::s
@ s
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
absl::Span::empty
constexpr bool empty() const noexcept
Definition: abseil-cpp/absl/types/span.h:271
absl::cord_internal::CordRep
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:209
absl::cordrep_testing::MakeFlat
cord_internal::CordRepFlat * MakeFlat(absl::string_view value)
Definition: cord_rep_test_util.h:45
absl::cord_internal::CordRep::tag
uint8_t tag
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:232
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
start
static uint64_t start
Definition: benchmark-pound.c:74
absl::cordrep_testing::CreateFlatsFromString
std::vector< cord_internal::CordRep * > CreateFlatsFromString(absl::string_view data, size_t chunk_size)
Definition: cord_rep_test_util.h:86
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::cordrep_testing::AutoUnref::RefIf
CordRepType * RefIf(bool condition, CordRepType *rep)
Definition: cord_rep_test_util.h:190
absl::cord_internal::CordRepExternal
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:306
generate-asm-lcov.fn
fn
Definition: generate-asm-lcov.py:146
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
absl::cord_internal::FLAT
@ FLAT
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:194
cord_rep_btree.h
absl::cordrep_testing::CordRepBtreeFromFlats
cord_internal::CordRepBtree * CordRepBtreeFromFlats(absl::Span< cord_internal::CordRep *const > flats)
Definition: cord_rep_test_util.h:96
gen_synthetic_protos.base
base
Definition: gen_synthetic_protos.py:31
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
absl::cord_internal::CordRepBtree::Create
static CordRepBtree * Create(CordRep *rep)
Definition: cord_rep_btree.h:831
absl::cordrep_testing::AutoUnref
Definition: cord_rep_test_util.h:166
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
absl::cord_internal::CordRepBtree::Append
static CordRepBtree * Append(CordRepBtree *tree, CordRep *rep)
Definition: cord_rep_btree.h:892
absl::cordrep_testing::CordVisitReps
void CordVisitReps(cord_internal::CordRep *rep, Fn &&fn)
Definition: cord_rep_test_util.h:107
absl::cordrep_testing::MakeSubstring
cord_internal::CordRepSubstring * MakeSubstring(size_t start, size_t len, cord_internal::CordRep *rep)
Definition: cord_rep_test_util.h:35
value
const char * value
Definition: hpack_parser_table.cc:165
absl::cordrep_testing::AutoUnref::Add
CordRepType * Add(CordRepType *rep)
Definition: cord_rep_test_util.h:174
FATAL
#define FATAL(msg)
Definition: task.h:88
absl::cord_internal::BTREE
@ BTREE
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:181
absl::cordrep_testing::AutoUnref::~AutoUnref
~AutoUnref()
Definition: cord_rep_test_util.h:168
absl::cord_internal::CordRepBtree
Definition: cord_rep_btree.h:63
absl::cordrep_testing::CordCollectReps
std::vector< cord_internal::CordRep * > CordCollectReps(cord_internal::CordRep *rep)
Definition: cord_rep_test_util.h:130
absl::Span::size
constexpr size_type size() const noexcept
Definition: abseil-cpp/absl/types/span.h:261
absl::cordrep_testing::MakeExternal
cord_internal::CordRepExternal * MakeExternal(absl::string_view s)
Definition: cord_rep_test_util.h:54
absl::cord_internal::SUBSTRING
@ SUBSTRING
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:179
rep
const CordRep * rep
Definition: cord_analysis.cc:53
absl::cord_internal::CordRep::Ref
static CordRep * Ref(CordRep *rep)
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:634
absl::cordrep_testing::AutoUnref::unrefs_
std::vector< CordRep * > unrefs_
Definition: cord_rep_test_util.h:198
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
absl::cordrep_testing::CordToString
void CordToString(cord_internal::CordRep *rep, std::string &s)
Definition: cord_rep_test_util.h:138
absl::cord_internal::CordRepSubstring
Definition: abseil-cpp/absl/strings/internal/cord_internal.h:280
Fn
void Fn()
ABSL_RAW_LOG
#define ABSL_RAW_LOG(severity,...)
Definition: abseil-cpp/absl/base/internal/raw_logging.h:44
absl::cord_internal::CordRepFlat
Definition: abseil-cpp/absl/strings/internal/cord_rep_flat.h:107
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:56