99 Commits

Author SHA1 Message Date
Derek Mauro
9346a86073 Fix typo in the documentation of absl::CopyCordToSpan()
PiperOrigin-RevId: 918529786
Change-Id: I1cff5ae9a9571a97ea38e2b83de1d661675363a0
2026-05-20 10:40:25 -07:00
Derek Mauro
638e17aedd Add absl::CopyCordToSpan()
PiperOrigin-RevId: 912247630
Change-Id: Ie5d2837c9b878e6094dce4d2ec7e60441a7c6bb7
2026-05-07 17:55:11 -07:00
Abseil Team
bd6adb86c2 Change abseil hardening assertions in the strings directory from macros to functions
This associates debug information with the assertion sites, allowing clearer stack-traces for assertion failures and better accounting of the performance overhead of assertions.

PiperOrigin-RevId: 910863016
Change-Id: Ic615a9eeb8ad4b3f8c035074df4ff8347190e5c7
2026-05-05 13:00:46 -07:00
Abseil Team
ed2114e8ff Stop using C++17 type traits polyfills
This will let us deprecate the declarations without triggering warnings in Abseil itself.

PiperOrigin-RevId: 894202105
Change-Id: I57bb2a1647be1fedf9b724a07042fd0f564ce074
2026-04-03 12:34:35 -07:00
Derek Mauro
5088cf5194 Cleanup the uses of the polyfills absl::any, absl::optional,
absl::variant, and related types

The corresponding headers are removed from cc files, but kept in
headers to prevent breakages from transitive dependencies.

PiperOrigin-RevId: 872421685
Change-Id: I867d4c3f7c9e422289c63816d44719b0530fb0a6
2026-02-19 08:53:17 -08:00
Abseil Team
90633b5020 Fix comment about releaser's operators in MakeCordFromExternal.
PiperOrigin-RevId: 871940822
Change-Id: I493f8e5e13de9b80f71b63d2ad8c96f649c0449f
2026-02-18 10:41:38 -08:00
Marcin Kowalczyk
7555c7e1ad Fix incorrect nullability annotation of absl::Cord::InlineRep::set_data().
It is called with `(nullptr, 0)` by `absl::Cord` constructor from
`absl::string_view(nullptr, 0)`.

The implementation works for `(nullptr, 0)`.

PiperOrigin-RevId: 802213857
Change-Id: Ibb9b9dae620262ebee8aa3347c4177e7a3da52c0
2025-09-02 11:04:13 -07:00
Vitaly Goldshteyn
fbb1d06795 Make combine_contiguous to mix length in a weak way by adding size << 24, so that we can avoid a separate mixing of size later. The empty range is mixing 0x57 byte.
It was also considered to add just `size` without transformation. But this causes collisions for small contiguous strings that may be quite a common case. So it is better to avoid additional disruptions for client code.

