cord.h 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633
  1. // Copyright 2020 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. // -----------------------------------------------------------------------------
  16. // File: cord.h
  17. // -----------------------------------------------------------------------------
  18. //
  19. // This file defines the `absl::Cord` data structure and operations on that data
  20. // structure. A Cord is a string-like sequence of characters optimized for
  21. // specific use cases. Unlike a `std::string`, which stores an array of
  22. // contiguous characters, Cord data is stored in a structure consisting of
  23. // separate, reference-counted "chunks."
  24. //
  25. // Because a Cord consists of these chunks, data can be added to or removed from
  26. // a Cord during its lifetime. Chunks may also be shared between Cords. Unlike a
  27. // `std::string`, a Cord can therefore accommodate data that changes over its
  28. // lifetime, though it's not quite "mutable"; it can change only in the
  29. // attachment, detachment, or rearrangement of chunks of its constituent data.
  30. //
  31. // A Cord provides some benefit over `std::string` under the following (albeit
  32. // narrow) circumstances:
  33. //
  34. // * Cord data is designed to grow and shrink over a Cord's lifetime. Cord
  35. // provides efficient insertions and deletions at the start and end of the
  36. // character sequences, avoiding copies in those cases. Static data should
  37. // generally be stored as strings.
  38. // * External memory consisting of string-like data can be directly added to
  39. // a Cord without requiring copies or allocations.
  40. // * Cord data may be shared and copied cheaply. Cord provides a copy-on-write
  41. // implementation and cheap sub-Cord operations. Copying a Cord is an O(1)
  42. // operation.
  43. //
  44. // As a consequence to the above, Cord data is generally large. Small data
  45. // should generally use strings, as construction of a Cord requires some
  46. // overhead. Small Cords (<= 15 bytes) are represented inline, but most small
  47. // Cords are expected to grow over their lifetimes.
  48. //
  49. // Note that because a Cord is made up of separate chunked data, random access
  50. // to character data within a Cord is slower than within a `std::string`.
  51. //
  52. // Thread Safety
  53. //
  54. // Cord has the same thread-safety properties as many other types like
  55. // std::string, std::vector<>, int, etc -- it is thread-compatible. In
  56. // particular, if threads do not call non-const methods, then it is safe to call
  57. // const methods without synchronization. Copying a Cord produces a new instance
  58. // that can be used concurrently with the original in arbitrary ways.
  59. #ifndef ABSL_STRINGS_CORD_H_
  60. #define ABSL_STRINGS_CORD_H_
  61. #include <algorithm>
  62. #include <cstddef>
  63. #include <cstdint>
  64. #include <cstring>
  65. #include <iosfwd>
  66. #include <iterator>
  67. #include <string>
  68. #include <type_traits>
  69. #include "absl/base/attributes.h"
  70. #include "absl/base/config.h"
  71. #include "absl/base/internal/endian.h"
  72. #include "absl/base/internal/per_thread_tls.h"
  73. #include "absl/base/macros.h"
  74. #include "absl/base/port.h"
  75. #include "absl/container/inlined_vector.h"
  76. #include "absl/crc/internal/crc_cord_state.h"
  77. #include "absl/functional/function_ref.h"
  78. #include "absl/meta/type_traits.h"
  79. #include "absl/strings/cord_analysis.h"
  80. #include "absl/strings/cord_buffer.h"
  81. #include "absl/strings/internal/cord_data_edge.h"
  82. #include "absl/strings/internal/cord_internal.h"
  83. #include "absl/strings/internal/cord_rep_btree.h"
  84. #include "absl/strings/internal/cord_rep_btree_reader.h"
  85. #include "absl/strings/internal/cord_rep_crc.h"
  86. #include "absl/strings/internal/cord_rep_ring.h"
  87. #include "absl/strings/internal/cordz_functions.h"
  88. #include "absl/strings/internal/cordz_info.h"
  89. #include "absl/strings/internal/cordz_statistics.h"
  90. #include "absl/strings/internal/cordz_update_scope.h"
  91. #include "absl/strings/internal/cordz_update_tracker.h"
  92. #include "absl/strings/internal/resize_uninitialized.h"
  93. #include "absl/strings/internal/string_constant.h"
  94. #include "absl/strings/string_view.h"
  95. #include "absl/types/optional.h"
  96. namespace absl {
  97. ABSL_NAMESPACE_BEGIN
  98. class Cord;
  99. class CordTestPeer;
  100. template <typename Releaser>
  101. Cord MakeCordFromExternal(absl::string_view, Releaser&&);
  102. void CopyCordToString(const Cord& src, std::string* dst);
  103. // Cord memory accounting modes
  104. enum class CordMemoryAccounting {
  105. // Counts the *approximate* number of bytes held in full or in part by this
  106. // Cord (which may not remain the same between invocations). Cords that share
  107. // memory could each be "charged" independently for the same shared memory.
  108. kTotal,
  109. // Counts the *approximate* number of bytes held in full or in part by this
  110. // Cord weighted by the sharing ratio of that data. For example, if some data
  111. // edge is shared by 4 different Cords, then each cord is attributed 1/4th of
  112. // the total memory usage as a 'fair share' of the total memory usage.
  113. kFairShare,
  114. };
  115. // Cord
  116. //
  117. // A Cord is a sequence of characters, designed to be more efficient than a
  118. // `std::string` in certain circumstances: namely, large string data that needs
  119. // to change over its lifetime or shared, especially when such data is shared
  120. // across API boundaries.
  121. //
  122. // A Cord stores its character data in a structure that allows efficient prepend
  123. // and append operations. This makes a Cord useful for large string data sent
  124. // over in a wire format that may need to be prepended or appended at some point
  125. // during the data exchange (e.g. HTTP, protocol buffers). For example, a
  126. // Cord is useful for storing an HTTP request, and prepending an HTTP header to
  127. // such a request.
  128. //
  129. // Cords should not be used for storing general string data, however. They
  130. // require overhead to construct and are slower than strings for random access.
  131. //
  132. // The Cord API provides the following common API operations:
  133. //
  134. // * Create or assign Cords out of existing string data, memory, or other Cords
  135. // * Append and prepend data to an existing Cord
  136. // * Create new Sub-Cords from existing Cord data
  137. // * Swap Cord data and compare Cord equality
  138. // * Write out Cord data by constructing a `std::string`
  139. //
  140. // Additionally, the API provides iterator utilities to iterate through Cord
  141. // data via chunks or character bytes.
  142. //
  143. class Cord {
  144. private:
  145. template <typename T>
  146. using EnableIfString =
  147. absl::enable_if_t<std::is_same<T, std::string>::value, int>;
  148. public:
  149. // Cord::Cord() Constructors.
  150. // Creates an empty Cord.
  151. constexpr Cord() noexcept;
  152. // Creates a Cord from an existing Cord. Cord is copyable and efficiently
  153. // movable. The moved-from state is valid but unspecified.
  154. Cord(const Cord& src);
  155. Cord(Cord&& src) noexcept;
  156. Cord& operator=(const Cord& x);
  157. Cord& operator=(Cord&& x) noexcept;
  158. // Creates a Cord from a `src` string. This constructor is marked explicit to
  159. // prevent implicit Cord constructions from arguments convertible to an
  160. // `absl::string_view`.
  161. explicit Cord(absl::string_view src);
  162. Cord& operator=(absl::string_view src);
  163. // Creates a Cord from a `std::string&&` rvalue. These constructors are
  164. // templated to avoid ambiguities for types that are convertible to both
  165. // `absl::string_view` and `std::string`, such as `const char*`.
  166. template <typename T, EnableIfString<T> = 0>
  167. explicit Cord(T&& src);
  168. template <typename T, EnableIfString<T> = 0>
  169. Cord& operator=(T&& src);
  170. // Cord::~Cord()
  171. //
  172. // Destructs the Cord.
  173. ~Cord() {
  174. if (contents_.is_tree()) DestroyCordSlow();
  175. }
  176. // MakeCordFromExternal()
  177. //
  178. // Creates a Cord that takes ownership of external string memory. The
  179. // contents of `data` are not copied to the Cord; instead, the external
  180. // memory is added to the Cord and reference-counted. This data may not be
  181. // changed for the life of the Cord, though it may be prepended or appended
  182. // to.
  183. //
  184. // `MakeCordFromExternal()` takes a callable "releaser" that is invoked when
  185. // the reference count for `data` reaches zero. As noted above, this data must
  186. // remain live until the releaser is invoked. The callable releaser also must:
  187. //
  188. // * be move constructible
  189. // * support `void operator()(absl::string_view) const` or `void operator()`
  190. //
  191. // Example:
  192. //
  193. // Cord MakeCord(BlockPool* pool) {
  194. // Block* block = pool->NewBlock();
  195. // FillBlock(block);
  196. // return absl::MakeCordFromExternal(
  197. // block->ToStringView(),
  198. // [pool, block](absl::string_view v) {
  199. // pool->FreeBlock(block, v);
  200. // });
  201. // }
  202. //
  203. // WARNING: Because a Cord can be reference-counted, it's likely a bug if your
  204. // releaser doesn't do anything. For example, consider the following:
  205. //
  206. // void Foo(const char* buffer, int len) {
  207. // auto c = absl::MakeCordFromExternal(absl::string_view(buffer, len),
  208. // [](absl::string_view) {});
  209. //
  210. // // BUG: If Bar() copies its cord for any reason, including keeping a
  211. // // substring of it, the lifetime of buffer might be extended beyond
  212. // // when Foo() returns.
  213. // Bar(c);
  214. // }
  215. template <typename Releaser>
  216. friend Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser);
  217. // Cord::Clear()
  218. //
  219. // Releases the Cord data. Any nodes that share data with other Cords, if
  220. // applicable, will have their reference counts reduced by 1.
  221. ABSL_ATTRIBUTE_REINITIALIZES void Clear();
  222. // Cord::Append()
  223. //
  224. // Appends data to the Cord, which may come from another Cord or other string
  225. // data.
  226. void Append(const Cord& src);
  227. void Append(Cord&& src);
  228. void Append(absl::string_view src);
  229. template <typename T, EnableIfString<T> = 0>
  230. void Append(T&& src);
  231. // Appends `buffer` to this cord, unless `buffer` has a zero length in which
  232. // case this method has no effect on this cord instance.
  233. // This method is guaranteed to consume `buffer`.
  234. void Append(CordBuffer buffer);
  235. // Returns a CordBuffer, re-using potential existing capacity in this cord.
  236. //
  237. // Cord instances may have additional unused capacity in the last (or first)
  238. // nodes of the underlying tree to facilitate amortized growth. This method
  239. // allows applications to explicitly use this spare capacity if available,
  240. // or create a new CordBuffer instance otherwise.
  241. // If this cord has a final non-shared node with at least `min_capacity`
  242. // available, then this method will return that buffer including its data
  243. // contents. I.e.; the returned buffer will have a non-zero length, and
  244. // a capacity of at least `buffer.length + min_capacity`. Otherwise, this
  245. // method will return `CordBuffer::CreateWithDefaultLimit(capacity)`.
  246. //
  247. // Below an example of using GetAppendBuffer. Notice that in this example we
  248. // use `GetAppendBuffer()` only on the first iteration. As we know nothing
  249. // about any initial extra capacity in `cord`, we may be able to use the extra
  250. // capacity. But as we add new buffers with fully utilized contents after that
  251. // we avoid calling `GetAppendBuffer()` on subsequent iterations: while this
  252. // works fine, it results in an unnecessary inspection of cord contents:
  253. //
  254. // void AppendRandomDataToCord(absl::Cord &cord, size_t n) {
  255. // bool first = true;
  256. // while (n > 0) {
  257. // CordBuffer buffer = first ? cord.GetAppendBuffer(n)
  258. // : CordBuffer::CreateWithDefaultLimit(n);
  259. // absl::Span<char> data = buffer.available_up_to(n);
  260. // FillRandomValues(data.data(), data.size());
  261. // buffer.IncreaseLengthBy(data.size());
  262. // cord.Append(std::move(buffer));
  263. // n -= data.size();
  264. // first = false;
  265. // }
  266. // }
  267. CordBuffer GetAppendBuffer(size_t capacity, size_t min_capacity = 16);
  268. // Returns a CordBuffer, re-using potential existing capacity in this cord.
  269. //
  270. // This function is identical to `GetAppendBuffer`, except that in the case
  271. // where a new `CordBuffer` is allocated, it is allocated using the provided
  272. // custom limit instead of the default limit. `GetAppendBuffer` will default
  273. // to `CordBuffer::CreateWithDefaultLimit(capacity)` whereas this method
  274. // will default to `CordBuffer::CreateWithCustomLimit(block_size, capacity)`.
  275. // This method is equivalent to `GetAppendBuffer` if `block_size` is zero.
  276. // See the documentation for `CreateWithCustomLimit` for more details on the
  277. // restrictions and legal values for `block_size`.
  278. CordBuffer GetCustomAppendBuffer(size_t block_size, size_t capacity,
  279. size_t min_capacity = 16);
  280. // Cord::Prepend()
  281. //
  282. // Prepends data to the Cord, which may come from another Cord or other string
  283. // data.
  284. void Prepend(const Cord& src);
  285. void Prepend(absl::string_view src);
  286. template <typename T, EnableIfString<T> = 0>
  287. void Prepend(T&& src);
  288. // Prepends `buffer` to this cord, unless `buffer` has a zero length in which
  289. // case this method has no effect on this cord instance.
  290. // This method is guaranteed to consume `buffer`.
  291. void Prepend(CordBuffer buffer);
  292. // Cord::RemovePrefix()
  293. //
  294. // Removes the first `n` bytes of a Cord.
  295. void RemovePrefix(size_t n);
  296. void RemoveSuffix(size_t n);
  297. // Cord::Subcord()
  298. //
  299. // Returns a new Cord representing the subrange [pos, pos + new_size) of
  300. // *this. If pos >= size(), the result is empty(). If
  301. // (pos + new_size) >= size(), the result is the subrange [pos, size()).
  302. Cord Subcord(size_t pos, size_t new_size) const;
  303. // Cord::swap()
  304. //
  305. // Swaps the contents of the Cord with `other`.
  306. void swap(Cord& other) noexcept;
  307. // swap()
  308. //
  309. // Swaps the contents of two Cords.
  310. friend void swap(Cord& x, Cord& y) noexcept { x.swap(y); }
  311. // Cord::size()
  312. //
  313. // Returns the size of the Cord.
  314. size_t size() const;
  315. // Cord::empty()
  316. //
  317. // Determines whether the given Cord is empty, returning `true` is so.
  318. bool empty() const;
  319. // Cord::EstimatedMemoryUsage()
  320. //
  321. // Returns the *approximate* number of bytes held by this cord.
  322. // See CordMemoryAccounting for more information on the accounting method.
  323. size_t EstimatedMemoryUsage(CordMemoryAccounting accounting_method =
  324. CordMemoryAccounting::kTotal) const;
  325. // Cord::Compare()
  326. //
  327. // Compares 'this' Cord with rhs. This function and its relatives treat Cords
  328. // as sequences of unsigned bytes. The comparison is a straightforward
  329. // lexicographic comparison. `Cord::Compare()` returns values as follows:
  330. //
  331. // -1 'this' Cord is smaller
  332. // 0 two Cords are equal
  333. // 1 'this' Cord is larger
  334. int Compare(absl::string_view rhs) const;
  335. int Compare(const Cord& rhs) const;
  336. // Cord::StartsWith()
  337. //
  338. // Determines whether the Cord starts with the passed string data `rhs`.
  339. bool StartsWith(const Cord& rhs) const;
  340. bool StartsWith(absl::string_view rhs) const;
  341. // Cord::EndsWith()
  342. //
  343. // Determines whether the Cord ends with the passed string data `rhs`.
  344. bool EndsWith(absl::string_view rhs) const;
  345. bool EndsWith(const Cord& rhs) const;
  346. // Cord::operator std::string()
  347. //
  348. // Converts a Cord into a `std::string()`. This operator is marked explicit to
  349. // prevent unintended Cord usage in functions that take a string.
  350. explicit operator std::string() const;
  351. // CopyCordToString()
  352. //
  353. // Copies the contents of a `src` Cord into a `*dst` string.
  354. //
  355. // This function optimizes the case of reusing the destination string since it
  356. // can reuse previously allocated capacity. However, this function does not
  357. // guarantee that pointers previously returned by `dst->data()` remain valid
  358. // even if `*dst` had enough capacity to hold `src`. If `*dst` is a new
  359. // object, prefer to simply use the conversion operator to `std::string`.
  360. friend void CopyCordToString(const Cord& src, std::string* dst);
  361. class CharIterator;
  362. //----------------------------------------------------------------------------
  363. // Cord::ChunkIterator
  364. //----------------------------------------------------------------------------
  365. //
  366. // A `Cord::ChunkIterator` allows iteration over the constituent chunks of its
  367. // Cord. Such iteration allows you to perform non-const operations on the data
  368. // of a Cord without modifying it.
  369. //
  370. // Generally, you do not instantiate a `Cord::ChunkIterator` directly;
  371. // instead, you create one implicitly through use of the `Cord::Chunks()`
  372. // member function.
  373. //
  374. // The `Cord::ChunkIterator` has the following properties:
  375. //
  376. // * The iterator is invalidated after any non-const operation on the
  377. // Cord object over which it iterates.
  378. // * The `string_view` returned by dereferencing a valid, non-`end()`
  379. // iterator is guaranteed to be non-empty.
  380. // * Two `ChunkIterator` objects can be compared equal if and only if they
  381. // remain valid and iterate over the same Cord.
  382. // * The iterator in this case is a proxy iterator; the `string_view`
  383. // returned by the iterator does not live inside the Cord, and its
  384. // lifetime is limited to the lifetime of the iterator itself. To help
  385. // prevent lifetime issues, `ChunkIterator::reference` is not a true
  386. // reference type and is equivalent to `value_type`.
  387. // * The iterator keeps state that can grow for Cords that contain many
  388. // nodes and are imbalanced due to sharing. Prefer to pass this type by
  389. // const reference instead of by value.
  390. class ChunkIterator {
  391. public:
  392. using iterator_category = std::input_iterator_tag;
  393. using value_type = absl::string_view;
  394. using difference_type = ptrdiff_t;
  395. using pointer = const value_type*;
  396. using reference = value_type;
  397. ChunkIterator() = default;
  398. ChunkIterator& operator++();
  399. ChunkIterator operator++(int);
  400. bool operator==(const ChunkIterator& other) const;
  401. bool operator!=(const ChunkIterator& other) const;
  402. reference operator*() const;
  403. pointer operator->() const;
  404. friend class Cord;
  405. friend class CharIterator;
  406. private:
  407. using CordRep = absl::cord_internal::CordRep;
  408. using CordRepBtree = absl::cord_internal::CordRepBtree;
  409. using CordRepBtreeReader = absl::cord_internal::CordRepBtreeReader;
  410. // Constructs a `begin()` iterator from `tree`. `tree` must not be null.
  411. explicit ChunkIterator(cord_internal::CordRep* tree);
  412. // Constructs a `begin()` iterator from `cord`.
  413. explicit ChunkIterator(const Cord* cord);
  414. // Initializes this instance from a tree. Invoked by constructors.
  415. void InitTree(cord_internal::CordRep* tree);
  416. // Removes `n` bytes from `current_chunk_`. Expects `n` to be smaller than
  417. // `current_chunk_.size()`.
  418. void RemoveChunkPrefix(size_t n);
  419. Cord AdvanceAndReadBytes(size_t n);
  420. void AdvanceBytes(size_t n);
  421. // Btree specific operator++
  422. ChunkIterator& AdvanceBtree();
  423. void AdvanceBytesBtree(size_t n);
  424. // A view into bytes of the current `CordRep`. It may only be a view to a
  425. // suffix of bytes if this is being used by `CharIterator`.
  426. absl::string_view current_chunk_;
  427. // The current leaf, or `nullptr` if the iterator points to short data.
  428. // If the current chunk is a substring node, current_leaf_ points to the
  429. // underlying flat or external node.
  430. absl::cord_internal::CordRep* current_leaf_ = nullptr;
  431. // The number of bytes left in the `Cord` over which we are iterating.
  432. size_t bytes_remaining_ = 0;
  433. // Cord reader for cord btrees. Empty if not traversing a btree.
  434. CordRepBtreeReader btree_reader_;
  435. };
  436. // Cord::chunk_begin()
  437. //
  438. // Returns an iterator to the first chunk of the `Cord`.
  439. //
  440. // Generally, prefer using `Cord::Chunks()` within a range-based for loop for
  441. // iterating over the chunks of a Cord. This method may be useful for getting
  442. // a `ChunkIterator` where range-based for-loops are not useful.
  443. //
  444. // Example:
  445. //
  446. // absl::Cord::ChunkIterator FindAsChunk(const absl::Cord& c,
  447. // absl::string_view s) {
  448. // return std::find(c.chunk_begin(), c.chunk_end(), s);
  449. // }
  450. ChunkIterator chunk_begin() const;
  451. // Cord::chunk_end()
  452. //
  453. // Returns an iterator one increment past the last chunk of the `Cord`.
  454. //
  455. // Generally, prefer using `Cord::Chunks()` within a range-based for loop for
  456. // iterating over the chunks of a Cord. This method may be useful for getting
  457. // a `ChunkIterator` where range-based for-loops may not be available.
  458. ChunkIterator chunk_end() const;
  459. //----------------------------------------------------------------------------
  460. // Cord::ChunkRange
  461. //----------------------------------------------------------------------------
  462. //
  463. // `ChunkRange` is a helper class for iterating over the chunks of the `Cord`,
  464. // producing an iterator which can be used within a range-based for loop.
  465. // Construction of a `ChunkRange` will return an iterator pointing to the
  466. // first chunk of the Cord. Generally, do not construct a `ChunkRange`
  467. // directly; instead, prefer to use the `Cord::Chunks()` method.
  468. //
  469. // Implementation note: `ChunkRange` is simply a convenience wrapper over
  470. // `Cord::chunk_begin()` and `Cord::chunk_end()`.
  471. class ChunkRange {
  472. public:
  473. // Fulfill minimum c++ container requirements [container.requirements]
  474. // These (partial) container type definitions allow ChunkRange to be used
  475. // in various utilities expecting a subset of [container.requirements].
  476. // For example, the below enables using `::testing::ElementsAre(...)`
  477. using value_type = absl::string_view;
  478. using reference = value_type&;
  479. using const_reference = const value_type&;
  480. using iterator = ChunkIterator;
  481. using const_iterator = ChunkIterator;
  482. explicit ChunkRange(const Cord* cord) : cord_(cord) {}
  483. ChunkIterator begin() const;
  484. ChunkIterator end() const;
  485. private:
  486. const Cord* cord_;
  487. };
  488. // Cord::Chunks()
  489. //
  490. // Returns a `Cord::ChunkRange` for iterating over the chunks of a `Cord` with
  491. // a range-based for-loop. For most iteration tasks on a Cord, use
  492. // `Cord::Chunks()` to retrieve this iterator.
  493. //
  494. // Example:
  495. //
  496. // void ProcessChunks(const Cord& cord) {
  497. // for (absl::string_view chunk : cord.Chunks()) { ... }
  498. // }
  499. //
  500. // Note that the ordinary caveats of temporary lifetime extension apply:
  501. //
  502. // void Process() {
  503. // for (absl::string_view chunk : CordFactory().Chunks()) {
  504. // // The temporary Cord returned by CordFactory has been destroyed!
  505. // }
  506. // }
  507. ChunkRange Chunks() const;
  508. //----------------------------------------------------------------------------
  509. // Cord::CharIterator
  510. //----------------------------------------------------------------------------
  511. //
  512. // A `Cord::CharIterator` allows iteration over the constituent characters of
  513. // a `Cord`.
  514. //
  515. // Generally, you do not instantiate a `Cord::CharIterator` directly; instead,
  516. // you create one implicitly through use of the `Cord::Chars()` member
  517. // function.
  518. //
  519. // A `Cord::CharIterator` has the following properties:
  520. //
  521. // * The iterator is invalidated after any non-const operation on the
  522. // Cord object over which it iterates.
  523. // * Two `CharIterator` objects can be compared equal if and only if they
  524. // remain valid and iterate over the same Cord.
  525. // * The iterator keeps state that can grow for Cords that contain many
  526. // nodes and are imbalanced due to sharing. Prefer to pass this type by
  527. // const reference instead of by value.
  528. // * This type cannot act as a forward iterator because a `Cord` can reuse
  529. // sections of memory. This fact violates the requirement for forward
  530. // iterators to compare equal if dereferencing them returns the same
  531. // object.
  532. class CharIterator {
  533. public:
  534. using iterator_category = std::input_iterator_tag;
  535. using value_type = char;
  536. using difference_type = ptrdiff_t;
  537. using pointer = const char*;
  538. using reference = const char&;
  539. CharIterator() = default;
  540. CharIterator& operator++();
  541. CharIterator operator++(int);
  542. bool operator==(const CharIterator& other) const;
  543. bool operator!=(const CharIterator& other) const;
  544. reference operator*() const;
  545. pointer operator->() const;
  546. friend Cord;
  547. private:
  548. explicit CharIterator(const Cord* cord) : chunk_iterator_(cord) {}
  549. ChunkIterator chunk_iterator_;
  550. };
  551. // Cord::AdvanceAndRead()
  552. //
  553. // Advances the `Cord::CharIterator` by `n_bytes` and returns the bytes
  554. // advanced as a separate `Cord`. `n_bytes` must be less than or equal to the
  555. // number of bytes within the Cord; otherwise, behavior is undefined. It is
  556. // valid to pass `char_end()` and `0`.
  557. static Cord AdvanceAndRead(CharIterator* it, size_t n_bytes);
  558. // Cord::Advance()
  559. //
  560. // Advances the `Cord::CharIterator` by `n_bytes`. `n_bytes` must be less than
  561. // or equal to the number of bytes remaining within the Cord; otherwise,
  562. // behavior is undefined. It is valid to pass `char_end()` and `0`.
  563. static void Advance(CharIterator* it, size_t n_bytes);
  564. // Cord::ChunkRemaining()
  565. //
  566. // Returns the longest contiguous view starting at the iterator's position.
  567. //
  568. // `it` must be dereferenceable.
  569. static absl::string_view ChunkRemaining(const CharIterator& it);
  570. // Cord::char_begin()
  571. //
  572. // Returns an iterator to the first character of the `Cord`.
  573. //
  574. // Generally, prefer using `Cord::Chars()` within a range-based for loop for
  575. // iterating over the chunks of a Cord. This method may be useful for getting
  576. // a `CharIterator` where range-based for-loops may not be available.
  577. CharIterator char_begin() const;
  578. // Cord::char_end()
  579. //
  580. // Returns an iterator to one past the last character of the `Cord`.
  581. //
  582. // Generally, prefer using `Cord::Chars()` within a range-based for loop for
  583. // iterating over the chunks of a Cord. This method may be useful for getting
  584. // a `CharIterator` where range-based for-loops are not useful.
  585. CharIterator char_end() const;
  586. // Cord::CharRange
  587. //
  588. // `CharRange` is a helper class for iterating over the characters of a
  589. // producing an iterator which can be used within a range-based for loop.
  590. // Construction of a `CharRange` will return an iterator pointing to the first
  591. // character of the Cord. Generally, do not construct a `CharRange` directly;
  592. // instead, prefer to use the `Cord::Chars()` method shown below.
  593. //
  594. // Implementation note: `CharRange` is simply a convenience wrapper over
  595. // `Cord::char_begin()` and `Cord::char_end()`.
  596. class CharRange {
  597. public:
  598. // Fulfill minimum c++ container requirements [container.requirements]
  599. // Theses (partial) container type definitions allow CharRange to be used
  600. // in various utilities expecting a subset of [container.requirements].
  601. // For example, the below enables using `::testing::ElementsAre(...)`
  602. using value_type = char;
  603. using reference = value_type&;
  604. using const_reference = const value_type&;
  605. using iterator = CharIterator;
  606. using const_iterator = CharIterator;
  607. explicit CharRange(const Cord* cord) : cord_(cord) {}
  608. CharIterator begin() const;
  609. CharIterator end() const;
  610. private:
  611. const Cord* cord_;
  612. };
  613. // Cord::Chars()
  614. //
  615. // Returns a `Cord::CharRange` for iterating over the characters of a `Cord`
  616. // with a range-based for-loop. For most character-based iteration tasks on a
  617. // Cord, use `Cord::Chars()` to retrieve this iterator.
  618. //
  619. // Example:
  620. //
  621. // void ProcessCord(const Cord& cord) {
  622. // for (char c : cord.Chars()) { ... }
  623. // }
  624. //
  625. // Note that the ordinary caveats of temporary lifetime extension apply:
  626. //
  627. // void Process() {
  628. // for (char c : CordFactory().Chars()) {
  629. // // The temporary Cord returned by CordFactory has been destroyed!
  630. // }
  631. // }
  632. CharRange Chars() const;
  633. // Cord::operator[]
  634. //
  635. // Gets the "i"th character of the Cord and returns it, provided that
  636. // 0 <= i < Cord.size().
  637. //
  638. // NOTE: This routine is reasonably efficient. It is roughly
  639. // logarithmic based on the number of chunks that make up the cord. Still,
  640. // if you need to iterate over the contents of a cord, you should
  641. // use a CharIterator/ChunkIterator rather than call operator[] or Get()
  642. // repeatedly in a loop.
  643. char operator[](size_t i) const;
  644. // Cord::TryFlat()
  645. //
  646. // If this cord's representation is a single flat array, returns a
  647. // string_view referencing that array. Otherwise returns nullopt.
  648. absl::optional<absl::string_view> TryFlat() const;
  649. // Cord::Flatten()
  650. //
  651. // Flattens the cord into a single array and returns a view of the data.
  652. //
  653. // If the cord was already flat, the contents are not modified.
  654. absl::string_view Flatten();
  655. // Supports absl::Cord as a sink object for absl::Format().
  656. friend void AbslFormatFlush(absl::Cord* cord, absl::string_view part) {
  657. cord->Append(part);
  658. }
  659. // Cord::SetExpectedChecksum()
  660. //
  661. // Stores a checksum value with this non-empty cord instance, for later
  662. // retrieval.
  663. //
  664. // The expected checksum is a number stored out-of-band, alongside the data.
  665. // It is preserved across copies and assignments, but any mutations to a cord
  666. // will cause it to lose its expected checksum.
  667. //
  668. // The expected checksum is not part of a Cord's value, and does not affect
  669. // operations such as equality or hashing.
  670. //
  671. // This field is intended to store a CRC32C checksum for later validation, to
  672. // help support end-to-end checksum workflows. However, the Cord API itself
  673. // does no CRC validation, and assigns no meaning to this number.
  674. //
  675. // This call has no effect if this cord is empty.
  676. void SetExpectedChecksum(uint32_t crc);
  677. // Returns this cord's expected checksum, if it has one. Otherwise, returns
  678. // nullopt.
  679. absl::optional<uint32_t> ExpectedChecksum() const;
  680. template <typename H>
  681. friend H AbslHashValue(H hash_state, const absl::Cord& c) {
  682. absl::optional<absl::string_view> maybe_flat = c.TryFlat();
  683. if (maybe_flat.has_value()) {
  684. return H::combine(std::move(hash_state), *maybe_flat);
  685. }
  686. return c.HashFragmented(std::move(hash_state));
  687. }
  688. // Create a Cord with the contents of StringConstant<T>::value.
  689. // No allocations will be done and no data will be copied.
  690. // This is an INTERNAL API and subject to change or removal. This API can only
  691. // be used by spelling absl::strings_internal::MakeStringConstant, which is
  692. // also an internal API.
  693. template <typename T>
  694. // NOLINTNEXTLINE(google-explicit-constructor)
  695. constexpr Cord(strings_internal::StringConstant<T>);
  696. private:
  697. using CordRep = absl::cord_internal::CordRep;
  698. using CordRepFlat = absl::cord_internal::CordRepFlat;
  699. using CordzInfo = cord_internal::CordzInfo;
  700. using CordzUpdateScope = cord_internal::CordzUpdateScope;
  701. using CordzUpdateTracker = cord_internal::CordzUpdateTracker;
  702. using InlineData = cord_internal::InlineData;
  703. using MethodIdentifier = CordzUpdateTracker::MethodIdentifier;
  704. // Creates a cord instance with `method` representing the originating
  705. // public API call causing the cord to be created.
  706. explicit Cord(absl::string_view src, MethodIdentifier method);
  707. friend class CordTestPeer;
  708. friend bool operator==(const Cord& lhs, const Cord& rhs);
  709. friend bool operator==(const Cord& lhs, absl::string_view rhs);
  710. friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord);
  711. // Calls the provided function once for each cord chunk, in order. Unlike
  712. // Chunks(), this API will not allocate memory.
  713. void ForEachChunk(absl::FunctionRef<void(absl::string_view)>) const;
  714. // Allocates new contiguous storage for the contents of the cord. This is
  715. // called by Flatten() when the cord was not already flat.
  716. absl::string_view FlattenSlowPath();
  717. // Actual cord contents are hidden inside the following simple
  718. // class so that we can isolate the bulk of cord.cc from changes
  719. // to the representation.
  720. //
  721. // InlineRep holds either a tree pointer, or an array of kMaxInline bytes.
  722. class InlineRep {
  723. public:
  724. static constexpr unsigned char kMaxInline = cord_internal::kMaxInline;
  725. static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), "");
  726. constexpr InlineRep() : data_() {}
  727. explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {}
  728. InlineRep(const InlineRep& src);
  729. InlineRep(InlineRep&& src);
  730. InlineRep& operator=(const InlineRep& src);
  731. InlineRep& operator=(InlineRep&& src) noexcept;
  732. explicit constexpr InlineRep(absl::string_view sv, CordRep* rep);
  733. void Swap(InlineRep* rhs);
  734. bool empty() const;
  735. size_t size() const;
  736. const char* data() const; // Returns nullptr if holding pointer
  737. void set_data(const char* data, size_t n); // Discards pointer, if any
  738. char* set_data(size_t n); // Write data to the result
  739. // Returns nullptr if holding bytes
  740. absl::cord_internal::CordRep* tree() const;
  741. absl::cord_internal::CordRep* as_tree() const;
  742. const char* as_chars() const;
  743. // Returns non-null iff was holding a pointer
  744. absl::cord_internal::CordRep* clear();
  745. // Converts to pointer if necessary.
  746. void reduce_size(size_t n); // REQUIRES: holding data
  747. void remove_prefix(size_t n); // REQUIRES: holding data
  748. void AppendArray(absl::string_view src, MethodIdentifier method);
  749. absl::string_view FindFlatStartPiece() const;
  750. // Creates a CordRepFlat instance from the current inlined data with `extra'
  751. // bytes of desired additional capacity.
  752. CordRepFlat* MakeFlatWithExtraCapacity(size_t extra);
  753. // Sets the tree value for this instance. `rep` must not be null.
  754. // Requires the current instance to hold a tree, and a lock to be held on
  755. // any CordzInfo referenced by this instance. The latter is enforced through
  756. // the CordzUpdateScope argument. If the current instance is sampled, then
  757. // the CordzInfo instance is updated to reference the new `rep` value.
  758. void SetTree(CordRep* rep, const CordzUpdateScope& scope);
  759. // Identical to SetTree(), except that `rep` is allowed to be null, in
  760. // which case the current instance is reset to an empty value.
  761. void SetTreeOrEmpty(CordRep* rep, const CordzUpdateScope& scope);
  762. // Sets the tree value for this instance, and randomly samples this cord.
  763. // This function disregards existing contents in `data_`, and should be
  764. // called when a Cord is 'promoted' from an 'uninitialized' or 'inlined'
  765. // value to a non-inlined (tree / ring) value.
  766. void EmplaceTree(CordRep* rep, MethodIdentifier method);
  767. // Identical to EmplaceTree, except that it copies the parent stack from
  768. // the provided `parent` data if the parent is sampled.
  769. void EmplaceTree(CordRep* rep, const InlineData& parent,
  770. MethodIdentifier method);
  771. // Commits the change of a newly created, or updated `rep` root value into
  772. // this cord. `old_rep` indicates the old (inlined or tree) value of the
  773. // cord, and determines if the commit invokes SetTree() or EmplaceTree().
  774. void CommitTree(const CordRep* old_rep, CordRep* rep,
  775. const CordzUpdateScope& scope, MethodIdentifier method);
  776. void AppendTreeToInlined(CordRep* tree, MethodIdentifier method);
  777. void AppendTreeToTree(CordRep* tree, MethodIdentifier method);
  778. void AppendTree(CordRep* tree, MethodIdentifier method);
  779. void PrependTreeToInlined(CordRep* tree, MethodIdentifier method);
  780. void PrependTreeToTree(CordRep* tree, MethodIdentifier method);
  781. void PrependTree(CordRep* tree, MethodIdentifier method);
  782. bool IsSame(const InlineRep& other) const { return data_ == other.data_; }
  783. void CopyTo(std::string* dst) const {
  784. // memcpy is much faster when operating on a known size. On most supported
  785. // platforms, the small string optimization is large enough that resizing
  786. // to 15 bytes does not cause a memory allocation.
  787. absl::strings_internal::STLStringResizeUninitialized(dst, kMaxInline);
  788. data_.copy_max_inline_to(&(*dst)[0]);
  789. // erase is faster than resize because the logic for memory allocation is
  790. // not needed.
  791. dst->erase(inline_size());
  792. }
  793. // Copies the inline contents into `dst`. Assumes the cord is not empty.
  794. void CopyToArray(char* dst) const;
  795. bool is_tree() const { return data_.is_tree(); }
  796. // Returns true if the Cord is being profiled by cordz.
  797. bool is_profiled() const { return data_.is_tree() && data_.is_profiled(); }
  798. // Returns the available inlined capacity, or 0 if is_tree() == true.
  799. size_t remaining_inline_capacity() const {
  800. return data_.is_tree() ? 0 : kMaxInline - data_.inline_size();
  801. }
  802. // Returns the profiled CordzInfo, or nullptr if not sampled.
  803. absl::cord_internal::CordzInfo* cordz_info() const {
  804. return data_.cordz_info();
  805. }
  806. // Sets the profiled CordzInfo. `cordz_info` must not be null.
  807. void set_cordz_info(cord_internal::CordzInfo* cordz_info) {
  808. assert(cordz_info != nullptr);
  809. data_.set_cordz_info(cordz_info);
  810. }
  811. // Resets the current cordz_info to null / empty.
  812. void clear_cordz_info() { data_.clear_cordz_info(); }
  813. private:
  814. friend class Cord;
  815. void AssignSlow(const InlineRep& src);
  816. // Unrefs the tree and stops profiling.
  817. void UnrefTree();
  818. void ResetToEmpty() { data_ = {}; }
  819. void set_inline_size(size_t size) { data_.set_inline_size(size); }
  820. size_t inline_size() const { return data_.inline_size(); }
  821. // Empty cords that carry a checksum have a CordRepCrc node with a null
  822. // child node. The code can avoid lots of special cases where it would
  823. // otherwise transition from tree to inline storage if we just remove the
  824. // CordRepCrc node before mutations. Must never be called inside a
  825. // CordzUpdateScope since it untracks the cordz info.
  826. void MaybeRemoveEmptyCrcNode();
  827. cord_internal::InlineData data_;
  828. };
  829. InlineRep contents_;
  830. // Helper for GetFlat() and TryFlat().
  831. static bool GetFlatAux(absl::cord_internal::CordRep* rep,
  832. absl::string_view* fragment);
  833. // Helper for ForEachChunk().
  834. static void ForEachChunkAux(
  835. absl::cord_internal::CordRep* rep,
  836. absl::FunctionRef<void(absl::string_view)> callback);
  837. // The destructor for non-empty Cords.
  838. void DestroyCordSlow();
  839. // Out-of-line implementation of slower parts of logic.
  840. void CopyToArraySlowPath(char* dst) const;
  841. int CompareSlowPath(absl::string_view rhs, size_t compared_size,
  842. size_t size_to_compare) const;
  843. int CompareSlowPath(const Cord& rhs, size_t compared_size,
  844. size_t size_to_compare) const;
  845. bool EqualsImpl(absl::string_view rhs, size_t size_to_compare) const;
  846. bool EqualsImpl(const Cord& rhs, size_t size_to_compare) const;
  847. int CompareImpl(const Cord& rhs) const;
  848. template <typename ResultType, typename RHS>
  849. friend ResultType GenericCompare(const Cord& lhs, const RHS& rhs,
  850. size_t size_to_compare);
  851. static absl::string_view GetFirstChunk(const Cord& c);
  852. static absl::string_view GetFirstChunk(absl::string_view sv);
  853. // Returns a new reference to contents_.tree(), or steals an existing
  854. // reference if called on an rvalue.
  855. absl::cord_internal::CordRep* TakeRep() const&;
  856. absl::cord_internal::CordRep* TakeRep() &&;
  857. // Helper for Append().
  858. template <typename C>
  859. void AppendImpl(C&& src);
  860. // Appends / Prepends `src` to this instance, using precise sizing.
  861. // This method does explicitly not attempt to use any spare capacity
  862. // in any pending last added private owned flat.
  863. // Requires `src` to be <= kMaxFlatLength.
  864. void AppendPrecise(absl::string_view src, MethodIdentifier method);
  865. void PrependPrecise(absl::string_view src, MethodIdentifier method);
  866. CordBuffer GetAppendBufferSlowPath(size_t block_size, size_t capacity,
  867. size_t min_capacity);
  868. // Prepends the provided data to this instance. `method` contains the public
  869. // API method for this action which is tracked for Cordz sampling purposes.
  870. void PrependArray(absl::string_view src, MethodIdentifier method);
  871. // Assigns the value in 'src' to this instance, 'stealing' its contents.
  872. // Requires src.length() > kMaxBytesToCopy.
  873. Cord& AssignLargeString(std::string&& src);
  874. // Helper for AbslHashValue().
  875. template <typename H>
  876. H HashFragmented(H hash_state) const {
  877. typename H::AbslInternalPiecewiseCombiner combiner;
  878. ForEachChunk([&combiner, &hash_state](absl::string_view chunk) {
  879. hash_state = combiner.add_buffer(std::move(hash_state), chunk.data(),
  880. chunk.size());
  881. });
  882. return H::combine(combiner.finalize(std::move(hash_state)), size());
  883. }
  884. friend class CrcCord;
  885. void SetCrcCordState(crc_internal::CrcCordState state);
  886. const crc_internal::CrcCordState* MaybeGetCrcCordState() const;
  887. };
  888. ABSL_NAMESPACE_END
  889. } // namespace absl
  890. namespace absl {
  891. ABSL_NAMESPACE_BEGIN
  892. // allow a Cord to be logged
  893. extern std::ostream& operator<<(std::ostream& out, const Cord& cord);
  894. // ------------------------------------------------------------------
  895. // Internal details follow. Clients should ignore.
  896. namespace cord_internal {
  897. // Does non-template-specific `CordRepExternal` initialization.
  898. // Requires `data` to be non-empty.
  899. void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep);
  900. // Creates a new `CordRep` that owns `data` and `releaser` and returns a pointer
  901. // to it. Requires `data` to be non-empty.
  902. template <typename Releaser>
  903. // NOLINTNEXTLINE - suppress clang-tidy raw pointer return.
  904. CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) {
  905. assert(!data.empty());
  906. using ReleaserType = absl::decay_t<Releaser>;
  907. CordRepExternal* rep = new CordRepExternalImpl<ReleaserType>(
  908. std::forward<Releaser>(releaser), 0);
  909. InitializeCordRepExternal(data, rep);
  910. return rep;
  911. }
  912. // Overload for function reference types that dispatches using a function
  913. // pointer because there are no `alignof()` or `sizeof()` a function reference.
  914. // NOLINTNEXTLINE - suppress clang-tidy raw pointer return.
  915. inline CordRep* NewExternalRep(absl::string_view data,
  916. void (&releaser)(absl::string_view)) {
  917. return NewExternalRep(data, &releaser);
  918. }
  919. } // namespace cord_internal
  920. template <typename Releaser>
  921. Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) {
  922. Cord cord;
  923. if (ABSL_PREDICT_TRUE(!data.empty())) {
  924. cord.contents_.EmplaceTree(::absl::cord_internal::NewExternalRep(
  925. data, std::forward<Releaser>(releaser)),
  926. Cord::MethodIdentifier::kMakeCordFromExternal);
  927. } else {
  928. using ReleaserType = absl::decay_t<Releaser>;
  929. cord_internal::InvokeReleaser(
  930. cord_internal::Rank0{}, ReleaserType(std::forward<Releaser>(releaser)),
  931. data);
  932. }
  933. return cord;
  934. }
  935. constexpr Cord::InlineRep::InlineRep(absl::string_view sv, CordRep* rep)
  936. : data_(sv, rep) {}
  937. inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src)
  938. : data_(InlineData::kDefaultInit) {
  939. if (CordRep* tree = src.tree()) {
  940. EmplaceTree(CordRep::Ref(tree), src.data_,
  941. CordzUpdateTracker::kConstructorCord);
  942. } else {
  943. data_ = src.data_;
  944. }
  945. }
  946. inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) : data_(src.data_) {
  947. src.ResetToEmpty();
  948. }
  949. inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) {
  950. if (this == &src) {
  951. return *this;
  952. }
  953. if (!is_tree() && !src.is_tree()) {
  954. data_ = src.data_;
  955. return *this;
  956. }
  957. AssignSlow(src);
  958. return *this;
  959. }
  960. inline Cord::InlineRep& Cord::InlineRep::operator=(
  961. Cord::InlineRep&& src) noexcept {
  962. if (is_tree()) {
  963. UnrefTree();
  964. }
  965. data_ = src.data_;
  966. src.ResetToEmpty();
  967. return *this;
  968. }
  969. inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) {
  970. if (rhs == this) {
  971. return;
  972. }
  973. std::swap(data_, rhs->data_);
  974. }
  975. inline const char* Cord::InlineRep::data() const {
  976. return is_tree() ? nullptr : data_.as_chars();
  977. }
  978. inline const char* Cord::InlineRep::as_chars() const {
  979. assert(!data_.is_tree());
  980. return data_.as_chars();
  981. }
  982. inline absl::cord_internal::CordRep* Cord::InlineRep::as_tree() const {
  983. assert(data_.is_tree());
  984. return data_.as_tree();
  985. }
  986. inline absl::cord_internal::CordRep* Cord::InlineRep::tree() const {
  987. if (is_tree()) {
  988. return as_tree();
  989. } else {
  990. return nullptr;
  991. }
  992. }
  993. inline bool Cord::InlineRep::empty() const { return data_.is_empty(); }
  994. inline size_t Cord::InlineRep::size() const {
  995. return is_tree() ? as_tree()->length : inline_size();
  996. }
  997. inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity(
  998. size_t extra) {
  999. static_assert(cord_internal::kMinFlatLength >= sizeof(data_), "");
  1000. size_t len = data_.inline_size();
  1001. auto* result = CordRepFlat::New(len + extra);
  1002. result->length = len;
  1003. data_.copy_max_inline_to(result->Data());
  1004. return result;
  1005. }
  1006. inline void Cord::InlineRep::EmplaceTree(CordRep* rep,
  1007. MethodIdentifier method) {
  1008. assert(rep);
  1009. data_.make_tree(rep);
  1010. CordzInfo::MaybeTrackCord(data_, method);
  1011. }
  1012. inline void Cord::InlineRep::EmplaceTree(CordRep* rep, const InlineData& parent,
  1013. MethodIdentifier method) {
  1014. data_.make_tree(rep);
  1015. CordzInfo::MaybeTrackCord(data_, parent, method);
  1016. }
  1017. inline void Cord::InlineRep::SetTree(CordRep* rep,
  1018. const CordzUpdateScope& scope) {
  1019. assert(rep);
  1020. assert(data_.is_tree());
  1021. data_.set_tree(rep);
  1022. scope.SetCordRep(rep);
  1023. }
  1024. inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep,
  1025. const CordzUpdateScope& scope) {
  1026. assert(data_.is_tree());
  1027. if (rep) {
  1028. data_.set_tree(rep);
  1029. } else {
  1030. data_ = {};
  1031. }
  1032. scope.SetCordRep(rep);
  1033. }
  1034. inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep,
  1035. const CordzUpdateScope& scope,
  1036. MethodIdentifier method) {
  1037. if (old_rep) {
  1038. SetTree(rep, scope);
  1039. } else {
  1040. EmplaceTree(rep, method);
  1041. }
  1042. }
  1043. inline absl::cord_internal::CordRep* Cord::InlineRep::clear() {
  1044. if (is_tree()) {
  1045. CordzInfo::MaybeUntrackCord(cordz_info());
  1046. }
  1047. absl::cord_internal::CordRep* result = tree();
  1048. ResetToEmpty();
  1049. return result;
  1050. }
  1051. inline void Cord::InlineRep::CopyToArray(char* dst) const {
  1052. assert(!is_tree());
  1053. size_t n = inline_size();
  1054. assert(n != 0);
  1055. cord_internal::SmallMemmove(dst, data_.as_chars(), n);
  1056. }
  1057. inline void Cord::InlineRep::MaybeRemoveEmptyCrcNode() {
  1058. CordRep* rep = tree();
  1059. if (rep == nullptr || ABSL_PREDICT_TRUE(rep->length > 0)) {
  1060. return;
  1061. }
  1062. assert(rep->IsCrc());
  1063. assert(rep->crc()->child == nullptr);
  1064. CordzInfo::MaybeUntrackCord(cordz_info());
  1065. CordRep::Unref(rep);
  1066. ResetToEmpty();
  1067. }
  1068. constexpr inline Cord::Cord() noexcept {}
  1069. inline Cord::Cord(absl::string_view src)
  1070. : Cord(src, CordzUpdateTracker::kConstructorString) {}
  1071. template <typename T>
  1072. constexpr Cord::Cord(strings_internal::StringConstant<T>)
  1073. : contents_(strings_internal::StringConstant<T>::value,
  1074. strings_internal::StringConstant<T>::value.size() <=
  1075. cord_internal::kMaxInline
  1076. ? nullptr
  1077. : &cord_internal::ConstInitExternalStorage<
  1078. strings_internal::StringConstant<T>>::value) {}
  1079. inline Cord& Cord::operator=(const Cord& x) {
  1080. contents_ = x.contents_;
  1081. return *this;
  1082. }
  1083. template <typename T, Cord::EnableIfString<T>>
  1084. Cord& Cord::operator=(T&& src) {
  1085. if (src.size() <= cord_internal::kMaxBytesToCopy) {
  1086. return operator=(absl::string_view(src));
  1087. } else {
  1088. return AssignLargeString(std::forward<T>(src));
  1089. }
  1090. }
  1091. inline Cord::Cord(const Cord& src) : contents_(src.contents_) {}
  1092. inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {}
  1093. inline void Cord::swap(Cord& other) noexcept {
  1094. contents_.Swap(&other.contents_);
  1095. }
  1096. inline Cord& Cord::operator=(Cord&& x) noexcept {
  1097. contents_ = std::move(x.contents_);
  1098. return *this;
  1099. }
  1100. extern template Cord::Cord(std::string&& src);
  1101. inline size_t Cord::size() const {
  1102. // Length is 1st field in str.rep_
  1103. return contents_.size();
  1104. }
  1105. inline bool Cord::empty() const { return size() == 0; }
  1106. inline size_t Cord::EstimatedMemoryUsage(
  1107. CordMemoryAccounting accounting_method) const {
  1108. size_t result = sizeof(Cord);
  1109. if (const absl::cord_internal::CordRep* rep = contents_.tree()) {
  1110. if (accounting_method == CordMemoryAccounting::kFairShare) {
  1111. result += cord_internal::GetEstimatedFairShareMemoryUsage(rep);
  1112. } else {
  1113. result += cord_internal::GetEstimatedMemoryUsage(rep);
  1114. }
  1115. }
  1116. return result;
  1117. }
  1118. inline absl::optional<absl::string_view> Cord::TryFlat() const {
  1119. absl::cord_internal::CordRep* rep = contents_.tree();
  1120. if (rep == nullptr) {
  1121. return absl::string_view(contents_.data(), contents_.size());
  1122. }
  1123. absl::string_view fragment;
  1124. if (GetFlatAux(rep, &fragment)) {
  1125. return fragment;
  1126. }
  1127. return absl::nullopt;
  1128. }
  1129. inline absl::string_view Cord::Flatten() {
  1130. absl::cord_internal::CordRep* rep = contents_.tree();
  1131. if (rep == nullptr) {
  1132. return absl::string_view(contents_.data(), contents_.size());
  1133. } else {
  1134. absl::string_view already_flat_contents;
  1135. if (GetFlatAux(rep, &already_flat_contents)) {
  1136. return already_flat_contents;
  1137. }
  1138. }
  1139. return FlattenSlowPath();
  1140. }
  1141. inline void Cord::Append(absl::string_view src) {
  1142. contents_.AppendArray(src, CordzUpdateTracker::kAppendString);
  1143. }
  1144. inline void Cord::Prepend(absl::string_view src) {
  1145. PrependArray(src, CordzUpdateTracker::kPrependString);
  1146. }
  1147. inline void Cord::Append(CordBuffer buffer) {
  1148. if (ABSL_PREDICT_FALSE(buffer.length() == 0)) return;
  1149. absl::string_view short_value;
  1150. if (CordRep* rep = buffer.ConsumeValue(short_value)) {
  1151. contents_.AppendTree(rep, CordzUpdateTracker::kAppendCordBuffer);
  1152. } else {
  1153. AppendPrecise(short_value, CordzUpdateTracker::kAppendCordBuffer);
  1154. }
  1155. }
  1156. inline void Cord::Prepend(CordBuffer buffer) {
  1157. if (ABSL_PREDICT_FALSE(buffer.length() == 0)) return;
  1158. absl::string_view short_value;
  1159. if (CordRep* rep = buffer.ConsumeValue(short_value)) {
  1160. contents_.PrependTree(rep, CordzUpdateTracker::kPrependCordBuffer);
  1161. } else {
  1162. PrependPrecise(short_value, CordzUpdateTracker::kPrependCordBuffer);
  1163. }
  1164. }
  1165. inline CordBuffer Cord::GetAppendBuffer(size_t capacity, size_t min_capacity) {
  1166. if (empty()) return CordBuffer::CreateWithDefaultLimit(capacity);
  1167. return GetAppendBufferSlowPath(0, capacity, min_capacity);
  1168. }
  1169. inline CordBuffer Cord::GetCustomAppendBuffer(size_t block_size,
  1170. size_t capacity,
  1171. size_t min_capacity) {
  1172. if (empty()) {
  1173. return block_size ? CordBuffer::CreateWithCustomLimit(block_size, capacity)
  1174. : CordBuffer::CreateWithDefaultLimit(capacity);
  1175. }
  1176. return GetAppendBufferSlowPath(block_size, capacity, min_capacity);
  1177. }
  1178. extern template void Cord::Append(std::string&& src);
  1179. extern template void Cord::Prepend(std::string&& src);
  1180. inline int Cord::Compare(const Cord& rhs) const {
  1181. if (!contents_.is_tree() && !rhs.contents_.is_tree()) {
  1182. return contents_.data_.Compare(rhs.contents_.data_);
  1183. }
  1184. return CompareImpl(rhs);
  1185. }
  1186. // Does 'this' cord start/end with rhs
  1187. inline bool Cord::StartsWith(const Cord& rhs) const {
  1188. if (contents_.IsSame(rhs.contents_)) return true;
  1189. size_t rhs_size = rhs.size();
  1190. if (size() < rhs_size) return false;
  1191. return EqualsImpl(rhs, rhs_size);
  1192. }
  1193. inline bool Cord::StartsWith(absl::string_view rhs) const {
  1194. size_t rhs_size = rhs.size();
  1195. if (size() < rhs_size) return false;
  1196. return EqualsImpl(rhs, rhs_size);
  1197. }
  1198. inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) {
  1199. tree = cord_internal::SkipCrcNode(tree);
  1200. if (tree->tag == cord_internal::BTREE) {
  1201. current_chunk_ = btree_reader_.Init(tree->btree());
  1202. } else {
  1203. current_leaf_ = tree;
  1204. current_chunk_ = cord_internal::EdgeData(tree);
  1205. }
  1206. }
  1207. inline Cord::ChunkIterator::ChunkIterator(cord_internal::CordRep* tree) {
  1208. bytes_remaining_ = tree->length;
  1209. InitTree(tree);
  1210. }
  1211. inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) {
  1212. if (CordRep* tree = cord->contents_.tree()) {
  1213. bytes_remaining_ = tree->length;
  1214. if (ABSL_PREDICT_TRUE(bytes_remaining_ != 0)) {
  1215. InitTree(tree);
  1216. } else {
  1217. current_chunk_ = {};
  1218. }
  1219. } else {
  1220. bytes_remaining_ = cord->contents_.inline_size();
  1221. current_chunk_ = {cord->contents_.data(), bytes_remaining_};
  1222. }
  1223. }
  1224. inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceBtree() {
  1225. current_chunk_ = btree_reader_.Next();
  1226. return *this;
  1227. }
  1228. inline void Cord::ChunkIterator::AdvanceBytesBtree(size_t n) {
  1229. assert(n >= current_chunk_.size());
  1230. bytes_remaining_ -= n;
  1231. if (bytes_remaining_) {
  1232. if (n == current_chunk_.size()) {
  1233. current_chunk_ = btree_reader_.Next();
  1234. } else {
  1235. size_t offset = btree_reader_.length() - bytes_remaining_;
  1236. current_chunk_ = btree_reader_.Seek(offset);
  1237. }
  1238. } else {
  1239. current_chunk_ = {};
  1240. }
  1241. }
  1242. inline Cord::ChunkIterator& Cord::ChunkIterator::operator++() {
  1243. ABSL_HARDENING_ASSERT(bytes_remaining_ > 0 &&
  1244. "Attempted to iterate past `end()`");
  1245. assert(bytes_remaining_ >= current_chunk_.size());
  1246. bytes_remaining_ -= current_chunk_.size();
  1247. if (bytes_remaining_ > 0) {
  1248. if (btree_reader_) {
  1249. return AdvanceBtree();
  1250. } else {
  1251. assert(!current_chunk_.empty()); // Called on invalid iterator.
  1252. }
  1253. current_chunk_ = {};
  1254. }
  1255. return *this;
  1256. }
  1257. inline Cord::ChunkIterator Cord::ChunkIterator::operator++(int) {
  1258. ChunkIterator tmp(*this);
  1259. operator++();
  1260. return tmp;
  1261. }
  1262. inline bool Cord::ChunkIterator::operator==(const ChunkIterator& other) const {
  1263. return bytes_remaining_ == other.bytes_remaining_;
  1264. }
  1265. inline bool Cord::ChunkIterator::operator!=(const ChunkIterator& other) const {
  1266. return !(*this == other);
  1267. }
  1268. inline Cord::ChunkIterator::reference Cord::ChunkIterator::operator*() const {
  1269. ABSL_HARDENING_ASSERT(bytes_remaining_ != 0);
  1270. return current_chunk_;
  1271. }
  1272. inline Cord::ChunkIterator::pointer Cord::ChunkIterator::operator->() const {
  1273. ABSL_HARDENING_ASSERT(bytes_remaining_ != 0);
  1274. return &current_chunk_;
  1275. }
  1276. inline void Cord::ChunkIterator::RemoveChunkPrefix(size_t n) {
  1277. assert(n < current_chunk_.size());
  1278. current_chunk_.remove_prefix(n);
  1279. bytes_remaining_ -= n;
  1280. }
  1281. inline void Cord::ChunkIterator::AdvanceBytes(size_t n) {
  1282. assert(bytes_remaining_ >= n);
  1283. if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) {
  1284. RemoveChunkPrefix(n);
  1285. } else if (n != 0) {
  1286. if (btree_reader_) {
  1287. AdvanceBytesBtree(n);
  1288. } else {
  1289. bytes_remaining_ = 0;
  1290. }
  1291. }
  1292. }
  1293. inline Cord::ChunkIterator Cord::chunk_begin() const {
  1294. return ChunkIterator(this);
  1295. }
  1296. inline Cord::ChunkIterator Cord::chunk_end() const { return ChunkIterator(); }
  1297. inline Cord::ChunkIterator Cord::ChunkRange::begin() const {
  1298. return cord_->chunk_begin();
  1299. }
  1300. inline Cord::ChunkIterator Cord::ChunkRange::end() const {
  1301. return cord_->chunk_end();
  1302. }
  1303. inline Cord::ChunkRange Cord::Chunks() const { return ChunkRange(this); }
  1304. inline Cord::CharIterator& Cord::CharIterator::operator++() {
  1305. if (ABSL_PREDICT_TRUE(chunk_iterator_->size() > 1)) {
  1306. chunk_iterator_.RemoveChunkPrefix(1);
  1307. } else {
  1308. ++chunk_iterator_;
  1309. }
  1310. return *this;
  1311. }
  1312. inline Cord::CharIterator Cord::CharIterator::operator++(int) {
  1313. CharIterator tmp(*this);
  1314. operator++();
  1315. return tmp;
  1316. }
  1317. inline bool Cord::CharIterator::operator==(const CharIterator& other) const {
  1318. return chunk_iterator_ == other.chunk_iterator_;
  1319. }
  1320. inline bool Cord::CharIterator::operator!=(const CharIterator& other) const {
  1321. return !(*this == other);
  1322. }
  1323. inline Cord::CharIterator::reference Cord::CharIterator::operator*() const {
  1324. return *chunk_iterator_->data();
  1325. }
  1326. inline Cord::CharIterator::pointer Cord::CharIterator::operator->() const {
  1327. return chunk_iterator_->data();
  1328. }
  1329. inline Cord Cord::AdvanceAndRead(CharIterator* it, size_t n_bytes) {
  1330. assert(it != nullptr);
  1331. return it->chunk_iterator_.AdvanceAndReadBytes(n_bytes);
  1332. }
  1333. inline void Cord::Advance(CharIterator* it, size_t n_bytes) {
  1334. assert(it != nullptr);
  1335. it->chunk_iterator_.AdvanceBytes(n_bytes);
  1336. }
  1337. inline absl::string_view Cord::ChunkRemaining(const CharIterator& it) {
  1338. return *it.chunk_iterator_;
  1339. }
  1340. inline Cord::CharIterator Cord::char_begin() const {
  1341. return CharIterator(this);
  1342. }
  1343. inline Cord::CharIterator Cord::char_end() const { return CharIterator(); }
  1344. inline Cord::CharIterator Cord::CharRange::begin() const {
  1345. return cord_->char_begin();
  1346. }
  1347. inline Cord::CharIterator Cord::CharRange::end() const {
  1348. return cord_->char_end();
  1349. }
  1350. inline Cord::CharRange Cord::Chars() const { return CharRange(this); }
  1351. inline void Cord::ForEachChunk(
  1352. absl::FunctionRef<void(absl::string_view)> callback) const {
  1353. absl::cord_internal::CordRep* rep = contents_.tree();
  1354. if (rep == nullptr) {
  1355. callback(absl::string_view(contents_.data(), contents_.size()));
  1356. } else {
  1357. ForEachChunkAux(rep, callback);
  1358. }
  1359. }
  1360. // Nonmember Cord-to-Cord relational operators.
  1361. inline bool operator==(const Cord& lhs, const Cord& rhs) {
  1362. if (lhs.contents_.IsSame(rhs.contents_)) return true;
  1363. size_t rhs_size = rhs.size();
  1364. if (lhs.size() != rhs_size) return false;
  1365. return lhs.EqualsImpl(rhs, rhs_size);
  1366. }
  1367. inline bool operator!=(const Cord& x, const Cord& y) { return !(x == y); }
  1368. inline bool operator<(const Cord& x, const Cord& y) { return x.Compare(y) < 0; }
  1369. inline bool operator>(const Cord& x, const Cord& y) { return x.Compare(y) > 0; }
  1370. inline bool operator<=(const Cord& x, const Cord& y) {
  1371. return x.Compare(y) <= 0;
  1372. }
  1373. inline bool operator>=(const Cord& x, const Cord& y) {
  1374. return x.Compare(y) >= 0;
  1375. }
  1376. // Nonmember Cord-to-absl::string_view relational operators.
  1377. //
  1378. // Due to implicit conversions, these also enable comparisons of Cord with
  1379. // with std::string, ::string, and const char*.
  1380. inline bool operator==(const Cord& lhs, absl::string_view rhs) {
  1381. size_t lhs_size = lhs.size();
  1382. size_t rhs_size = rhs.size();
  1383. if (lhs_size != rhs_size) return false;
  1384. return lhs.EqualsImpl(rhs, rhs_size);
  1385. }
  1386. inline bool operator==(absl::string_view x, const Cord& y) { return y == x; }
  1387. inline bool operator!=(const Cord& x, absl::string_view y) { return !(x == y); }
  1388. inline bool operator!=(absl::string_view x, const Cord& y) { return !(x == y); }
  1389. inline bool operator<(const Cord& x, absl::string_view y) {
  1390. return x.Compare(y) < 0;
  1391. }
  1392. inline bool operator<(absl::string_view x, const Cord& y) {
  1393. return y.Compare(x) > 0;
  1394. }
  1395. inline bool operator>(const Cord& x, absl::string_view y) { return y < x; }
  1396. inline bool operator>(absl::string_view x, const Cord& y) { return y < x; }
  1397. inline bool operator<=(const Cord& x, absl::string_view y) { return !(y < x); }
  1398. inline bool operator<=(absl::string_view x, const Cord& y) { return !(y < x); }
  1399. inline bool operator>=(const Cord& x, absl::string_view y) { return !(x < y); }
  1400. inline bool operator>=(absl::string_view x, const Cord& y) { return !(x < y); }
  1401. // Some internals exposed to test code.
  1402. namespace strings_internal {
  1403. class CordTestAccess {
  1404. public:
  1405. static size_t FlatOverhead();
  1406. static size_t MaxFlatLength();
  1407. static size_t SizeofCordRepExternal();
  1408. static size_t SizeofCordRepSubstring();
  1409. static size_t FlatTagToLength(uint8_t tag);
  1410. static uint8_t LengthToTag(size_t s);
  1411. };
  1412. } // namespace strings_internal
  1413. ABSL_NAMESPACE_END
  1414. } // namespace absl
  1415. #endif // ABSL_STRINGS_CORD_H_