20 #include "absl/base/attributes.h"
21 #include "absl/base/config.h"
22 #include "absl/container/inlined_vector.h"
24 #include "absl/strings/internal/cord_internal.h"
27 #include "absl/strings/internal/cord_rep_flat.h"
28 #include "absl/strings/internal/cord_rep_ring.h"
30 #include "absl/base/macros.h"
31 #include "absl/base/port.h"
32 #include "absl/functional/function_ref.h"
36 namespace cord_internal {
47 explicit CordRepRef(
const CordRep*
r) :
rep(
r) {}
51 CordRepRef Child(
const CordRep*
child)
const {
return CordRepRef(
child); }
66 template <
typename refcount_t>
67 double MaybeDiv(
double d, refcount_t
refcount) {
80 explicit CordRepRef(
const CordRep*
r,
double frac = 1.0)
84 CordRepRef Child(
const CordRep*
child)
const {
85 return CordRepRef(
child, fraction);
98 void Add(
size_t size, CordRepRef<Mode::kFairShare>
rep) {
106 void AnalyzeDataEdge(CordRepRef<mode>
rep, RawUsage<mode>& raw_usage) {
111 raw_usage.Add(
sizeof(CordRepSubstring),
rep);
119 :
rep.rep->
length +
sizeof(CordRepExternalImpl<intptr_t>);
125 void AnalyzeRing(CordRepRef<mode>
rep, RawUsage<mode>& raw_usage) {
126 const CordRepRing* ring =
rep.rep->
ring();
129 AnalyzeDataEdge(
rep.Child(ring->entry_child(
pos)), raw_usage);
135 void AnalyzeBtree(CordRepRef<mode>
rep, RawUsage<mode>& raw_usage) {
136 raw_usage.Add(
sizeof(CordRepBtree),
rep);
137 const CordRepBtree* tree =
rep.rep->
btree();
138 if (tree->height() > 0) {
139 for (CordRep* edge : tree->Edges()) {
140 AnalyzeBtree(
rep.Child(edge), raw_usage);
143 for (CordRep* edge : tree->Edges()) {
144 AnalyzeDataEdge(
rep.Child(edge), raw_usage);
150 size_t GetEstimatedUsage(
const CordRep*
rep) {
152 RawUsage<mode> raw_usage;
155 CordRepRef<mode> repref(
rep);
158 if (repref.rep->tag ==
CRC) {
159 raw_usage.Add(
sizeof(CordRepCrc), repref);
160 repref = repref.Child(repref.rep->crc()->child);
164 AnalyzeDataEdge(repref, raw_usage);
165 }
else if (repref.rep->tag ==
BTREE) {
166 AnalyzeBtree(repref, raw_usage);
167 }
else if (repref.rep->tag ==
RING) {
168 AnalyzeRing(repref, raw_usage);
173 return static_cast<size_t>(raw_usage.total);
179 return GetEstimatedUsage<Mode::kTotal>(
rep);
183 return GetEstimatedUsage<Mode::kFairShare>(
rep);