```
name                           old INSTRUCTIONS/op  new INSTRUCTIONS/op  delta
BM_latency_AbslHash_Int32        9.00 ± 0%            9.00 ± 0%     ~     (all samples are equal)
BM_latency_AbslHash_Int64        9.00 ± 0%            9.00 ± 0%     ~     (all samples are equal)
BM_latency_AbslHash_String3      32.0 ± 0%            34.0 ± 0%   +6.25%        (p=0.000 n=57+57)
BM_latency_AbslHash_String5      31.0 ± 5%            32.8 ± 5%   +6.00%        (p=0.000 n=57+57)
BM_latency_AbslHash_String9      28.8 ± 4%            30.2 ± 5%   +4.94%        (p=0.000 n=53+53)
BM_latency_AbslHash_String17     27.4 ± 3%            27.6 ± 4%   +0.64%        (p=0.032 n=53+52)
BM_latency_AbslHash_String33     32.8 ± 4%            32.5 ± 8%     ~           (p=0.079 n=51+53)
BM_latency_AbslHash_String65     55.9 ±14%            55.1 ±10%     ~           (p=0.288 n=52+51)
BM_latency_AbslHash_String257     122 ±11%             121 ±11%     ~           (p=0.432 n=50+55)

name                           old CYCLES/op        new CYCLES/op        delta
BM_latency_AbslHash_Int32        16.0 ± 2%            16.1 ± 4%     ~           (p=0.433 n=56+57)
BM_latency_AbslHash_Int64        16.4 ± 4%            16.5 ± 3%     ~           (p=0.076 n=56+46)
BM_latency_AbslHash_String3      22.6 ± 0%            21.0 ± 1%   -6.83%        (p=0.000 n=52+47)
BM_latency_AbslHash_String5      22.2 ± 5%            21.2 ± 4%   -4.53%        (p=0.000 n=54+56)
BM_latency_AbslHash_String9      22.1 ±11%            20.4 ± 5%   -7.72%        (p=0.000 n=51+55)
BM_latency_AbslHash_String17     21.4 ± 3%            19.6 ± 4%   -8.52%        (p=0.000 n=54+51)
BM_latency_AbslHash_String33     23.5 ± 4%            20.8 ± 7%  -11.42%        (p=0.000 n=53+54)
BM_latency_AbslHash_String65     28.6 ± 6%            27.0 ± 7%   -5.47%        (p=0.000 n=53+55)
BM_latency_AbslHash_String257    46.7 ± 9%            44.4 ±10%   -4.93%        (p=0.000 n=52+56)
```

PiperOrigin-RevId: 765281185
Change-Id: I0754877ca7eaa4d187390fe631ef407d379ccae7
2025-05-30 12:01:00 -07:00
Abseil Team
309adff2a5 Delete deprecated absl::Cord::Get and its remaining call sites.
PiperOrigin-RevId: 757900896
Change-Id: I0b56fcbcbd82d2decd1b59676a7af55d868be5a4
2025-05-12 13:57:28 -07:00
Vitaly Goldshteyn
7bf6d7918f Use weaker mixing for absl::Hash for types that mix their sizes.
When a container or a string is mixed, size is only supplementary data.
We are still mixing size to avoid hash expansion to be a suffix of one another.

Mixing is done by addition `size + Seed()`. `+ Seed()` is needed to make an empty string to change the hash state. We assume that `Seed()` is already loaded to some register. Addition would modify low bits that will be spread with data mixing later.

We considered the following optimization. Mix the size at the beginning in order to improve the dependency graph. Mixing would happen in parallel with reading strings data. It's not feasible because absl::Hash API requires that hash expansions can't be suffixes of each other.

```
name                           old CYCLES/op        new CYCLES/op        delta
BM_latency_AbslHash_String3      27.2 ± 0%            21.5 ± 0%  -21.08%        (p=0.000 n=52+52)
BM_latency_AbslHash_String5      28.1 ± 8%            22.3 ±11%  -20.70%        (p=0.000 n=57+57)
BM_latency_AbslHash_String9      27.7 ± 9%            22.2 ±17%  -19.77%        (p=0.000 n=56+57)
BM_latency_AbslHash_String17     25.9 ± 5%            21.2 ±23%  -18.02%        (p=0.000 n=57+54)
BM_latency_AbslHash_String33     28.0 ± 5%            22.5 ± 4%  -19.69%        (p=0.000 n=54+54)
BM_latency_AbslHash_String65     37.9 ± 8%            32.2 ±10%  -15.19%        (p=0.000 n=52+53)
BM_latency_AbslHash_String257    57.1 ± 8%            52.0 ±10%   -8.88%        (p=0.000 n=52+54)
```

