)]}'
{
  "log": [
    {
      "commit": "ce3fdac74069253ebcffd732eceffa49268630b0",
      "tree": "17f1ddd7425b1979bc43f2637c9ff4a8c25d5aa1",
      "parents": [
        "de5f86e4ff0c7a27481625772390d561fed413d1"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed May 13 10:45:29 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed May 13 10:46:06 2026 +0200"
      },
      "message": "Cosmetic changes:\n* Pass compression dictionaries by value. They are represented as `SharedPtr`\n  or `std::vector` at the toplevel.\n* Fix `ZlibDictionary::set_data()`: do not convert through NUL-terminated\n  `const char*`.\n* Fix typos.\n\nPiperOrigin-RevId: 914720638\n"
    },
    {
      "commit": "de5f86e4ff0c7a27481625772390d561fed413d1",
      "tree": "0a5424de0bb7502b3701a30833af1dd7fea0fa44",
      "parents": [
        "81ebea9a2bdbc8401cfd107d59aed7c957448e06"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue May 12 19:41:39 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue May 12 20:05:42 2026 +0200"
      },
      "message": "Add defaulted copy/move constructors/assignment in `Options` classes.\nClean up how `Options` are passed.\n\nAs for other types, add copy constructor/assignment except for\n`Text{Parse,Print}MessageOptions` which are uncopyable, and add move\nconstructor/assignment except when copying is equivalent to moving.\nThis indicates when it is worth using `std::move()` for passing a parameter.\n\nTake `Options` parameters by value in most public functions. Exceptions:\n\n* `CFile{Reader,Writer}Base::Options`: they are movable more efficiently than\n  copyable due to a `std::string` member, but the relevant classes do not move\n  anything from them, so it is better to accept them by reference.\n\n* `{Fd,riegeli::tensorflow::File}{Reader,Writer}Base::Options`: for consistency.\n\nIn private functions, take `Options` parameters by value if they are cheap to\ncopy or move, otherwise by reference.\n\nPiperOrigin-RevId: 914362870\n"
    },
    {
      "commit": "81ebea9a2bdbc8401cfd107d59aed7c957448e06",
      "tree": "e7ee50de6cfda5540abbd5754a6db74e3b6273ee",
      "parents": [
        "12db77a887a06ca7c0ef14368ece09b9badf1081"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue May 12 16:04:31 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue May 12 16:05:09 2026 +0200"
      },
      "message": "Add `{,Dynamic,Unbound}FieldSkipper()`.\n\nIt becomes increasingly common to do nothing in a field handler besides tracking\nfield presence. It is annoying to write lambdas which takes the value, context\nparameters, and just returns `absl::OkStatus()`, and it feels uncertain whether\ntaking and ignoring the value is as efficient as it could (it almost is;\narranging for this to perform varint skipping instead of varint parsing is not\nworth complicating the field handler protocol).\n\nIn contrast to `DynamicFieldCopier()`, `DynamicFieldSkipper()` field predicate\nreturns `bool` instead of `std::optional\u003cint\u003e`, because returning a destination\nfield number is not applicable.\n\nIn contrast to `AnyFieldCopier()`, `AnyFieldSkipper()` is not provided because\nskipping remaining fields is the implicit default.\n\nIn contrast to `UnboundFieldCopier()`, `UnboundFieldSkipper()` can reuse the\nimplementation of `FieldSkipper()`, because it does not need a destination field\nnumber.\n\nAlso, make public `FieldAccepted` and `FieldAcceptedIf` for dynamic field\nhandlers which carry no extra information about the field being accepted. The\nfield handler protocol requires an API which fits `std::unique_ptr` and\n`std::optional` but not `bool`. These types are extracted from a private\nimplementation detail of `DynamicFieldHandler()`. They are used by\n`DynamicFieldSkipper()` too.\n\nAlso, fix embarrassing compile errors in `FieldHandlerWrapper()` for dynamic\nfield handlers.\n\nPiperOrigin-RevId: 914263217\n"
    },
    {
      "commit": "12db77a887a06ca7c0ef14368ece09b9badf1081",
      "tree": "dae7acaf2057a08e069597ab419ee8d6a830dc00",
      "parents": [
        "ebbfb8ac96b844cf73e83d8492bf9f7d1f8671aa"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue May 12 15:23:47 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue May 12 15:34:31 2026 +0200"
      },
      "message": "Do not hardcode the assumption that `ZSTD_CLEVEL_DEFAULT` is 3.\n\nWhile redefining the default compression level on the preprocessor level is not\na great idea and possibly nobody does this, respect that.\n\nPiperOrigin-RevId: 914248051\n"
    },
    {
      "commit": "ebbfb8ac96b844cf73e83d8492bf9f7d1f8671aa",
      "tree": "4bc3ad048bdd4cb6aa2d5226b1ec9f95ae6b3254",
      "parents": [
        "cf978da4b3719218a76899ec8d5a57defb477ca2"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri May 08 22:44:06 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri May 08 22:45:02 2026 +0200"
      },
      "message": "Replace `ABSL_ATTRIBUTE_UNUSED`:\n\n* With commented-out parameter name if it applies to a function parameter which\n  is never used. This is more idiomatic and shorter.\n\n* With `[[maybe_unused]]` otherwise, i.e. the parameter is used conditionally\n  (due to `if constexpr`, possibly empty variadic expansion, or `#if`) or the\n  name is something other than a function parameter.\n\nThe parameter name is still skipped altogether when the parameter is never used\nto pass a value but e.g. disambiguates overloads (`operator++(int)`,\n`std::in_place_t`), specifies a type where an explicit template parameter\nwould not work, or introduces template parameters through\n`std::index_sequence\u003cindices...\u003e`.\n\nReplace `ABSL_ATTRIBUTE_NORETURN` with `[[noreturn]]`. It is available since\nC++11.\n\nReplace `ABSL_FALLTHROUGH_INTENDED` with `[[fallthrough]]`. It is available\nsince C++17.\n\nAttribute macros for non-standard and thus non-portable attributes remain.\n\nPiperOrigin-RevId: 912676701\n"
    },
    {
      "commit": "cf978da4b3719218a76899ec8d5a57defb477ca2",
      "tree": "30061d56ad871b0747e974c705e379420fe43420",
      "parents": [
        "252a73a901f527db8714fdd47f805792be85fff6"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu May 07 15:49:39 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu May 07 15:50:45 2026 +0200"
      },
      "message": "Remove unused `serialized_message_internal.h` which was left after the old\nversion of `SerializedMessageReader`.\n\nPiperOrigin-RevId: 911936819\n"
    },
    {
      "commit": "252a73a901f527db8714fdd47f805792be85fff6",
      "tree": "59a0893db18098623ef8e1e2961b4e8680abbcae",
      "parents": [
        "58d6d0fd37deb5fe0b0b4c3a6aa8f00eaaf99000"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu May 07 09:18:20 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu May 07 09:20:00 2026 +0200"
      },
      "message": "In `ZstdWriterBase::Reset()`, reorder statements and fix the comment:\nit is `compression_dictionary_` which must be destroyed after `compressor_`,\nnot `dictionary_`.\n\nIn `ZstdWriterBase::Done()` reset `compression_dictionary_` to save memory.\n\nFix include ordering.\n\nClean up TensorFlow macros.\n\nPiperOrigin-RevId: 911784963\n"
    },
    {
      "commit": "58d6d0fd37deb5fe0b0b4c3a6aa8f00eaaf99000",
      "tree": "2ab9a93784d2d722539a2f5bfcb993665657c412",
      "parents": [
        "8caf038fe50bb21881e39522577e2a76ef75d04d"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 30 15:54:16 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 30 15:56:15 2026 +0200"
      },
      "message": "Add optimized conversions between `LinearSortedStringSet` and\n`ChunkedSortedStringSet`.\n\nPiperOrigin-RevId: 908146178\n"
    },
    {
      "commit": "8caf038fe50bb21881e39522577e2a76ef75d04d",
      "tree": "0b991f870845b34a47c8eeee89e28ca0f47a53db",
      "parents": [
        "7e51af3f89117a4934b678745291b677547b74b6"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 30 08:38:43 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 30 08:39:27 2026 +0200"
      },
      "message": "Let varint fields parse even if their value overflows the target integer or enum\ntype. The overflow might happen if the field used to have a wider type.\n\nThis aligns the semantics with native proto parsing. The cost is replacing a\nfailure with silent data loss. Native proto parsing accepts that, so we can too.\n\nPiperOrigin-RevId: 907980660\n"
    },
    {
      "commit": "7e51af3f89117a4934b678745291b677547b74b6",
      "tree": "7b9e2f9b6b98923e75a0010800a0ff14913cfacb",
      "parents": [
        "a6dc26b78e652c985cf8e174cd3074cc0f130413"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 29 11:29:27 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 29 11:31:11 2026 +0200"
      },
      "message": "Add support for tracking presence of fields, in the form of wrappers of field\nhandlers:\n* `FieldTracker()`\n* `UntilFieldFound()`\n* `UntilFieldFoundThenCancel()`\n* `OnlyFirstField()`\n* `OnlyFirstFieldThenCancel()`\n\nPiperOrigin-RevId: 907461623\n"
    },
    {
      "commit": "a6dc26b78e652c985cf8e174cd3074cc0f130413",
      "tree": "1a8fc550228954cbcde14867b3f77325ec63c7b8",
      "parents": [
        "487f389777e39dbbf7e45a02364d06f636505c54"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 28 18:33:10 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 28 18:39:48 2026 +0200"
      },
      "message": "Reword a comment. \"Each other element\" was a leftover from times where the first\nelement was represented differently.\n\nPiperOrigin-RevId: 907023293\n"
    },
    {
      "commit": "487f389777e39dbbf7e45a02364d06f636505c54",
      "tree": "fa07ae73b1211be0f2cc8de8ea5bf0cd310572db",
      "parents": [
        "641142865fdacf84e144d1635b6466213256ffc5"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 28 16:13:35 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 28 16:15:07 2026 +0200"
      },
      "message": "Add `{Linear,Chunked}SortedStringSet::last()`.\n\nDuring iteration, promise that the last element remains valid while the iterator\nmoves to `end()`. This is useful to implement `last()`.\n\nPiperOrigin-RevId: 906960653\n"
    },
    {
      "commit": "641142865fdacf84e144d1635b6466213256ffc5",
      "tree": "9c3ac2b381a4689cd6d215245b6d24cbe29debbc",
      "parents": [
        "46bda0e3680a5b00ccc270d0d3e19f93d5948355"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 28 16:12:41 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 28 16:14:49 2026 +0200"
      },
      "message": "Fix `riegeli::EstimateMemory()` of a `ChunkedSortedStringSet`: follow through\nthe internal `Chunk` struct.\n\nPiperOrigin-RevId: 906960359\n"
    },
    {
      "commit": "46bda0e3680a5b00ccc270d0d3e19f93d5948355",
      "tree": "efeeae135825d9fca2752411167a01875deaaa79",
      "parents": [
        "86ff59bfec52a05efda32d3b0820781b6aa6146d"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 28 08:58:00 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 28 08:58:54 2026 +0200"
      },
      "message": "Add support for writing packed repeated fields to a preallocated array rather\nthan to a `Writer`. This avoids a bounds check for each element.\n\nCosmetics: write bools with specialized code instead of as varints. This avoids\nrelying on the compiler to statically compute lengths of these varints, which is\nonly possible due to their limited range of [0..1].\nPiperOrigin-RevId: 906770507\n"
    },
    {
      "commit": "86ff59bfec52a05efda32d3b0820781b6aa6146d",
      "tree": "32d8afbe2068bea3da804db57ba2a553c827a897",
      "parents": [
        "bb1618a4a81321fd72429b0d56b7ad885d80e8a9"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 22 20:00:29 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 22 20:41:30 2026 +0200"
      },
      "message": "Fix bazel 9 compatibility:\n\n* Update google_cloud_cpp to 3.3.0 to avoid an incompatible version of\n  rules_foreign_cc which uses removed `--incompatible_use_toolchain_transition`\n\n* Force rules_go@0.60.0: even google_cloud_cpp@3.3.0 brings rules_go@0.58.3\n  which is still incompatible with bazel 9.\n\n* Update xz to 5.4.5.bcr.8 to avoid having to specify\n  `--incompatible_disallow_empty_glob\u003dfalse` (in bazel 8 and 9).\n\n* Update brotli, bzip2, and snappy, because old versions use `cc_library` or\n  `cc_binary` as builtins which are no longer supported.\n\n* Actually update all other dependencies to their current versions.\n  Some of them were already newer due to indirect dependencies, with warnings.\n\n  Except for abseil-py: on my machine 2.4.0 is broken (cannot find \"\u003cPython.h\u003e\",\n  in bazel 8 and 9).\n\n* Add 3.13 to supported Python versions.\n\nBuilding with `--copt\u003d-Wa,--gsframe\u003dno --host_copt\u003d-Wa,--gsframe\u003dno` might still\nbe needed (in bazel 8 and 9) because of issues in Abseil which were not fixed\nyet.\n\nPiperOrigin-RevId: 903936571\n"
    },
    {
      "commit": "bb1618a4a81321fd72429b0d56b7ad885d80e8a9",
      "tree": "4c34bc70bd0cb80d5236e0f9f029ea5918786c3e",
      "parents": [
        "f61405711ee8e7fefd6b518e1f67f52d26c9dd32"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sat Apr 18 20:01:35 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sat Apr 18 20:27:24 2026 +0200"
      },
      "message": "Add `ChunkedSortedStringSet::first()`.\n\n`LinearSortedStringSet::first()` already exists. The first element is stored\ncontiguously, so a simple accessor returning `absl::string_view` is possible.\n\nPiperOrigin-RevId: 901838348\n"
    },
    {
      "commit": "f61405711ee8e7fefd6b518e1f67f52d26c9dd32",
      "tree": "360686d4c9130ebe6f3753069b6d15cdb2e0eab1",
      "parents": [
        "b5f440780b424b9ce68d0dbf32b83e854207ea25"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 16 12:26:46 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Apr 17 11:50:45 2026 +0200"
      },
      "message": "Optimize `OptionalCompactString \u003d\u003d CompactString` like\n`CompactString \u003d\u003d CompactString` is optimized: check the whole representation\nfirst, so that short strings are compared as one word comparison, without\nextracting a variable length `absl::string_view` and comparing that.\n\nPiperOrigin-RevId: 900627004\n"
    },
    {
      "commit": "b5f440780b424b9ce68d0dbf32b83e854207ea25",
      "tree": "8788a0a8289fc682b17b878704afaa1b3f3a7190",
      "parents": [
        "5d154d1eac1044b01f31b6422b8a9551e10bb1e4"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 16 12:25:50 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Apr 17 11:50:28 2026 +0200"
      },
      "message": "Fix `With{Equal,Compare}` in C++17 for corner cases:\n\n1. Heterogeneous secondary comparisons (`!\u003d`, `\u003c`, `\u003e`, `\u003c\u003d`, and `\u003e\u003d`)\n   are not defined if the other type is also implemented using `WithEqual`\n   or `WithCompare`.\n\n2. Heterogeneous primary comparisons with swapped parameters (`\u003d\u003d` and\n   `RIEGELI_COMPARE`) are added only for types explicitly specified by\n   additional template parameters of `WithEqual` and `WithCompare`.\n\nThis avoids ambiguous overloads and cyclic template instantiations:\n\n1. If both parameter types consider swapping the parameters, but the types are\n   not comparable, then each definition is rewritten from the other one, and\n   their SFINAE constraints depend on each other.\n\n   This does not happen only if the code tries to compare incomparable values.\n   Due to how ADL works, a call to an unqualified function name with an argument\n   of type `A\u003cT\u003e` brings not only functions related to `A`, but also functions\n   related to `T`. The argument of type `A\u003cT\u003e` will not match the parameter\n   of type `T`, but the function template is instantiated earlier, trying to\n   compare `T` against `A\u003cT\u003e`.\n\n2. Automatic parameter swapping could only generate a constrained template\n   rather than overloads with concrete parameter types.\n\n   That converts parameters in the callee rather than in the caller, which leads\n   to different overload resolution.\n\n   That would create ambiguities in cases like `CompactString \u003d\u003d Chain`.\n   The parameters are not swapped because both types use `WithEqual`.\n   Intended `Chain \u003d\u003d absl::string_view` is not found because it requires\n   parameter swapping after all, since the converted parameter does not use\n   `WithEqual`.\n\nPiperOrigin-RevId: 900626664\n"
    },
    {
      "commit": "5d154d1eac1044b01f31b6422b8a9551e10bb1e4",
      "tree": "a7561c257c1bb747c9164f19857db592b6875a17",
      "parents": [
        "eb29aa6a92ff38818873c89f08c704037f6a4bf2"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 16 12:23:58 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Apr 17 11:50:09 2026 +0200"
      },
      "message": "Make conversion from `{String,Bytes,Path}Ref` to `absl::string_view` explicit.\nSame for conversion from `{Bytes,Path}Ref` to `StringRef`. Conversions in the\nother direction remain implicit.\n\nMutual implicit conversions are prone to ambiguities, e.g. in heterogeneous\ncalls to `\u003d\u003d`.\n\nComparisons are especially problematic, as subtleties of overload resolution\ndepend on whether secondary comparison operators are derived automatically\nin C++20 or emulated in C++17 with `WithEqual` and `WithCompare`. If primary\ncomparison operators have concrete parameter types, then C++20 provides\nsecondary comparison operators with the same parameter types, for which argument\nconversions happen in the caller, while C++17 emulataion provides templates for\nwhich argument conversions happen in the callee.\n\nTypes `StringRef` etc. are designed for function parameters. It is important\nthat they accept any suitable argument, i.e. conversions to them are important\nto be implicit. OTOH consuming these parameters can be less convenient, and\nconversions from them can be explicit.\n\nLet `BytesRef` and `PathRef` derive from `StringRefBase` extracted from\n`StringRef` rather than from `StringRef` itself. The latter would make\n`BytesRef` implicitly convertible to `StringRef`, while we prefer\nthe other direction: `BytesRef` accepts more types than `StringRef`, e.g.\n`Span\u003cconst char\u003e`, so `BytesRef` should accept `StringRef` instead of\nthe other way around.\n\nMake `CStringRef` convertible from types convertible to `std::string`, e.g.\n`StringInitializer`. This improves compatibility with `StringRef`.\n\nPolish constructors of `StringRef` etc.:\n\n* Accept view types by value. This lets `ABSL_ATTRIBUTE_LIFETIME_BOUND` apply\n  only to what the view is constructed from, but not to the view object itself.\n  The view can safely be a temporary. Also, this reduces template instantiations\n  in common usages.\n\n* Remove `ABSL_ATTRIBUTE_LIFETIME_BOUND` where the parameter reference is not\n  actually retained because its data have been just copied to `std::string`.\n\n* Constrain templates by types being convertible to `absl::string_view` rather\n  than to `StringRef` etc. The latter conversions may keep data in defaulted\n  arguments, which do not survive forwarding, so they should not be used inside\n  implementations of other conversions to view types.\n\nCoalesce comments about the constructors. A single comment states the goal of\nmultiple constructors, rather than details of the order of conversions and\nmaterialization by each constructor. The details are not that important,\nand the expectations about arguments are already stated in class comments.\n\nMake `BytesRef` comparable only against itself, and make `CompactString`\nand `OptionalCompactString` comparable against `absl::string_view` but not\n`BytesRef`. While this disallows direct comparisons between e.g. `CompactString`\nand `std::array\u003cchar, length\u003e`, this reduces ambiguities in cases like\n`CompactString \u003d\u003d StringRef`. Arbitrary types convertible to `BytesRef`\nare not necessarily comparable anyway, e.g. `std::string` against\n`std::array\u003cchar, length\u003e`, so `CompactString` does not need to cover that.\n\n`BytesRef` remains implicitly convertible both from and to\n`absl::Span\u003cconst char\u003e`. This is hard to avoid because `absl::Span\u003cconst char\u003e`\nis convertible from any type providing suitable `data()` and `size()`,\nwhich includes `BytesRef`.\n\n`BytesRef` cannot be reliably compared against `absl::Span\u003cconst char\u003e` in C++17\nmode. This is so because `absl::Span` provides a comparison against any type\nconvertible to `absl::Span`, which is ambiguous wrt. comparisons provided by\n`WithCompare\u003cBytesRef\u003e`. It is comparable in C++20 mode though, because overload\nresolution prefers templated operators provided by `Span` over converting `Span`\nto `BytesRef` on the caller side.\n\nPiperOrigin-RevId: 900626152\n"
    },
    {
      "commit": "eb29aa6a92ff38818873c89f08c704037f6a4bf2",
      "tree": "56b78dc68cca8ff0379c433e1e70c2f12f416c95",
      "parents": [
        "a0a8dac780d1e46224045ae2ddc9d81e1def83ca"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 16 11:45:02 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Apr 17 11:49:51 2026 +0200"
      },
      "message": "Make `riegeli::Reset(dest, args...)` an effective optimization of\n`dest \u003d T(args...)` for more types and patterns:\n\n* `riegeli::Reset(dest, std::in_place, args...)` → `dest.emplace(args...)`\n* `riegeli::Reset(dest, std::in_place_type\u003cType\u003e, args...)` →\n  `dest.emplace\u003cType\u003e(args...)`\n* `riegeli::Reset(dest, std::in_place_index\u003cindex\u003e, args...)` →\n  `dest.emplace\u003cindex\u003e(args...)`\n* `riegeli::Reset(dest)` → `dest.clear()` (`begin()` and `end()` must be\n  defined because this pattern would be risky for non-containers)\n* `riegeli::Reset(dest, args...)` → `dest.assign(args...)`\n  (`begin()` and `end()` must be defined)\n\nThis covers in particular `std::optional`, `std::variant`, `std::any`,\n`absl::InlinedVector`...\n\nDescribe some caveats when resetting may differ from assignment from a newly\nconstructed object.\n\nRemove overrides of `RiegeliReset()` which became redundant.\n\nPiperOrigin-RevId: 900610370\n"
    },
    {
      "commit": "a0a8dac780d1e46224045ae2ddc9d81e1def83ca",
      "tree": "b135ab89d3ed2d3611ba10590da5d8d778e5cdea",
      "parents": [
        "401f6cb01b48f18541e32618ca2e80666948057f"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 14 10:57:11 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 14 10:58:02 2026 +0200"
      },
      "message": "Qualify private `{Linear,Chunked}SortedStringSet::HashValue()` as const.\nIt is called from const `AbslHashValue()`.\n\nPiperOrigin-RevId: 899442381\n"
    },
    {
      "commit": "401f6cb01b48f18541e32618ca2e80666948057f",
      "tree": "a9e00f58eebdef82706d7c08d9a1b7f2273d0815",
      "parents": [
        "f0a5005c50947df9a0ce005b83dc767871941354"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 14 09:44:39 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 14 10:04:00 2026 +0200"
      },
      "message": "Derive from `With{Equal,Compare}` publicly, even though technically this does\nnot matter because they bring only friend functions.\n\nSkip explicit `public` in a struct.\n\nIn `HybridDirectMap::IteratorImpl`, make `operator\u003d\u003d` homogeneous for\nsimplicity. Heterogeneous comparison of iterators of different constness work\nby converting the arguments to a common type, which is simple enough to be\noptimizable.\n\nPiperOrigin-RevId: 899412745\n"
    },
    {
      "commit": "f0a5005c50947df9a0ce005b83dc767871941354",
      "tree": "e7bfcea5d0072ec598d7d4c07cea4196a25b0694",
      "parents": [
        "23b12cd2cfccfd5271ec56f5590053c88e4320f0"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Apr 10 15:33:38 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 14 10:03:41 2026 +0200"
      },
      "message": "Use more idiomatic `riegeli::Maker\u003cType\u003e(args...)` instead of\n`Initializer\u003cType\u003e(arg)` for specifying an initializer which constructs\nan object from the given arguments.\n\nPiperOrigin-RevId: 897661672\n"
    },
    {
      "commit": "23b12cd2cfccfd5271ec56f5590053c88e4320f0",
      "tree": "b46ce372d6efcb7e86596d23429f3fb602047496",
      "parents": [
        "cceff87ea7a7703e540eff1b185c9eaff8858203"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 09 19:05:49 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 09 19:06:26 2026 +0200"
      },
      "message": "Add `UnboundFieldCopier()` for registering field copiers with a\n`FieldHandlerMap`.\n\nPiperOrigin-RevId: 897171160\n"
    },
    {
      "commit": "cceff87ea7a7703e540eff1b185c9eaff8858203",
      "tree": "468078f6efc2b333acf61bc32caaeca8bc2bb21c",
      "parents": [
        "0d51945bce37e68c22afc7f35b8ffacba0b1d5b4"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 09 08:02:32 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 09 08:12:02 2026 +0200"
      },
      "message": "Simplify code by relying on the fact that `ABSL_USES_STD_STRING_VIEW` is always\ntrue nowadays: remove conditional handling of `std::string_view` as a separate\ntype, and assume that e.g. `std::string::append(std::string_view)` works.\n\n`string_view` continues to be spelled `absl::string_view` rather than\n`std::string_view` for compatibility with Google style.\n\nRemove an outdated comment at `StringRef`. It cannot be simply replaced with\n`absl::string_view` without breaking materializing a temporary `std::string`\nfrom e.g. `StringInitializer`.\n\nPiperOrigin-RevId: 896895786\n"
    },
    {
      "commit": "0d51945bce37e68c22afc7f35b8ffacba0b1d5b4",
      "tree": "6b977ceb36826c5b4933bf34f153226be4e51d43",
      "parents": [
        "a283a583a654a60b89f9f30e46649408a140ae5f"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 14:19:25 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 14:20:52 2026 +0200"
      },
      "message": "Reword a comment.\n\nPiperOrigin-RevId: 896436509\n"
    },
    {
      "commit": "a283a583a654a60b89f9f30e46649408a140ae5f",
      "tree": "702a67fbe186fe0f5d8ce6a371d7ec4618fb0a5a",
      "parents": [
        "b6cebdc128758e6127bf51e46eae35f945d97baa"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 12:21:34 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 12:45:56 2026 +0200"
      },
      "message": "Remove deprecated `RIEGELI_ASSERT_NOTNULL` and `RIEGELI_ASSERT_UNREACHABLE`\nmacros, no longer used.\n\nPiperOrigin-RevId: 896388278\n"
    },
    {
      "commit": "b6cebdc128758e6127bf51e46eae35f945d97baa",
      "tree": "f89d129fb0fef59163a62bf54ca5a64376255892",
      "parents": [
        "2567e5247b9ca04bf0a360dceb7f08ec1c6db788"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 12:09:34 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 12:45:41 2026 +0200"
      },
      "message": "Fix `SerializedMessage{,Backward}Writer` build `#if !__cpp_concepts`:\nremove defaulted template parameter from definition which was already present\nin the declaration.\n\nPiperOrigin-RevId: 896383147\n"
    },
    {
      "commit": "2567e5247b9ca04bf0a360dceb7f08ec1c6db788",
      "tree": "9ef4964c1535bd8ffc342c98e89edcc3827c9003",
      "parents": [
        "e2f818adb1f2ff4fdf98a97f46331998ed25fec5"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 09:51:45 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 12:45:25 2026 +0200"
      },
      "message": "Between `BZ2_bzDecompressEnd()` and `BZ2_bzDecompressInit()`, set `bzalloc`,\n`bzfree`, and `opaque` to `nullptr`.\n\nThis is not needed for `libbz2` but needed for `libbz2_rs_sys`.\n\nThe documentation implies that this might be needed. While there are no\nallowable actions after `BZ2_bzDecompressEnd()`, `BZ2_bzDecompressInit()`\naccepts an arbitrary `bz_stream`, as long as `bzalloc`, `bzfree`, and `opaque`\nare set, possibly to `nullptr`.\n\nPiperOrigin-RevId: 896323110\n"
    },
    {
      "commit": "e2f818adb1f2ff4fdf98a97f46331998ed25fec5",
      "tree": "1be271da18ff728ae92fae19a4a7338a0369d539",
      "parents": [
        "b51b787ee39470084df5a4327862abfcdd19cc82"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 07:12:46 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Apr 08 12:45:09 2026 +0200"
      },
      "message": "Add support for optimizing reading packed repeated fields.\n\nThis is not used automatically for now.\n\nPiperOrigin-RevId: 896261060\n"
    },
    {
      "commit": "b51b787ee39470084df5a4327862abfcdd19cc82",
      "tree": "2dcb243238c1bbb52d20e27ddd4cd3e82fb73ac1",
      "parents": [
        "387f369d7dd59b6924d9ab6727cafb6c3960bf83"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 07 09:46:20 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 07 09:47:01 2026 +0200"
      },
      "message": "Allow overriding the default `HybridDirectTraits` for the given `Key` type by\ndefining a free function `friend RawKey RiegeliHybridDirectToRawKey(Key key)`,\nand optionally also\n`friend Key RiegeliHybridDirectFromRawKey(RawKey raw_key, Key*)`.\n\nThis avoids having to explicitly specify the traits each time a\n`HybridDirectMap` with that key type is used.\n\nAlso, change `expected_min_key` type from `Key` to `auto`. This allows to define\n`RiegeliHybridDirectToRawKey()` for key types which are not suitable as a\nnon-type template parameter.\n\nPiperOrigin-RevId: 895726185\n"
    },
    {
      "commit": "387f369d7dd59b6924d9ab6727cafb6c3960bf83",
      "tree": "7e5cd85f85ae07f82d14860729c22833b8c42a33",
      "parents": [
        "0dede994833aa5a992db91a79dd9c7a4ea33044e"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 07 09:39:40 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 07 09:40:41 2026 +0200"
      },
      "message": "Optimize `StringWriter` and `ResizableWriter` to avoid resizing to the whole\ncapacity if it is much larger than currently needed.\n\nResizing proceeds at most to twice the current size each time.\n\nChange the traits protocol of `ResizableWriter`: replace `GrowToCapacity()`\nwith `GrowUnderCapacity()`. It takes the new size as a parameter, and indicates\nwhether growing without reallocation was possible.\n\nInvariants of `StringWriter` are changed to match `ResizableWriter` more\nclosely: even if the secondary buffer is used, the string can have uninitialized\nspace appended.\n\nA difference between invariants of `StringWriter` and `ResizableWriter` remains:\n`StringWriter` has functions which resize the string as a side effect of\nappending a `Chain` (including the secondary buffer), `Cord`, `ExternalRef`, or\n`ByteFill`. `ResizableWriter` is simpler but less efficient by not having these\ncombined functions, because otherwise traits would need to have several new\nfunctions, one for each type being appended.\n\nAs before, if the initial string is not empty but `set_append(true)` is not\nrequested, then the original contents are utilized as the new space without\nclearing, avoiding filling them with zeros. This means that it is more efficient\nto let `StringWriter` clear the string than to clear it explicitly before\ncreating the `StringWriter`.\n\nMinor changes:\n\n* Override `WriteSlow(absl::string_view)`. In the case of `StringWriter`,\n  this can be more efficient than the default implementation in terms of\n  `PushSlow()`, by resizing as a side effect of appending. In the case of\n  `{String,Resizable}Writer`, this avoids forced resizing if data follow the\n  current position, because there is no need to make them available for partial\n  overwriting, because the whole buffer will be overwritten immediately.\n\n* Call `ResizableTraits::Grow()` only if the existing size is insufficient.\n  Move the responsibility of that check from implementations of this function\n  to their caller.\n\n* During `ResizableWriter` initialization, set buffer pointers to existing\n  contents eagerly, instead of leaving buffer pointers unset and waiting for\n  an operation like `ResizableWriterGrowDestAndMakeBuffer()` to set them.\n\nPiperOrigin-RevId: 895723423\n"
    },
    {
      "commit": "0dede994833aa5a992db91a79dd9c7a4ea33044e",
      "tree": "9e94e583da3ce626450f6afe785c4f315529fefe",
      "parents": [
        "28afd1ba846ea7469ade17b1f9a6e47f40385a7c"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 07 09:03:39 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Apr 07 09:36:22 2026 +0200"
      },
      "message": "Remove unused functions of a private class:\n`Chain::RawBlock::Can{Append,Prepend}MovingData()`.\n\nPiperOrigin-RevId: 895707819\n"
    },
    {
      "commit": "28afd1ba846ea7469ade17b1f9a6e47f40385a7c",
      "tree": "7c2365850f29524fbcd11a7e88b9a11cc96f18bc",
      "parents": [
        "c95c3747b8bfeec036ce5830af7c5e03d6e99490"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Apr 03 11:29:10 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Apr 03 11:30:39 2026 +0200"
      },
      "message": "Use more concise `UnsignedClamp()` instead of a combination of `UnsignedMax()`\nwith `UnsignedMin()`.\n\nPiperOrigin-RevId: 893969157\n"
    },
    {
      "commit": "c95c3747b8bfeec036ce5830af7c5e03d6e99490",
      "tree": "a07b511fbb3401339011a2806ee2a6472594b72f",
      "parents": [
        "fc37128e99f75fe94e027ca4542d0c07a9a0b312"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 02 21:35:07 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Apr 02 23:37:08 2026 +0200"
      },
      "message": "Fix spelling of the include guard.\n\nPiperOrigin-RevId: 893643675\n"
    },
    {
      "commit": "fc37128e99f75fe94e027ca4542d0c07a9a0b312",
      "tree": "e1f9343a7e1b64d20b72c667f625c722b37fa991",
      "parents": [
        "f56a831267862161530e124e45648013b0e95186"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 31 09:56:14 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 31 09:57:02 2026 +0200"
      },
      "message": "Fix `uint32_t` integer overflow in `TransposeDecoder` state machine resize.\n\nAlso, convert `state_machine_size` to `size_t` explicitly rather than implicitly\nwhen it is used as `size_t`, even without addition, to remind that it has a\ndifferent type.\n\nThis was reported by https://github.com/google/riegeli/pull/38. Thank you!\n\nPiperOrigin-RevId: 892165540\n"
    },
    {
      "commit": "f56a831267862161530e124e45648013b0e95186",
      "tree": "ef881551354d68d414c763af8df378b3f4f225cb",
      "parents": [
        "aaad107c6f9a7876e16c72eba072125eafab0326"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 30 10:48:35 2026 +0200"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 30 10:52:07 2026 +0200"
      },
      "message": "In `HybridDirect{Map,Set}`, if the distribution of keys is so unfortunate that\nall keys are too large for the array, no lookup hits can be optimized. In that\ncase, do not allocate the array full of absent keys to save memory, at the cost\nof not optimizing any lookup misses.\n\nPolish comments.\n\nPiperOrigin-RevId: 891579337\n"
    },
    {
      "commit": "aaad107c6f9a7876e16c72eba072125eafab0326",
      "tree": "405bb05d40c58304f5a9171d5cd2d46980990479",
      "parents": [
        "d1622e72e1034c8f56f143c592b3364722b5b80e"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 27 11:15:10 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 27 11:16:57 2026 +0100"
      },
      "message": "Support building `HybridDirect{Map,Set}` from key projection and value\nprojection applied to elements of C++20 `std::ranges::views::iota`,\nwithout actually using `std::ranges`.\n\nThis is another way to avoid materializing a source sequence or map.\n\nCosmetics: change the spelling, projectible → projectable. This is apparently\nmore common.\nPiperOrigin-RevId: 890346744\n"
    },
    {
      "commit": "d1622e72e1034c8f56f143c592b3364722b5b80e",
      "tree": "d00c1352b2bc01b0a5e4a0d3888690fd0e6fd260",
      "parents": [
        "208c9faccab449ad567ee01cee666e43496679a7"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 27 10:51:13 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 27 10:52:36 2026 +0100"
      },
      "message": "Add `HybridDirectSet` based on `HybridDirectMap`.\n\nPiperOrigin-RevId: 890337057\n"
    },
    {
      "commit": "208c9faccab449ad567ee01cee666e43496679a7",
      "tree": "8123577f5c74a6150b084e500f2046dbd97caf9f",
      "parents": [
        "7268d9c2f8b5ec46b53a661032b2cb9410cef88a"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 15:59:45 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 16:01:06 2026 +0100"
      },
      "message": "Move `RIEGELI_ASSUME_EQ(member_, nullptr)` after an allocation, just before\nassignment.\n\nThis correctly allows the compiler to skip generating code for deleting the old\narray. The previous variant was ineffective: the compiler could not determine\nthat allocation and possible initialization cannot make the pointer non-null.\n\nPiperOrigin-RevId: 889843780\n"
    },
    {
      "commit": "7268d9c2f8b5ec46b53a661032b2cb9410cef88a",
      "tree": "9753b10a426bdd4559de214fc9cbd978d52a3cc5",
      "parents": [
        "c20e22af19d02c06837bac18cc3bff0fb3f53241"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 15:45:28 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 15:47:00 2026 +0100"
      },
      "message": "Deriving from `Conditionally{Constructible,Assignable}` publicly rather than\nprivately is more natural after all. I was mistaken before.\n\nThey define public members. Special member functions have peculiar defaulting\nrules so the derived class has them public either way, but the principle stands.\n\nPiperOrigin-RevId: 889836994\n"
    },
    {
      "commit": "c20e22af19d02c06837bac18cc3bff0fb3f53241",
      "tree": "81d7d9a9b4b4400b85dea5f1d11ef74ae6def7a1",
      "parents": [
        "662a28b4f57fdc40b3281c8550fce7267668d888"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 15:30:44 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 15:32:25 2026 +0100"
      },
      "message": "Allow duplicate keys in `HybridDirectMap`. The first value wins.\n\nThis allows using it for untrusted data.\n\nThis required surprisingly subtle implementation changes, since `SizedArray`\nmight now get fewer entries than initially declared.\n\nPiperOrigin-RevId: 889829968\n"
    },
    {
      "commit": "662a28b4f57fdc40b3281c8550fce7267668d888",
      "tree": "f96ead3e73cd448c79df00431ed3f2b2a8b8c07e",
      "parents": [
        "1d785227c6112837f1ad6de39b35d8408c25bcd6"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 13:22:51 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 13:24:01 2026 +0100"
      },
      "message": "Let `HybridDirectMap` API look more like a typical associative container.\n\nAdd `iterator` and `const_iterator`.\n\nRename `Find()` returning a pointer to `FindOrNull()`. Add `find()` returning an\niterator. The performance of `find()` and `FindOrNull()` is comparable, but if\nthe semantics of `FindOrNull()` is needed (such as in `FieldHandlerMap`), then\nthe dedicated function is more readable and can be faster.\n\nAdd `FindOrDefault()`, `contains()`, `at()`, `empty()`, `size()`, `{,c}begin()`,\n`{,c}end()`, and `operator\u003d\u003d`.\n\nPiperOrigin-RevId: 889778092\n"
    },
    {
      "commit": "1d785227c6112837f1ad6de39b35d8408c25bcd6",
      "tree": "6134586d2205ba1607c1c43d1458ee94d3c30db1",
      "parents": [
        "3a7cf2ed205a1930f85c6f7874f2a54b330f8361"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 11:10:15 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 11:11:46 2026 +0100"
      },
      "message": "Add non-const `HybridDirectMap::Find()`.\n\nPiperOrigin-RevId: 889725953\n"
    },
    {
      "commit": "3a7cf2ed205a1930f85c6f7874f2a54b330f8361",
      "tree": "cd28aad170b35e81917f5049bf48577550ee2458",
      "parents": [
        "7bc3daecf211bb2389c7dc2348c50fa433cb1c38"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 09:55:57 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 09:57:06 2026 +0100"
      },
      "message": "Support `HybridDirectMap` building with projection of keys and values from the\nsource iterable.\n\nThis is especially useful in the context of `HybridDirectMap` because it does\nnot support incremental modification. A projection cannot be applied during\nan insertion loop.\n\nPiperOrigin-RevId: 889697962\n"
    },
    {
      "commit": "7bc3daecf211bb2389c7dc2348c50fa433cb1c38",
      "tree": "12fb95f0fdd6b4ccbd8f38c1eb6672f82342bda4",
      "parents": [
        "3e6fa6c68783255cadc38c87fbb07b3fd0ef9b6f"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 09:16:40 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 09:17:45 2026 +0100"
      },
      "message": "Change how `HybridDirectMap` is parameterized.\n\nSpecify `direct_capacity` as a runtime constructor parameter rather than a\ntemplate parameter.\n\nReplace `expected_min_key` template parameter with `Traits`. This generalizes\nkeys from an integer type to a type with a translation to an unsigned integer\ntype. `SlowMap` is indexed by translated keys to avoid imposing a hashing\nrequirement on the key type.\n\nSplit private headers `hybrid_direct_common.h` (reexported) and\n`hybrid_direct_internal.h` (not reexported) out of `hybrid_direct_map.h`\nto keep the main public header focused.\n\nPiperOrigin-RevId: 889683578\n"
    },
    {
      "commit": "3e6fa6c68783255cadc38c87fbb07b3fd0ef9b6f",
      "tree": "c6088934a635eb8b54721c38f76def676f56b2f7",
      "parents": [
        "57b8ef4044a468f68d09ffc3003eba34b235b543"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 08:39:19 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 26 08:40:39 2026 +0100"
      },
      "message": "Rename `SmallIntMap` → `HybridDirectMap`.\n\nThe old name could be misleading: it is a map of small ints, not a small map of\nints. The new name gives a stronger hint about the implementation strategy and\nthus about properties.\n\n`Int` in the name should be avoided because keys will be generalized to a type\nwith a translation to an unsigned integer type.\n\n`Hash` in the name should be avoided because the fact that the fallback is\na hash map is not very interesting, although this not planned to be generalized.\n\nRename internals: `SmallMap` → `DirectMap`, `LargeMap` → `SlowMap`.\n\nUse `hybrid_direct_internal` instead of `hybrid_direct_map_internal` though,\nanticipating a `HybridDirectSet`.\n\nPiperOrigin-RevId: 889668812\n"
    },
    {
      "commit": "57b8ef4044a468f68d09ffc3003eba34b235b543",
      "tree": "e8f39e9b3b8a44e3f2e461bae062aa343f5ff3e7",
      "parents": [
        "58f7aeb883a16d537db653ff90cabfc28c98c6f7"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 24 10:44:10 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 24 10:51:27 2026 +0100"
      },
      "message": "Move `VectorResizableTraits` from `resizable_writer.h` to an internal namespace\nin `vector_writer.h`.\n\nPiperOrigin-RevId: 888546224\n"
    },
    {
      "commit": "58f7aeb883a16d537db653ff90cabfc28c98c6f7",
      "tree": "eec99d9a374d64a5f485c60f3fedd85948e50515",
      "parents": [
        "05a0603f8c1fd410c9b25b6802a4e1512e430550"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 23 11:46:04 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 23 11:48:59 2026 +0100"
      },
      "message": "Remove deprecated `ChunkWriter::PadToBlockBoundary()`, no longer used.\n\nPiperOrigin-RevId: 888004188\n"
    },
    {
      "commit": "05a0603f8c1fd410c9b25b6802a4e1512e430550",
      "tree": "ff6d25bcf19314d4404a21ecb11f7a917b443cbf",
      "parents": [
        "0dd662b0471c8345fadb775b29571af2d99f080a"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 20 14:35:48 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 20 14:36:26 2026 +0100"
      },
      "message": "Reword comments about `SharedPtr`, `IntrusiveSharedPtr`, and `RefCount`.\n\nPiperOrigin-RevId: 886754514\n"
    },
    {
      "commit": "0dd662b0471c8345fadb775b29571af2d99f080a",
      "tree": "4420f2a45aa214cffe1483c40659d22da43be151",
      "parents": [
        "036aae5859b0ab7ce147a487381c005f762a9f64"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 19 10:51:10 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 19 10:51:55 2026 +0100"
      },
      "message": "Replace `CopyingFieldHandler` with:\n\n* `FieldCopier()` for copying a single field.\n\n* `DynamicFieldCopier()` for copying a single field or multiple fields\n  determined at runtime.\n\n* `AnyFieldCopier()` for copying any field, like `CopyingFieldHandler` before,\n  but taking any `Context...`.\n\nPiperOrigin-RevId: 886062533\n"
    },
    {
      "commit": "036aae5859b0ab7ce147a487381c005f762a9f64",
      "tree": "4f46ce2bce50784a979253d20aebce0a1c4e9141",
      "parents": [
        "4a02339d87e13c284e19eefc889b1127e92fa373"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 19 09:54:59 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 19 10:04:54 2026 +0100"
      },
      "message": "Remove deprecated Endian reading/writing function name aliases.\n\nPiperOrigin-RevId: 886040251\n"
    },
    {
      "commit": "4a02339d87e13c284e19eefc889b1127e92fa373",
      "tree": "4a50cea4a336c404248326cff3d4695ec160cbfd",
      "parents": [
        "ebc6a3a136705975d37f1c99f40aeef38aa3d105"
      ],
      "author": {
        "name": "Compression Team",
        "email": "noreply@google.com",
        "time": "Wed Mar 18 23:24:36 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Mar 18 23:25:23 2026 +0100"
      },
      "message": "Depend on granular TensorFlow targets.\n\nThe open source build of Riegeli/TensorFlow is still broken because TensorFlow\ndoes not support bzlmod yet.\n\nPiperOrigin-RevId: 885816369\n"
    },
    {
      "commit": "ebc6a3a136705975d37f1c99f40aeef38aa3d105",
      "tree": "83388f17b4bbc86dc93d1e15ad392d46f2d8331c",
      "parents": [
        "d3d3f0a0f7ed19e045f4c6dd7618c3c40de1cac1"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 17 22:39:06 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 17 22:40:03 2026 +0100"
      },
      "message": "In `SerializedMessage{,Backward}Writer`, rename `WriteSerializedMessage()`\nto an overload of `WriteString()`.\n\nExclude message objects from the regular stringifying `WriteString()` because\nthey are stringified in the text format, which is rarely intended as a field\nvalue. A separate overload serializes a message object in the binary format.\n\nPiperOrigin-RevId: 885216863\n"
    },
    {
      "commit": "d3d3f0a0f7ed19e045f4c6dd7618c3c40de1cac1",
      "tree": "2664e6c7c780cabbf39faaaf466892ed07c9fab6",
      "parents": [
        "fae0dd9b7b21a9b216cbe88f0a938b4c3afe2977"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 17 11:32:21 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 17 11:51:32 2026 +0100"
      },
      "message": "Add `Write{Little,Big}Endians()` writing to `BackwardWriter`.\n\nThey were missing, but they will now have a use.\n\nPiperOrigin-RevId: 884922436\n"
    },
    {
      "commit": "fae0dd9b7b21a9b216cbe88f0a938b4c3afe2977",
      "tree": "d2d9053f6e81ec3dd5cd94d05bb3401d7f280fbf",
      "parents": [
        "6c8841bf0e585b3ec042bec6c16d294c9a9b20d6"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 17 11:31:01 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 17 11:51:16 2026 +0100"
      },
      "message": "Reduce code duplication in Endian reading and writing.\n\nThis was not done before because the initial design used overloaded function\nnames instead of templates.\n\nPiperOrigin-RevId: 884921783\n"
    },
    {
      "commit": "6c8841bf0e585b3ec042bec6c16d294c9a9b20d6",
      "tree": "9f60eca691355e33ba873c9bed4a639bfffde375",
      "parents": [
        "b405223db8ea29cc89e1ef1290cd48089471cff2"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 16 20:20:13 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 16 20:21:18 2026 +0100"
      },
      "message": "Make `IteratorType` and `IteratorTypeT` public (this used to be `IteratorT`).\n\nThis will have usages after all.\n\nPiperOrigin-RevId: 884579090\n"
    },
    {
      "commit": "b405223db8ea29cc89e1ef1290cd48089471cff2",
      "tree": "565ce724ba6b09adc613e2d2e631c3e418494b07",
      "parents": [
        "103acbce3b58f8fba35044c5dc888184393aa6ba"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 16 19:27:16 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 16 20:21:04 2026 +0100"
      },
      "message": "Add copy constructor and assignment to `SmallIntMap`.\n\nIt was weird that it was copy-constructible from all maps with the same type\nexcept for the same type.\n\nPiperOrigin-RevId: 884551507\n"
    },
    {
      "commit": "103acbce3b58f8fba35044c5dc888184393aa6ba",
      "tree": "354476fbc29fafb2301fdec58f7518249897bdab",
      "parents": [
        "e9b1b680d42275b1f1aac44887b7a6691f997fa6"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 16 19:26:46 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Mar 16 20:20:48 2026 +0100"
      },
      "message": "Rework conditional disabling of copy/move constructor/assignment:\n\n* Replace `ConditionallyCopyable` with separate `ConditionallyConstructible`\n  and `ConditionallyAssignable`, which can separately disable copying and\n  moving (moving \u003d copying by default).\n\n* Extend `ConditionallyAssignable` so that it can separately disable copying and\n  moving.\n\n* Remove `CopyableLike`. It can be expressed using `ConditionallyConstructible`\n  and `ConditionallyAssignable`.\n\nThis is more verbose but also more explicit. This encourages more careful\nthinking which operations are actually depended on, e.g. copy assignment of\nan object holding a `T` might be implemented using copy construction of `T`,\nwhile move assignment might be present unconditionally.\n\nDocument some purposes of `ConditionallyCopyable` and `ConditionallyAssignable`.\n\nPrefer deriving from them privately. Defaulted special member functions already\ndepend on private members, this is an extension of that.\n\nPiperOrigin-RevId: 884551257\n"
    },
    {
      "commit": "e9b1b680d42275b1f1aac44887b7a6691f997fa6",
      "tree": "1edc12641a496ebaebbe73416b92033b090949f8",
      "parents": [
        "9cb4ad4286bc36136652f895ab61b61afac8df64"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sun Mar 15 14:56:24 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sun Mar 15 14:57:26 2026 +0100"
      },
      "message": "Pack `small_values_` and `num_small_values_` into a single object, implemented\nwith a `std::unique_ptr` with a deleter.\n\nThis reduces invariants across member variables, allows to use sized delete,\nand allows defaulting the move constructor and assignment of `SmallIntMap`.\n\nPiperOrigin-RevId: 883983726\n"
    },
    {
      "commit": "9cb4ad4286bc36136652f895ab61b61afac8df64",
      "tree": "f3eae84185a2c706c6d1d3984fdb07e9b3ead4d9",
      "parents": [
        "464c6ff9cc1d3d7689858bd570059cbdeea22d79"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sun Mar 15 14:54:52 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sun Mar 15 14:57:02 2026 +0100"
      },
      "message": "Construct `SmallIntMap` from an iterable rather than from iterators and size.\n\nThis conditionally applies `std::make_move_iterator` at the right place: only\nfor extracting the value (which happens once per value), not for extracting the\nkey (which happens multiple times).\n\nPiperOrigin-RevId: 883983292\n"
    },
    {
      "commit": "464c6ff9cc1d3d7689858bd570059cbdeea22d79",
      "tree": "aa18613ca0fd6991fd6abdb2eae6849620422049",
      "parents": [
        "f68e6e1f1bb216c17c9575693d25cbe0c5cf7e34"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 13 15:27:54 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 13 15:28:43 2026 +0100"
      },
      "message": "Factor out `ArrowProxy`, a common implementation of `iterator::pointer` when\n`iterator::reference` is not a true reference.\n\nMove `ReferencePair` from `csv_record.h` to `iterable.h`. It is not specific for\n`CsvRecord` but applicable to any map type with separate storage for keys and\nvalues.\n\nMinor changes to `{Linear,Chunked}SortedStringSet` iterators to satisfy C++20\nrequirements:\n\n* Make `ChunkedSortedStringSet` an alias to an internal `IteratorImpl`\n  instantiation instead of deriving from it. This makes return types correct.\n\n* Let\n  `{Linear,Chunked}SortedStringSet::NextInsertIterator::reference::operator\u003d`\n  be const (this is shallow), as required by `std::indirectly_writable`.\n\nPiperOrigin-RevId: 883153178\n"
    },
    {
      "commit": "f68e6e1f1bb216c17c9575693d25cbe0c5cf7e34",
      "tree": "1a138a52819cc85fcffd29e35dbfc7ebefda4dad",
      "parents": [
        "079dce16e57228ca04ba788612aadf11e44e51c7"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 13 06:55:36 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 13 06:57:11 2026 +0100"
      },
      "message": "Clean up `iterable.h`:\n\n* Remove public `IteratorT\u003cIterable\u003e`. It is used only internally.\n\n* Remove support for `Dependency` from `HasMovableElements` and\n  `MaybeMakeMoveIterator`. The iterable is only a value type, possibly const,\n  or a reference, without interpreting pointers, `std::unique_ptr` etc.\n\n  This is rarely needed, and this makes the traits conceptually simpler,\n  more similar to lower level traits.\n\n  (The only usage of a type providing an iterable through `Dependency`,\n  as opposed to an iterable itself, is in some pending code. That code can\n  resolve `Dependency` itself.)\n\n* Let `ElementType` reflect the semantics of `MaybeMakeMoveIterator()`,\n  returning the right kind of reference or value.\n\n  This propagates to `IsIterableOf`. In particular if the element type is\n  movable but not copyable, the iterable must support moving elements out.\n\n* Add `IsIterableOfPairs`. It is the more basic version of\n  `IsIterableOfPairsWithAssignableValues`, where values are read rather than\n  being assigned to.\n\n* Add `IterableHasSize`.\n\nPiperOrigin-RevId: 882968287\n"
    },
    {
      "commit": "079dce16e57228ca04ba788612aadf11e44e51c7",
      "tree": "357ab93ef4091e3518478e6132cf9c8c274e2715",
      "parents": [
        "577fc68c1047b68e701c51b9e397eaeaf9d0f7b9"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 12 23:03:58 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 13 06:56:58 2026 +0100"
      },
      "message": "Remove deprecated `pad_to_block_boundary` option for `RecordWriter`.\n\nUse `padding`, `initial_padding`, and `final_padding` instead.\n\nPiperOrigin-RevId: 882796923\n"
    },
    {
      "commit": "577fc68c1047b68e701c51b9e397eaeaf9d0f7b9",
      "tree": "c1a2e362ad03f14e2a9b405e6840b5e273a2be9b",
      "parents": [
        "5e10dcbb80fb7845faa45fc6be8e342396e7f232"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 12 15:58:22 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Mar 12 15:59:22 2026 +0100"
      },
      "message": "Add `target_cblock_size` option to `ZstdWriterBase::Options`.\n\nIt attempts to fit compressed block size into approximately\n`target_cblock_size`. A lower value allows the decompressor to begin\ndecompression sooner, having less data available, at the cost of\nreducing compression density.\n\nThis corresponds to `ZSTD_CCtx_setParameter(ZSTD_c_targetCBlockSize)`.\n\nAlso, add static assertions about matching constants. The constants cannot be\nused in `zstd_writer.h` because they require `ZSTD_STATIC_LINKING_ONLY`.\n\nInternally, store `window_log_` and `target_cblock_size_` without\n`std::optional` wrapping, with 0 meaning default. This makes options smaller.\n\nPiperOrigin-RevId: 882591475\n"
    },
    {
      "commit": "5e10dcbb80fb7845faa45fc6be8e342396e7f232",
      "tree": "3b16d0707ee94daa4b7f6ec8a9f819421cd15c0c",
      "parents": [
        "0f3ceb0cf386c6bba2c43f6a07728251be7ad9a4"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 06 09:09:20 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Mar 06 09:25:19 2026 +0100"
      },
      "message": "Move `FieldMap` from a private member class of `FieldHandlerMap` to a public\nstandalone class called `SmallIntMap`.\n\nIts design is not specific to field handlers, and it does not actually depend\non the `Context...` template parameters of `FieldHandlerMap`.\n\nGeneralize it a bit by parameterizing it over:\n* key type (`int` in `FieldHandlerMap`)\n* expected minimum key (1 in `FieldHandlerMap`)\n* maximum array capacity (128 in `FieldHandlerMap`)\n* source construct it from (`absl::flat_hash_map\u003cint, Value\u003e`\n  in `FieldHandlerMap`)\n\n`SmallIntMap` is a map optimized for keys being small integers. It supports only\nlookups, but no incremental building nor iteration.\n\nIt stores a part of the map covering some range of keys starting from\n`expected_min_key` in an array.\n\nAt least `array_capacity` possible keys starting from `expected_min_key` are\nsuitable for array lookup. If all present keys are suitable, the stored array\ncan be smaller than `array_capacity`, covering the range to the largest key.\nIf the map is large, the stored array can be larger than `array_capacity`,\nas long as it is at least 25% full.\n\nOptimizations to `SmallIntMap`:\n* Move `large_map_` behind a pointer to reduce memory usage in the common case.\n* Delay constructing elements of `small_values_` to avoid requiring `Value`\n  to be default-constructible, and to make the code initializing them smaller.\n* Move the slow path of `Find()` to a separate function to inline less code.\n* Add `RIEGELI_ASSUME(_ \u003d\u003d nullptr)` to avoid generating deletion code for an\n  initial assignment to a `std::unique_ptr`.\n\nPiperOrigin-RevId: 879470235\n"
    },
    {
      "commit": "0f3ceb0cf386c6bba2c43f6a07728251be7ad9a4",
      "tree": "3197de77178a6ece0a1f81f04407d15e4e05a29f",
      "parents": [
        "25f18fb9a353d6a9c469452050b58e0bbcd2462f"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 03 22:58:17 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 03 23:01:11 2026 +0100"
      },
      "message": "Make `map_entry_field.h` a public header in a separate `\":map_entry_field\"`\ntarget, instead of reexporting its symbols from other headers.\n\nThe old setup becomes more confusing as more headers export it.\n\nThe cost is more includes and deps in client code, instead of pretending that\n`MapEntryField` is exported together with functions which use it.\n\nPiperOrigin-RevId: 878113699\n"
    },
    {
      "commit": "25f18fb9a353d6a9c469452050b58e0bbcd2462f",
      "tree": "d8506c015a17b73a08a6f2fcfd9ee2b536c87590",
      "parents": [
        "9121f29d18ff1baa94af6da9a8f5879e553e7f5d"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 03 22:21:45 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 03 22:33:45 2026 +0100"
      },
      "message": "In `SerializeMessage()`, avoid `nullptr` violation in\n`SerializeWithCachedSizesToArray()` by returning early if `size \u003d\u003d 0`.\nIn that case the data pointer might be `nullptr`.\n\nPiperOrigin-RevId: 878096881\n"
    },
    {
      "commit": "9121f29d18ff1baa94af6da9a8f5879e553e7f5d",
      "tree": "f7070a6ec6ba2f07f8c724270a3cf4162bdab3c4",
      "parents": [
        "0b23da2cfd1c7157ee89855950ad681c397db37b"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 03 08:15:39 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Mar 03 08:17:13 2026 +0100"
      },
      "message": "Add `ContextProjection()`.\n\nIt adapts a field handler to depend on a part of the context. Makes a field\nhandler depending on some outer context parameters from a field handler\ndepending on inner context parameters.\n\n`projection...` parameters are applied sequentially to transform the outer\ncontext to the inner context. Each `projection` is an invocable which\nreturns either a reference or a tuple of references. Common projections\ninclude `ContextAt\u003cindices...\u003e` to select a subset of context parameters,\nor `\u0026Context::member` to select a member of the context parameter.\n\nPiperOrigin-RevId: 877765506\n"
    },
    {
      "commit": "0b23da2cfd1c7157ee89855950ad681c397db37b",
      "tree": "0b87f5bc6c35222ff41be8e62364ac60ad2978cb",
      "parents": [
        "6e76a9c2b0858c1a37fa23a3c7d1b2f3ac21bbf2"
      ],
      "author": {
        "name": "Compression Team",
        "email": "noreply@google.com",
        "time": "Fri Feb 13 18:18:31 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Feb 13 18:19:25 2026 +0100"
      },
      "message": "MODULE.bazel: Bump highwayhash version\n\nPiperOrigin-RevId: 869763584\n"
    },
    {
      "commit": "6e76a9c2b0858c1a37fa23a3c7d1b2f3ac21bbf2",
      "tree": "64fdc7274cec38bc647008071ee623779f741f3b",
      "parents": [
        "9ca2ab068edf8396d5364d79705792bfe4ca79d9"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Feb 11 17:48:44 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Feb 11 17:49:33 2026 +0100"
      },
      "message": "In `StringWriter`, fix poisoning of memory supposed to be unused. After seeking\nback, it is possible that `written_size_` exceeds the cursor, in which case\nmemory between the cursor and `written_size_` is valid and must not be poisoned.\n\nIn `{String,Resizable}Writer::Push()`, protect against the theoretical\npossibility of `recommended_length` being so large that it overflows `size_t`\nwhen added to `size()`.\n\nOptimize a call to `std::string::reserve()`: since C++20 it can no longer be\ninterpreted as a non-binding shrink request.\n\nClean up comments at `ResizableWriter`.\n\nPiperOrigin-RevId: 868698749\n"
    },
    {
      "commit": "9ca2ab068edf8396d5364d79705792bfe4ca79d9",
      "tree": "ad60fe97a05aa5383fb725e2e91550063c2a3f7d",
      "parents": [
        "3afe9ac38d21d8adeb406a16e0513876d28c77e5"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Feb 09 19:19:33 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Feb 09 19:20:22 2026 +0100"
      },
      "message": "Fix a bug in `SkipVarint{32,64}(Cord::CharIterator\u0026)`: when the varint crosses\n`Cord` chunks, correctly advance past the last byte.\n\nFix a bug in `{Read,Copy,Skip}Varint{32,64}(Cord::CharIterator\u0026)`: when the\nvarint is truncated after exactly 2 bytes, fail instead of triggering an\nassertion and then reading past the end of the `Cord`. The code here is not\nfully analogous to reading from a `Reader` or array because `Cord::CharIterator`\ndoes not support forcing a lookahead by more than 1 byte.\n\nPiperOrigin-RevId: 867663513\n"
    },
    {
      "commit": "3afe9ac38d21d8adeb406a16e0513876d28c77e5",
      "tree": "6d7361974a6e2104e30f005696666006a989bd3f",
      "parents": [
        "a7a4771bea40355f6cb939d3378dfa3280034f59"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sat Feb 07 05:34:13 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sat Feb 07 05:34:59 2026 +0100"
      },
      "message": "Use `OptionalCompactString` instead of `std::optional\u003cCompactString\u003e`.\nIt is more compact.\n\nPiperOrigin-RevId: 866726446\n"
    },
    {
      "commit": "a7a4771bea40355f6cb939d3378dfa3280034f59",
      "tree": "a206cd55a73e0001e44b0cb65601fd7da9da4b90",
      "parents": [
        "629f0b97f605a11cc2dea1a2673322ee303d5514"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Feb 06 20:12:40 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Feb 06 20:13:56 2026 +0100"
      },
      "message": "Provide means for containers where newly allocated elements of\ntrivially-constructible types are left uninitialized:\n\n* `UninitializedAllocator`\n* `UninitializedVector`, which is `std::vector` with `UninitializedAllocator`\n* `UninitializedInlinedVector`, which is `absl::InlinedVector` with\n  `UninitializedAllocator`\n\nAdd `VectorWriter` for `std::vector` including `UninitializedVector`,\n`absl::InlinedVector` including `UninitializedInlinedVector`, and similar types.\nLike `CompactStringWriter`, `VectorWriter` can be more efficient than\n`StringWriter` when the destination can be resized with uninitialized space.\n\n`VectorResizableTraits` is generalized from `std::vector` to similar types.\nThe template parameter is the whole vector type rather than the element type\nand the allocator separately.\n\nPiperOrigin-RevId: 866537234\n"
    },
    {
      "commit": "629f0b97f605a11cc2dea1a2673322ee303d5514",
      "tree": "7df168d5d5b80ce2ddad1610a05b6153a4c48f9a",
      "parents": [
        "43b1456a2341b18e3506ad3c01c0f6bf7e37221d"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Feb 06 19:57:10 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Feb 06 19:58:00 2026 +0100"
      },
      "message": "Avoid `std::string::clear()` in `StringWriter`. This avoids filling existing\ndata during resizing.\n\nThis effectively reuses the initial size during initialization rather than the\ninitial capacity.\n\nUnder msan, poison `std::string` space which is meant not to be observed:\ninitial data, and space filled by `std::string::resize()`.\n\nPiperOrigin-RevId: 866529919\n"
    },
    {
      "commit": "43b1456a2341b18e3506ad3c01c0f6bf7e37221d",
      "tree": "e5559fd34598743e11468dc13d0d889db3eb51eb",
      "parents": [
        "71c9e235f2c70a5df7f6519a420239a60c4ead04"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Feb 06 17:18:08 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Feb 06 17:18:44 2026 +0100"
      },
      "message": "Remove nullability support for `OptionalCompactString`.\n\nIt is not useful to have `absl_nonnull OptionalCompactString`.\n`ABSL_POINTERS_DEFAULT_NONNULL` make that likely by accident.\n\nPiperOrigin-RevId: 866468668\n"
    },
    {
      "commit": "71c9e235f2c70a5df7f6519a420239a60c4ead04",
      "tree": "5c159fb4185c1e242d6d37d395eecfe1e5012fb1",
      "parents": [
        "f13f6462771f341b04dbd8446381152071939791"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Feb 02 22:14:09 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Feb 02 22:15:32 2026 +0100"
      },
      "message": "Rename `SerializedMessageReader2` to `SerializedMessageReader`.\n\nThis is now possible because the old class called `SerializedMessageReader`\nhas been removed.\n\nPiperOrigin-RevId: 864491649\n"
    },
    {
      "commit": "f13f6462771f341b04dbd8446381152071939791",
      "tree": "528b56e54a53b53427d69e4088893694915cfb52",
      "parents": [
        "9677de56d722e817ae7ab9b9658cba1748973877"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Jan 30 12:57:25 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Jan 30 12:58:20 2026 +0100"
      },
      "message": "Remove `SerializedMessage{Reader,Rewriter}`. They are no longer used.\n\nUse `SerializedMessageReader2` instead. It will be renamed to\n`SerializedMessageReader`.\n\nPiperOrigin-RevId: 863164938\n"
    },
    {
      "commit": "9677de56d722e817ae7ab9b9658cba1748973877",
      "tree": "af899a2c8d830e6a94bd30d3157d82ceb4ba79ed",
      "parents": [
        "e1b2fedf24735a1221f44cd01a6d0d79a522d5aa"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sat Jan 24 07:49:25 2026 +0100"
      },
      "committer": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Sat Jan 24 07:51:05 2026 +0100"
      },
      "message": "Add `SerializedMessageAssembler`, a class for assembling a serialized message\nfrom a dynamically specified tree of fields.\n\nPiperOrigin-RevId: 860405280\n"
    },
    {
      "commit": "e1b2fedf24735a1221f44cd01a6d0d79a522d5aa",
      "tree": "57be1ad4aee1d4b9e3ae66cfd03ab25fd919d4bf",
      "parents": [
        "2718295fe739faa70086b8713a8998842defdd2c"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Jan 21 20:02:16 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Wed Jan 21 20:03:09 2026 +0100"
      },
      "message": "Add `DynamicFieldHandler`, a field handler for `SerializedMessageReader2` for a\nsingle field, with the field number specified at runtime.\n\n`DynamicFieldHandler` is similar to a `FieldHandlerMap` with a single registered\nfield handler, but more efficient and without type erasure.\n\nPiperOrigin-RevId: 859177634\n"
    },
    {
      "commit": "2718295fe739faa70086b8713a8998842defdd2c",
      "tree": "dd92ff6f8b7f4a64267920188a41b0e1c1ba1e79",
      "parents": [
        "f4a86e2748aecfbfa6f4b3fb4b30b9b52a4269ef"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Jan 21 10:20:30 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Wed Jan 21 10:23:51 2026 +0100"
      },
      "message": "Use `absl::StringResizeAndOverwrite()` instead of `std::string::resize()`\nwhen the string is filled soon.\n\nRename `ResizeStringAmortized()` to `StringResizeAmortized()` for consistency,\nand add `StringResizeAndOverwriteAmortized()`.\n\nUse `absl::AppendCordToString()`, which is now available, instead of a custom\n`riegeli::cord_internal::AppendCordToString()`.\n\nCosmetics: for `std::string`, replace `\u0026dest[i]` with `dest.data() + i`\nin remaining places. This relies on C++17.\nPiperOrigin-RevId: 858971838\n"
    },
    {
      "commit": "f4a86e2748aecfbfa6f4b3fb4b30b9b52a4269ef",
      "tree": "15d6e1c2e3c15ec159691d1bf83fcc2b531e3cab",
      "parents": [
        "d08612fa81f0ad792598af2b3633a0c5f197fac6"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Jan 21 09:18:46 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Wed Jan 21 09:54:01 2026 +0100"
      },
      "message": "Update Abseil version.\n\nDefine `RIEGELI_COMPARE()` for `absl::string_view` whenever\n`!__cpp_impl_three_way_comparison`. `ABSL_USES_STD_STRING_VIEW` is now\nalways true so there is no need to consider it.\n\nWe assume that if `__cpp_impl_three_way_comparison` then `\u003c\u003d\u003e` for standard\ntypes is usable. Hopefully there is no need to consider implementations where\nthis does not apply.\n\nPiperOrigin-RevId: 858951940\n"
    },
    {
      "commit": "d08612fa81f0ad792598af2b3633a0c5f197fac6",
      "tree": "26ffe7cf7f2df436bc0155c1eade432891c335d4",
      "parents": [
        "f4484d8973e0ef60a3a28a3b2a812a8037b0d077"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Jan 21 07:59:53 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Wed Jan 21 08:01:12 2026 +0100"
      },
      "message": "Optimize `FieldHandlerMap` and delegate some of its responsibilities to its\nclients.\n\n1. Let `FieldHandlerMap` support string and `Cord` sources natively, rather than\n   only by forced wrapping them in a `Reader`.\n\n   This is a tradeoff: unbound field handlers of length-delimited fields\n   must now support at least the string source (and possibly other sources as\n   optimizations), and not require a `Reader` source. This is not the case\n   for direct `SerializedMessageReader2` usage.\n\n   Handling `absl::string_view` natively is important for performance of short\n   sessions, often making them twice faster.\n\n2. Split `FieldHandlerMap::Builder` out of `FieldHandlerMap`, distinguishing\n   between the building stage and the execution stage.\n\n   The original motivation is enabling optimizations of field maps once their\n   contents are fully known.\n\n   This has interesting impact on clients. Clients are implicitly encouraged to\n   distinguish their own building stage and execution stage. This can be more\n   complicated, but it can also enable further flexibility and optimizations.\n\n   Data structures for building are free to use a more flexible but less\n   efficient representation of the partially registered state. Data structures\n   for execution can be simpler and faster, because they do not need to allow\n   for introspection of the current state, nor for incremental updates.\n\n3. Remove dedicated support nested field handler maps, and for storing values\n   of some `Associated` type. This is now the responsibility of the client.\n\n   This is related to the separate `FieldHandlerMap::Builder` stage. Besides\n   simplifying the `FieldHandlerMap` design, a separate building stage of the\n   client allows it to organize introspection of the current state with all\n   needed flexibility, without impacting execution. This reduces constraining\n   the client by particular design choices of `FieldHandlerMap`, in particular\n   how introspection is organized: `associated()`, `submessages()`, and\n   `empty()`, or what happens if a field or parent is registered again.\n\n   The execution stage can hold nested field handler maps and associated data in\n   captured variables of field handler actions, to make them available without\n   additional lookups by field number. That representation does not allow\n   introspection, but introspection is not needed at this stage.\n\n   If it turns out that a particular pattern of handling nested fields emerges,\n   then a separate class for that can be added later.\n\n4. Apply a particular optimization to `FieldHandlerMap`, enabled by the separate\n   `FieldHandlerMap::Builder` stage: store an initial portion of the map in an\n   array indexed by field number.\n\n   Effectiveness of this relies on the assumption that typical field numbers are\n   small, both registered and encountered.\n\n   With low enough all registered field numbers, this involves two conditionals,\n   whether on a hit or miss, whether the miss has a smaller or larger field\n   number than the maximum registered.\n\n   This makes some usages 20% faster.\n\nPiperOrigin-RevId: 858926025\n"
    },
    {
      "commit": "f4484d8973e0ef60a3a28a3b2a812a8037b0d077",
      "tree": "04690cba63af38e9594e452f95571adacc248011",
      "parents": [
        "0435f3312b5ee79ced28053c70a16720501eb1f1"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Jan 20 18:26:23 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Tue Jan 20 18:58:33 2026 +0100"
      },
      "message": "In SFINAE constraints involving field handler actions, do not require the return\ntype to be `absl::Status`. This will be verified implicitly when the action is\ninvoked.\n\nThis makes error messages more informative if action parameters are correct but\nthe return type does not match.\n\nThe same applies to `Handle...()` functions in the field handler protocol.\n\nCosmetics: simplify a `SFINAE` constraint involving a conjunction of a `bool`\ncondition and an expression being well-formed. Replace\n`std::enable_if_t\u003cstd::conjunction_v\u003c..., std::is_void\u003cstd::void_t\u003c...\u003e\u003e\u003e\u003e` with\n`std::enable_if_t\u003c...::value, std::void_t\u003c...\u003e\u003e`.\nPiperOrigin-RevId: 858624299\n"
    },
    {
      "commit": "0435f3312b5ee79ced28053c70a16720501eb1f1",
      "tree": "3afeef4d74ef0b55c59b21f6408552f59eedf70b",
      "parents": [
        "bef360f32d9b5db6681c42dfe59cbc98baf4112c"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Jan 19 18:50:15 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Mon Jan 19 18:52:39 2026 +0100"
      },
      "message": "Remove `Reader::ReadOrPullSome()` with the corresponding virtual functions:\n`Reader::ReadOrPullSomeSlow()` and\n`PullableReader::ReadOrPullSomeBehindScratch()`.\n\nInstead, override `Reader::ReadSomeSlow(char*)` and\n`Reader::CopySomeSlow(Writer\u0026)`, which are now virtual.\n\nAdvantages:\n\n* The overriding API is much more intuitive.\n\n  `ReadOrPullSome()` was weird in how it allowed the `Reader` to choose whether\n  to expose its data or to write to a destination buffer, how it allowed the\n  `Reader` to communicate a tighter `max_length` to the destination, and how it\n  allowed the destination to effectively override the choice if it needs the\n  data in a particular place.\n\n  The choice influences whether the destination should be asked for a buffer\n  at all, and how large, hence `ReadOrPullSome()` used a callback for this.\n\n  Now, `ReadSome(char*)` always copies to the destination buffer, and for\n  `CopySome(Writer\u0026)` the `Reader` calls `Writer::Write(absl::string_view)`,\n  `Writer::Write(ExternalRef)`, or `Writer::Push()` as appropriate.\n\n* In `ReadSome(std::string\u0026)`, string allocation is done together with filling,\n  which will allow to use `absl::StringResizeAndOverwrite()` to avoid prefilling\n  with zeros.\n\nDisadvantages:\n\n* There are two functions to override instead of one, which leads to some\n  duplication of logic.\n\n* `ReadSome(std::string\u0026)` preallocates the whole `max_length`, instead of\n  allowing the `Reader` to communicate if the maximum needed is smaller.\n  A `Writer` is also hinted for the whole `max_length`. That optimization is\n  deemed not worth the API complication.\n\nOther changes:\n\n* Strengthen the preconditions of `ReadSomeSlow()` and `CopySomeSlow()` from\n  `available() \u003c max_length` to `available() \u003d\u003d 0`. Other cases are handled\n  by non-virtual `ReadSome()` and `CopySome()`, by delegating to `Read()` or\n  `Copy()` with `max_length` limited to `available()`.\n\n  This makes overrides simpler, at the cost of potentially losing optimizations\n  to write data from multiple flat buffers at one call.\n\n* Clean up comments about which `Reader` functions are implemented in terms of\n  which ones. This includes all non-virtual functions instead of some of them.\n  This can be important to determine which functions can be called by overrides\n  to avoid infinite recursion.\n\n* Move length overflow checks from `ReadSlow()` to `ReadAndAppend()`, and\n  remove private `ReadSlowWithSizeCheck()` functions. Relevant usages have been\n  already moved from `reader.h` to `reader.cc`, so there is no need to put them\n  in separate functions.\n\n* Move `move_cursor()` calls above `dest.Write()` if this allows to call\n  `dest.Write()` in a tail position.\n\n* Cosmetic change in `riegeli::tensorflow::File{Reader,Writer}Base::OpenFile()`:\n  allow NRVO by always returning the same local variable.\n\nPiperOrigin-RevId: 858222599\n"
    },
    {
      "commit": "bef360f32d9b5db6681c42dfe59cbc98baf4112c",
      "tree": "379dd94b526af5281697dcbdcc3408ac112f80a8",
      "parents": [
        "e71dd41609d2a8c6152aeb4855e5be152c29b13d"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Jan 06 19:40:52 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Tue Jan 06 19:46:49 2026 +0100"
      },
      "message": "Optimization: use `absl::FixedArray` instead of `std::vector` for local arrays\nwhere the size is known at construction but is not a compile time constant.\n\nThis avoids bounds checking in `push_back()`, while avoiding zero initialization\nwhich would be introduced if `std::vector` was resized early.\n\nThis also avoids a heap allocation if the size is small enough.\n\nPiperOrigin-RevId: 852844090\n"
    },
    {
      "commit": "e71dd41609d2a8c6152aeb4855e5be152c29b13d",
      "tree": "6969ced1a60dd977233d2f7fcde3da277bc472fd",
      "parents": [
        "158cc2ea10264aa4c37f597100fc195cc0a5d6d1"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Jan 06 15:39:10 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Tue Jan 06 15:42:50 2026 +0100"
      },
      "message": "Embrace `__cpp_aggregate_paren_init`, i.e. initializing aggregates with parens\nand not only with braces: use `emplace_back()` with aggregate elements instead\nof `push_back()` with a temporary struct.\n\nThis will be unconditional when C++20 can be assumed.\n\nPiperOrigin-RevId: 852755751\n"
    },
    {
      "commit": "158cc2ea10264aa4c37f597100fc195cc0a5d6d1",
      "tree": "9d621a62e842464bd28f99be2a70ded514f47112",
      "parents": [
        "3ae0188cd8b0bc22d04a9406bc4a44e0d61795f0"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Tue Jan 06 09:59:01 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Tue Jan 06 09:59:57 2026 +0100"
      },
      "message": "Migrate proto files to 2024 edition.\n\nBesides syntax changes, this involves semantic changes according to current\nbest practices:\n* Repeated fields are packed if possible.\n* Enums are open.\n* String fields are validated for UTF-8.\n* Getters of string and bytes fields return `absl::string_view`.\n\nPiperOrigin-RevId: 852655791\n"
    },
    {
      "commit": "3ae0188cd8b0bc22d04a9406bc4a44e0d61795f0",
      "tree": "3e76704523771e520d1cc12f208ac78f4723d455",
      "parents": [
        "52443c3f35ac5c32a16e2c649d2a2937cf2b0985"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Jan 05 16:34:29 2026 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Mon Jan 05 16:38:00 2026 +0100"
      },
      "message": "Use `absl::bit_cast` instead of `std::bit_cast` which requires C++20.\n\nPiperOrigin-RevId: 852294864\n"
    },
    {
      "commit": "52443c3f35ac5c32a16e2c649d2a2937cf2b0985",
      "tree": "1432122d7d1386cff388081cb53e621a538ec503",
      "parents": [
        "3feaaab06e10ec58d51d557b7a9a9135a5945c8f"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Dec 22 22:30:18 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Mon Dec 22 22:31:00 2025 +0100"
      },
      "message": "Flip preferred names of reading/writing functions with explicit Endianness:\nuse `{Read,Write}{Little,Big}Endian{,s}\u003c{u,}int{8,16,32,64}_t\u003e()` etc., making\n`{Read,Write}{Little,Big}Endian{,Signed}{16,32,64}{,s}()` etc. deprecated.\nThe latter names were original, but the former names are more clear, they make\nit easier to write generic code, and there is no need to keep two variants.\n\nRemove internal decoding/encoding functions, and inline their logic into\nreading/writing functions. This was not done before because some compilers\ngenerated poor code if decoding/encoding was applied to an external array as\nopposed to a local variable. To be sure that this does not happen, and to make\nthe life of the compiler easier, use `memcpy()` instead of bit operations when\nEndianness matches.\n\nReorder definitions: put `char*` before `Reader` / `Writer` / `BackwardWriter`,\nand put scalar and array `Writer` functions together. The `char*` functions\nmust be defined before they are called from other functions (these template\nspecializations do not have individual forward declarations, a forward\ndeclaration of the primary template is not enough), and also `char*` functions\nare used as building blocks of various decoding/encoding functions of headers\netc.\n\nPiperOrigin-RevId: 847867537\n"
    },
    {
      "commit": "3feaaab06e10ec58d51d557b7a9a9135a5945c8f",
      "tree": "2fe61f15539d89e835a4eecfde0874fd5b825f5c",
      "parents": [
        "03d643f69b46b20c6da41e726e2b4cb00fdd29a3"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Dec 22 22:14:34 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Mon Dec 22 22:15:20 2025 +0100"
      },
      "message": "Let `SerializedMessageReader2` use the `riegeli::TargetT` mechanism for\ninitializing field handlers instead of `std::decay_t`. This allows to use\n`riegeli::Maker()` for constructing them in-place.\n\nMake `SerializedMessageReader2` a value type in Riegeli style, with default\nconstructor and `Reset()`, to enable late initialization.\n\nRaw pointers to proper field handlers are no longer automatically treated\nas field handlers. References are supported instead, which is more natural,\nbecause calling member functions on references is not special.\n\nWith `riegeli::TargetT`, `std::cref(field_handler)` deduces a reference type as\nthe type to store. This replaces a raw pointer.\n\nIn a future change, this will make using `FieldHandlerMap` easier, often\nconstructing it in-place instead of using `std::cref()`.\n\nPiperOrigin-RevId: 847862733\n"
    },
    {
      "commit": "03d643f69b46b20c6da41e726e2b4cb00fdd29a3",
      "tree": "8ae90d40b2b5607fa481ba018a43bdea0968b5e4",
      "parents": [
        "6e47c7f3e75a3ebc798409f2ab238826bac8fc43"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Dec 22 20:44:42 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Mon Dec 22 20:47:12 2025 +0100"
      },
      "message": "In `SerializedMessage{,Backward}Writer`, rename `CopyString()` to\n`WriteString()`, merging it with other overloads.\n\nAdd direct support for `CordIteratorSpan` in `WriteString()`. It is convertible\nto `absl::Cord`, but the stringification mechanism does not find that.\n\nRationale: it is not that important to explicitly indicate whether reading is\ndestructive or not, especially since `ReaderSpan` is move-only. It is more\nimportant to be able to treat `ReaderSpan`, `CordIteratorSpan`, and\n`absl::string_view` uniformly.\nPiperOrigin-RevId: 847835642\n"
    },
    {
      "commit": "6e47c7f3e75a3ebc798409f2ab238826bac8fc43",
      "tree": "30fe648c44ae90dbd46f5f66cf2d58211bdda4c2",
      "parents": [
        "a9be707bf24ad44fca8d42be4f8d72c7d8a94f30"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Mon Dec 22 13:37:13 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Mon Dec 22 13:38:42 2025 +0100"
      },
      "message": "Include `\u003cstddef.h\u003e` instead of `\u003ccstddef\u003e` (except for `std::nullptr_t`)\nand `\u003cstdint.h\u003e` instead of `\u003ccstdint\u003e`.\n\nThis was the original convention but some cases slipped through.\n\nThese headers guarantee type names being present in the global namespace, not\nonly in `std::`. While in practice they are interchangeable, I see no reason to\nbe non-portable in this respect, even though the majority of Google code does\nnot care.\n\nPiperOrigin-RevId: 847713149\n"
    },
    {
      "commit": "a9be707bf24ad44fca8d42be4f8d72c7d8a94f30",
      "tree": "956dd8b1eece26b4df2dc73d88159c8d26634877",
      "parents": [
        "0bde5778f4dca6fba56b4c041871789dfb973e98"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Fri Dec 12 09:36:32 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Fri Dec 12 09:44:53 2025 +0100"
      },
      "message": "Assume `__cpp_sized_deallocation` unconditionally, since Riegeli requires C++14\nnowadays.\n\nPiperOrigin-RevId: 843561682\n"
    },
    {
      "commit": "0bde5778f4dca6fba56b4c041871789dfb973e98",
      "tree": "1b1a738688cac006ce2d152c96958679c49da2ba",
      "parents": [
        "cab1eb11bd2e7f2b20b3c4e6c93242d172234e62"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Dec 11 20:01:48 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Thu Dec 11 20:09:55 2025 +0100"
      },
      "message": "Clarify comments regarding adapting field handlers of length-delimited fields\nto various source types.\n\nPiperOrigin-RevId: 843294940\n"
    },
    {
      "commit": "cab1eb11bd2e7f2b20b3c4e6c93242d172234e62",
      "tree": "412afd4c82dc8b64fc6b3d89e47a5a4fc2ed69b0",
      "parents": [
        "cdcc5546a4a557c76512ce8264c368a5a497f650"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Thu Dec 11 00:14:15 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Thu Dec 11 08:45:21 2025 +0100"
      },
      "message": "`riegeli::SkipLengthDelimited()` is no longer needed.\n\nSkipping is automatic if the action does not read the whole length-delimited\nfield.\n\nPiperOrigin-RevId: 842901007\n"
    },
    {
      "commit": "cdcc5546a4a557c76512ce8264c368a5a497f650",
      "tree": "24875efd52a7c615344b66797a1345695c9d608a",
      "parents": [
        "df4257d510190bbefa7b71f22af51165beeb3efe"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Dec 10 19:52:51 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Wed Dec 10 19:53:47 2025 +0100"
      },
      "message": "In the field handler protocol, distinguish `Handle` functions for dynamic field\nnumbers by naming them with the `DynamicHandle` prefix.\n\nThis makes the interpretation of the signature of the given handling funtion\nunambiguous. While in practice the functions are called only when the role has\nbeen determined by `kFieldNumber` and by the presence of `Accept` functions,\nit is cleaner when the signature can be interpreted on its own: which parameter\nis `accepted` if it exists, which parameter is `repr`, and which parameters are\n`context...`.\n\nPiperOrigin-RevId: 842793312\n"
    },
    {
      "commit": "df4257d510190bbefa7b71f22af51165beeb3efe",
      "tree": "d7146594a4b1d6048cf9d8040b403e165074c496",
      "parents": [
        "018c91c6f545d4d6bec74c8a8e3ed5dfd27e1a3e"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Dec 10 19:41:12 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Wed Dec 10 19:45:55 2025 +0100"
      },
      "message": "Reduce code duplication in field handlers by having more templates, and simplify\nthe types somewhat.\n\nRemove a separate layer of naming of field handler types, i.e. aliases to lower\nlevel handlers. At the same time, parameterize the field handler types by the\nvalue type, together with varnint kind for varint fields, rather than a trait\nstruct. Spelling the types is very rare anyway, and this makes it easier to\ntreat them generically, including future code. This also reduces the amount of\nexported names.\n\nFor parameters holding the undecoded representation of a field value for a\nparticular wire type (`uint64_t` for varint, `uint32_t` for fixed32 etc.),\nprefer the name `repr` to `value`. Let `value` mean the decoded value.\n\nDo not inline implementations of decoding packed fields.\n\nPiperOrigin-RevId: 842788195\n"
    },
    {
      "commit": "018c91c6f545d4d6bec74c8a8e3ed5dfd27e1a3e",
      "tree": "e1916457a37fcd885ff4b53ca5426758d3ea1814",
      "parents": [
        "fb10e1ed5963c28f96ab935ab001b3594b48cd49"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Dec 10 17:05:42 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Wed Dec 10 17:09:17 2025 +0100"
      },
      "message": "Use a tail-recursive loop over indices instead of `std::apply()`.\n\nWith many field handlers, the lambda passed to `apply()` is not inlined,\nand calling it yields a large number of `push` instructions to call it.\n\nThis speeds up processing some protos with a large number of fields by 20%.\n\nPiperOrigin-RevId: 842731220\n"
    },
    {
      "commit": "fb10e1ed5963c28f96ab935ab001b3594b48cd49",
      "tree": "f2599521e2523b4d884e7053c67a140ae3c50743",
      "parents": [
        "8fdfe38d4da996f44706b9e9f23bcddd07afa3c5"
      ],
      "author": {
        "name": "Marcin Kowalczyk",
        "email": "qrczak@google.com",
        "time": "Wed Dec 10 17:04:16 2025 +0100"
      },
      "committer": {
        "name": "qrczak",
        "email": "qrczak@google.com",
        "time": "Wed Dec 10 17:09:00 2025 +0100"
      },
      "message": "Add a separate implementation of `SerializedMessageReader2::ReadMessage()` from\n`absl::Cord`, along with the needed extensions of the field handler protocol.\n\nFor short reading sessions, reading directly using `Cord::CharIterator` can be\ntwice faster than setting up a `CordReader`. The cost is limited features:\nno lookahead spanning `absl::Cord` chunks, no tracking of absolute position,\nno polymorphism. Also `Cord` is simple enough: no failures (which are potential\nwith polymorphism), unconditionally available remaining size, cheap access\nto the original buffer pointers.\n\nPiperOrigin-RevId: 842730631\n"
    }
  ],
  "next": "8fdfe38d4da996f44706b9e9f23bcddd07afa3c5"
}
