Stop requiring `absl::is_trivially_relocatable` for `Any` with
`inline_size == 0` to store the `Dependency<Handle, Manager>` inline.

Stop trying to replace an indirect call to `methods->move()` with `memcpy()`
when `inline_size == 0`.

This was not as effective as initially hoped because
`absl::is_trivially_relocatable` is too conservative. In particular it no longer
recognizes `std::unique_ptr`. This means that storing `std::unique_ptr` in `Any`
with `inline_size == 0` made an extra allocation.

The final nail in the coffin was realizing that `Dependency<Handle, Manager&&>`
is not `absl::is_trivially_relocatable`, unless `DependencyBase<Manager&&>` is
changed to store a pointer rather than a reference and to be assignable. This
means that `AnyRef` constructed from a temporary allocated the reference on the
heap.

Another issue is that it is possible that a future version of C++ will require
some special function instead of `memcpy()` for trivial relocation.

Unfortunately this optimization turned out to be too brittle.

Hence moving an `Any` will always involve an indirect call, but it will save
allocations. Saving allocations will be more predictable. As a side effect,
due to `Any` losing `ABSL_ATTRIBUTE_TRIVIAL_ABI`, it is destroyed by the caller
instead of by the callee.

Clang `std::__libcpp_is_trivially_relocatable`, which is what e.g. `std::vector`
uses for relocation, would be a partial solution. It recognizes classes with a
sufficiently simple definition, even if they have reference members and deleted
move assignment. And it has a mechanism for other types to opt in: it recognizes
types with `__trivially_relocatable` type alias, which describes conditions of
trivial relocatability, possibly in terms of
`std::__libcpp_is_trivially_relocatable` for their members. But these two
mechanisms do not automatically compose. It does not recognize a simple struct
with a `std::unique_ptr` member.

PiperOrigin-RevId: 807117537
4 files changed
tree: 81453c9f774c5e54f5d021010c25458172304bc8
  1. doc/
  2. python/
  3. riegeli/
  4. tf_dependency/
  5. .bazelrc
  6. configure
  7. CONTRIBUTING.md
  8. LICENSE
  9. MANIFEST.in
  10. MODULE.bazel
  11. README.md
README.md

Riegeli

Riegeli/records is a file format for storing a sequence of string records, typically serialized protocol buffers. It supports dense compression, fast decoding, seeking, detection and optional skipping of data corruption, filtering of proto message fields for even faster decoding, and parallel encoding.

See documentation.

Status

Riegeli file format will only change in a backward compatible way (i.e. future readers will understand current files, but current readers might not understand files using future features).

Riegeli C++ API might change in incompatible ways.