PiperOrigin-RevId: 750151406
Change-Id: I2245bad4906960d9236bea671738a218a85eb1af
2025-04-22 05:26:01 -07:00
Abseil Team
03db88d0f5 Introduce absl::Cord::Distance()
PiperOrigin-RevId: 745245070
Change-Id: Idb7d63170cfc4b83786de8c4de85a3ae07e9105a
2025-04-08 12:25:30 -07:00
Abseil Team
d97663ee23 Automated Code Change
PiperOrigin-RevId: 744017203
Change-Id: I69b4418b306bdb5f89194bbcddaed9813e46ec6f
2025-04-04 11:43:03 -07:00
Abseil Team
1d508979fc Faster copy from inline Cords to inline Strings
PiperOrigin-RevId: 714061397
Change-Id: Iad41d5033d7a0f87a54cd97d636aa450e0d6b8b4
2025-01-10 08:28:05 -08:00
Martin Brænne
08850701d2 Remove CharIterator::operator->.
An `operator->` that doesn't return a record type doesn't really serve a useful
purpose, and it is not required by the iterator concepts. I haven't been able
to find any usage in non-test code, so I'm removing it.

Even though the `pointer` type alias is now not being used anywhere, I'm keeping
it because otherwise some standard libraries don't accept `CharIterator` when
passed to `std::string::apend()`, for example.

PiperOrigin-RevId: 659832167
Change-Id: I5de183a01009bfd71c8477f2023973075be8d860
2024-08-06 00:06:36 -07:00
Ikko Eltociear Ashimine
3cb4988999 PR #1720: Fix spelling mistake: occurrance -> occurrence
Imported from GitHub PR https://github.com/abseil/abseil-cpp/pull/1720

Merge a72c4bcc7b into 0598e582f6

Merging this change closes #1720

COPYBARA_INTEGRATE_REVIEW=https://github.com/abseil/abseil-cpp/pull/1720 from eltociear:patch-1 a72c4bcc7b
PiperOrigin-RevId: 653737423
Change-Id: I5638538d1b008942feba6dc6fc98dcdbf53653ef
2024-07-18 13:33:52 -07:00
Abseil Team
c98bd9c884 Three-way comparison spaceship <=> operators for Cord.
This is portable because cord already has `operator<` etc., which will be unaffected. This just allows C++ >= 20 users to explicitly call `operator<=>`.

PiperOrigin-RevId: 646951415
Change-Id: I1432e224bd5dc09b99d56a1d27e95078463adf45
2024-06-26 08:14:50 -07:00
Abseil Team
b85096e6ec Minor cleanup for absl::Cord
PiperOrigin-RevId: 626124196
Change-Id: I81a9e4c35d6456ab8cd3942f9c2452c70db90678
2024-04-18 13:00:44 -07:00
Abseil Team
6645f31412 Add absl::AppendCordToString
PiperOrigin-RevId: 626039936
Change-Id: I6e791363bab06d66029a8565c42d158a2fe176f0
2024-04-18 08:18:20 -07:00
Abseil Team
b59913e479 Add ABSL_ATTRIBUTE_LIFETIME_BOUND to Cord::Flatten/TryFlat
These were already on the declarations, but it seems like the definitions need them as well.

PiperOrigin-RevId: 621868985
Change-Id: I2595aae506924f8b1dad3b07efe1660ae0e4488e
2024-04-04 08:36:45 -07:00
Marcin Kowalczyk
86f3019430 Fix a bug in Cord::{Append,Prepend}(CordBuffer): call
`MaybeRemoveEmptyCrcNode()`. Otherwise appending a `CordBuffer` an empty Cord
with a CRC node crashes (`RemoveCrcNode()` which increases the refcount of a
nullptr child).

Cosmetics: in `Cord::InlineRep::AppendArray()`, return early for empty `src`
before removing the empty CRC node.
PiperOrigin-RevId: 619107278
Change-Id: I4f1bc6b75c662f4678c61e3ef310e8597d62e2e1
2024-03-26 01:44:07 -07:00
Matt Kulukundis
99f0b6d16f Switch rank structs to be consistent with written guidance in go/ranked-overloads
PiperOrigin-RevId: 605125821
Change-Id: I2ee260eaf283acafd80abfd2b7419a0e9f597a78
2024-02-07 16:03:39 -08:00
Martijn Vels
513a6f9399 Optimize Cord::Swap() for missed compiler optimization in clang.
PiperOrigin-RevId: 603342563
Change-Id: I1cd80103377f457770d5178dad8b56ae459cbd55
2024-02-01 05:38:02 -08:00
Dmitri Gribenko
55621d1af5 Add nullability annotations
PiperOrigin-RevId: 589842893
Change-Id: I9657761d1f71c665582406f278c6605f6d382f6d
2023-12-11 09:07:59 -08:00
Abseil Team
3abf3298b6 Fixing a comment to be correct with the current code.
PiperOrigin-RevId: 588530709
Change-Id: Iee28c7693a4802f11e13728e1c28febee8c8576f
2023-12-06 13:44:15 -08:00
Abseil Team
61ea5d253f Fixed a very small typo in the Cord::empty() docstring.
PiperOrigin-RevId: 582455513
Change-Id: Ic78d14d6dd748420a64e7026ec7f8b967bebbf42
2023-11-14 15:15:49 -08:00
Abseil Team
822e3244e4 Add AbslStringify() support to absl::Cord
PiperOrigin-RevId: 576149980
Change-Id: I0a7e3df7a01edc78ee5d15d8d8e82e7bbc5fc0f3
2023-10-24 08:33:49 -07:00
Abseil Team
5655528c41 Remove unused internal function InlineRep::empty() which has misleading semantics.
PiperOrigin-RevId: 565330231
Change-Id: I84f0e9065986bb592b5bfb196b3fc221feb14bc4
2023-09-14 04:34:14 -07:00
Martijn Vels
efb035a597 Remove CordRepRing experiment.
We have no intention to use it instead of the CordRepBtree implementation, so cleanup up and remove all code and references.

PiperOrigin-RevId: 563803813
Change-Id: I95a67318d0f722f3eb7ecdcc7b6c87e28f2e26dd
2023-09-08 11:19:54 -07:00
Abseil Team
17a3ac4bcc Implement Cord::Find() and Cord::Contains()
PiperOrigin-RevId: 557523229
Change-Id: I959c0b0b14a4a96bee396d4bc09b80328060287d
2023-08-16 10:09:41 -07:00
Abseil Team
baa0a5cd7a Add ATTRIBUTE_LIFETIME_BOUND to Cord iterator methods
PiperOrigin-RevId: 555515105
Change-Id: I00929a869880cddd932ed2a08adb8f762a582738
2023-08-10 09:06:15 -07:00
Dmitri Gribenko
49146ec1a3 Remove a doubled up "with"
PiperOrigin-RevId: 554934635
Change-Id: Ia666bc28ee8ee84c633f365312760996f0816ca7
2023-08-08 14:03:49 -07:00
Abseil Team
f850728a8a Add ATTRIBUTE_LIFETIME_BOUND to Cord::Flatten and TryFlat
PiperOrigin-RevId: 554898945
Change-Id: Id19acf5af56b1e7877cd73ac8420cf8e1a841b64
2023-08-08 12:03:36 -07:00
Dmitri Gribenko
a45b017770 Remove a reference to the global string type, which does not exist as a separate type anymore
PiperOrigin-RevId: 554462574
Change-Id: I749ae0308d76580a2264f35ee8df487da81e0f7b
2023-08-07 06:56:21 -07:00
Abseil Team
53fbcb883d Introduce a kTotalMorePrecise accounting mode for Cord::EstimatedMemoryUsage(). This mode avoids double-counting blocks that a Cord references more than once; otherwise it is similar to the existing kTotal mode.
There's no change to the existing kTotal or kFairShare accounting modes.

PiperOrigin-RevId: 544378591
Change-Id: I7b4ae55cd93d631194e59a9cd0ff07f47611219e
2023-06-29 09:26:57 -07:00
Vertexwahn
421a74dce4 Fix some spelling mistakes 2023-04-24 21:25:50 +02:00
Martijn Vels
52835439ca Refactor InlineData to allow for memory sanitizer changes step 2
PiperOrigin-RevId: 501074382
Change-Id: I26a59ee6452855685ffe89469c352e6384060f59
2023-01-10 13:08:25 -08:00
Martijn Vels
5169f3a45f Refactor InlineData to allow for memory sanitizer changes step 1
PiperOrigin-RevId: 500765473
Change-Id: Iaa3f9fdee6c9f4322bc8995b0d381cf1c8cb1349
2023-01-09 11:29:40 -08:00
Derek Mauro
ff5644bb34 Allow Cord to store chunked checksums
PiperOrigin-RevId: 494587777
Change-Id: I41504edca6fcf750d52602fa84a33bc7fe5fbb48
2022-12-11 16:44:18 -08:00
Derek Mauro
1db72eb03e Support empty Cords with an expected checksum
PiperOrigin-RevId: 484578104
Change-Id: Ie4be3e4de27dc28d88395e16fd075fb10ab7a302
2022-10-28 11:22:03 -07:00
Martijn Vels
ba78523573 Cleanup: SmallMemmove nullify should also be limited to 15 bytes
The current implementation correctly copies up to 15 bytes of data, but the nullify code clears up to 16 bytes, which was likely motivated by the assumption that the length indicator is always the last byte.

This changes limits the nullify to 15 bytes as well removing this layout specific assumption from cord.h, making future platform specific internal layout changes easier to land.

PiperOrigin-RevId: 477997741
Change-Id: Idcdfeca2a005139f97eafcc77111542d90b817af
2022-09-30 08:18:49 -07:00
Martijn Vels
92bc0b6b68 Cleanup: Move BitwiseCompare() to InlineData, and make it layout independent.
This removes layout specific details from InlineData from cord.h, making future platform specific internal layout changes easier to land.

PiperOrigin-RevId: 477869206
Change-Id: I1d417af47d7f04e34a98ba7b93ae591ece8f9151
2022-09-29 18:15:59 -07:00
Martijn Vels
cfa5dc7576 Cleanup some InlineData internal layout specific details from cord.h
This makes future platform specific internal layout changes easier to land.

PiperOrigin-RevId: 477843948
Change-Id: I4ca4fdea5e965261c029d08319aba0290721c227
2022-09-29 15:58:57 -07:00
Abseil Team
dce028bdce Documentation: Remove an obsolete note about the implementation of Cord.
PiperOrigin-RevId: 477587157
Change-Id: I4527b891222a011f8c1788387479bdc8e4a3bb94
2022-09-28 16:56:50 -07:00
Martijn Vels
6162604bee Internal Cleanup: removing unused internal function declaration.
PiperOrigin-RevId: 461616203
Change-Id: I4cf2e0738451a0471bb8341d9af003d271331fab
2022-07-18 07:38:05 -07:00
Martijn Vels
b707b6c179 Add GetCustomAppendBuffer method to absl::Cord
The Cord::GetCustomAppendBuffer() method provides the same functionality as Cord::GetAppendBuffer(), except that callers can specify a custom block size/limit if the method returns a newly allocated buffer.

In other words: Cord::GetAppendBuffer() defaults to CordBuffer::CreateWithDefaultLimit(), Cord::GetCustomAppendBuffer() defaults to CordBuffer::CreateWithCustomLimit().

PiperOrigin-RevId: 461231989
Change-Id: I5c03f31139d9b068feee1bea76d59e1c5e30ef07
2022-07-15 13:40:26 -07:00
Abseil Team
9431a83791 Fix several typos in comments.
PiperOrigin-RevId: 454185620
Change-Id: Ifdff33cec4bdd63f160a8d3c18f959ac2a3b6f25
2022-06-10 09:53:55 -07:00
Derek Mauro
48419595d3 Release absl::CordBuffer
absl::CordBuffer holds data for eventual inclusion within an existing
absl::Cord. CordBuffers are useful for building large Cords that may
require custom allocation of its associated memory, a pattern that is
common in zero-copy APIs.
PiperOrigin-RevId: 453212229
Change-Id: I6a8adc3a8d206691cb1b0001a9161e5080dd1c5f
2022-06-06 09:10:20 -07:00
Abseil Team
48f72c227b Fix typos.
PiperOrigin-RevId: 451434783
Change-Id: I572e77a67e18e8dd530bf0347c76863c9bb1946f
2022-05-27 11:13:07 -07:00
Abseil Team
5ed77665c4 Export of internal Abseil changes
--
d3b99682554d339c42556680f4d65f83226005e2 by Martijn Vels <mvels@google.com>:

Inline CycleClock code and remove branch for x86 CycleClockSource function

This CL removes the relaxed load for x86 as there is no acquire price to pay on x86. It inlines the UnscaledCycleClock::Now() which is a single RTDSC op for x86, and likewise inlines CycleClock::Now() for x86. The inlining should mostly have secondary benefits such as reducing spills on outlined calls.

LTO may eventually hoist these functions inline for the hotspots, but it doesn't hurt to default inline this for all builds and let the compiler decide on the first pass.

The perlab benchmark is noisy for the plain BM_Now, but the other benchmarks and the run on my local machine are clear.

------------- Local Benchy Benchmark
name                       old cpu/op  new cpu/op  delta
BM_Now                     3.41ns ± 1%  2.30ns ± 2%  -32.52%  (p=0.000 n=50+50)
BM_NowWithRegisterPresure  4.96ns ± 2%  4.19ns ± 2%  -15.57%  (p=0.000 n=56+55)
BM_NowWithCallback         3.30ns ± 2%  1.91ns ± 2%  -42.00%  (p=0.000 n=47+60)

------------- Perflab Benchy Benchmark
name                       old cpu/op  new cpu/op  delta
BM_Now                     8.20ns ±13%  4.32ns ±83%     ~     (p=0.413 n=4+5)
BM_NowWithRegisterPresure  7.91ns ± 1%  3.68ns ± 2%  -53.45%  (p=0.029 n=4+4)
BM_NowWithCallback         2.66ns ±13%  1.58ns ± 0%  -40.51%  (p=0.008 n=5+5)

PiperOrigin-RevId: 434474766
Change-Id: I991d987ae9233e50f09606c874055cf4c5a56300

--
b38330686a0af176a2679163e4d2fa1b90e2f667 by Laramie Leavitt <lar@google.com>:

Style, comment, and test updates

* Remove a redundant assert in uniform_real_distribution.
* Update comment in internal/generate_real.h
* Style updates to uniform_real_distribution_test
   mainly replacing TypeParam with real_type, using aliases for some limits, etc.
* Add a few more minor tests.

PiperOrigin-RevId: 433902174
Change-Id: Id75be8e24be2fb8f6aea05feec13e3ef320a7254

--
ab2da6047ff7f5dae3add3779fcddf73b03feabf by Abseil Team <absl-team@google.com>:

Remove declaration of method whose definition was previously removed.

PiperOrigin-RevId: 433507828
Change-Id: I0130b689813125250f7de2664e767e181f676c89

--
df0c87f4ec2c010691931c1bef9d26470a6e63a2 by Derek Mauro <dmauro@google.com>:

Internal change

PiperOrigin-RevId: 433289136
Change-Id: Iba157dc83ed99dafd17a2223d2504e49f8afbb9e

--
7445fa312f2995772900eda82467325b3401a17d by Martijn Vels <mvels@google.com>:

Optimize CordReader logic now that CONCAT is removed

This CL cleans up various helper functions and logic remaining from previous complex CONCAT logic that is no longer needed, simplifying the CordReader logic.

PiperOrigin-RevId: 433208748
Change-Id: I5f7b1883573c44e7c6f8af12c3cddbd197cb134d
GitOrigin-RevId: d3b99682554d339c42556680f4d65f83226005e2
2022-03-14 12:14:03 -04:00
Abseil Team
7f850b3167 Export of internal Abseil changes
--
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: Ie01ff3b9365fd45e5a55f858038552679f3180d3
2022-02-17 16:24:45 -05:00