.. Licensed to the Apache Software Foundation (ASF) under one
.. or more contributor license agreements.  See the NOTICE file
.. distributed with this work for additional information
.. regarding copyright ownership.  The ASF licenses this file
.. to you under the Apache License, Version 2.0 (the
.. "License"); you may not use this file except in compliance
.. with the License.  You may obtain a copy of the License at

..   http://www.apache.org/licenses/LICENSE-2.0

.. Unless required by applicable law or agreed to in writing,
.. software distributed under the License is distributed on an
.. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
.. KIND, either express or implied.  See the License for the
.. specific language governing permissions and limitations
.. under the License.

Write
=====
Batch writing requires the compute engine to specify the target ``partition``.
For fixed-bucket tables, the engine must also assign a valid bucket to every
``RecordBatch``. In unaware-bucket and postpone-bucket modes, the writer can
resolve the bucket automatically when it is omitted.

Paimon C++ uses Apache Arrow as the :ref:`in-memory columnar format<memory-format>`
to more efficiently support writing to disk columnar formats such as ORC,
Parquet, and Avro, thereby improving write throughput.

.. note::
  Currently supported table types:
    - Append table
    - Primary Key table

  Not supported in the current scope:
    - Changelog

Bucketing Modes
---------------

- Append tables:

  * Support ``bucket = -1`` (unaware-bucket mode)
  * Support ``bucket > 0`` (fixed bucket mode)

- PK tables:

  * Support ``bucket = -2`` (postpone bucket mode)
  * Support ``bucket > 0`` (fixed bucket mode)

.. note::
   PK tables do not support dynamic bucketing (``bucket = -1``).

RecordBatch Construction
------------------------

- The compute engine must:

  - Assign the correct ``partition`` for each row.
  - In fixed-bucket mode, apply the Paimon-consistent bucketing function, set a
    bucket in ``[0, bucket)``, and group rows into Arrow ``RecordBatch`` objects
    per partition-bucket combination.

- In unaware-bucket mode (append table with ``bucket = -1``), an omitted bucket
  is resolved to ``0``.
- In postpone-bucket mode (primary-key table with ``bucket = -2``), an omitted
  bucket is resolved to ``-2``.

- Recommended practices:

  - Use schema-aligned Arrow arrays with explicit validity bitmaps and offsets.
  - Prefer batch sizes tuned for I/O throughput (e.g., tens to hundreds of MB per flush, depending on filesystem and cluster configuration).
  - Maintain stable sort orders within a batch only if required by downstream merge or compaction logic; otherwise avoid unnecessary ordering costs.

Prepare Commit
----------------

The compute engine is responsible for triggering the writer nodes' ``PrepareCommit``.
Triggering conditions depend on the engine's business needs and can follow either:

- Streaming mode: time-based or periodic triggers (e.g., every N seconds).
- Batch mode: trigger after all data in the batch has been written.

Once the compute engine collects ``CommitMessages`` from all writer nodes, it
can issue a ``Commit`` request to the control plane (management path) to create
a new ``Snapshot``.

Compatibility Goals
~~~~~~~~~~~~~~~~~~~

To ensure interoperability, the ``PrepareCommit`` result produced by Paimon C++
must be consumable by Paimon Java. Therefore:

- The structure and semantics of ``CommitMessage`` must remain consistent with
  Java Paimon.
- Any evolution of the Java-side ``CommitMessage`` schema must be tracked and
  validated on the C++ side to maintain cross-language compatibility.

Interface Design in Paimon C++
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Unlike Java Paimon, Paimon C++ does not expose ``BinaryRow``-like types in its
public interfaces. To preserve compatibility without leaking internal row
representations, Paimon C++ provides ``CommitMessage`` only through:

- Serialization: convert the internal commit state into a well-defined binary
  representation that matches Java Paimon's expectations.
- Deserialization: parse the Java-compatible binary representation back into
  C++ commit structures for validation, replay, or tooling needs.

This design ensures that:

- Public APIs are independent of Java-specific row abstractions.
- Cross-language commit payloads remain stable and versionable.
- Internal data layouts can evolve without breaking external consumers.

CommitMessage Contract
~~~~~~~~~~~~~~~~~~~~~~

The ``CommitMessage`` must encode all information required by the coordinator to
produce a correct ``Snapshot``, which commonly includes (but is not limited to):

- Partition and bucket identifiers associated with written data.
- New data files, delete files (as applicable to the table type).
- File-level metadata required for manifest and index updates (e.g., row counts, min/max statistics where applicable).
- Transactional markers and sequence numbers as required by table semantics.
- Any per-writer state necessary for deduplication or idempotent commits.

.. note::

   The C++ writer supports Append and PK tables and can produce
   ``CommitMessage`` objects for both. ``FileStoreCommit`` currently executes
   local commits only for append-only tables on non-object-store file systems.
   PK and object-store commit messages must be sent to an external control
   plane. Changelog is out of scope and should not be emitted in
   ``CommitMessage`` until explicitly supported.

Serialization and Deserialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- **Binary format:** The binary payload must strictly conform to Java Paimon's
  ``CommitMessage`` encoding. It does not contain a version tag, so callers
  must transport ``CommitMessage::CurrentVersion()`` separately and supply it
  when deserializing.
- **Serialization API:** Use ``CommitMessage::Serialize`` for one message or
  ``CommitMessage::SerializeList`` for a list.
- **Deserialization API:** Use ``CommitMessage::Deserialize`` or
  ``CommitMessage::DeserializeList`` with the separately supplied
  serialization version.
- **Validation:** Conformance and round-trip tests must verify compatibility
  with Java Paimon for supported message versions.

Operational Flow
~~~~~~~~~~~~~~~~~~~~~~~

1. Writer nodes perform data ingestion and produce Arrow ``RecordBatch``
   organized by partition and bucket.

2. Writers flush batches into ORC/Parquet files via registered ``file.format``
   and ``file-system`` backends, producing file-level metadata and per-batch
   commit state.

3. Each writer invokes ``PrepareCommit``, which:
   - Aggregates per-writer state into a ``CommitMessage``.
   - Returns ``CommitMessage`` objects; it does not serialize them.

4. The compute engine gathers ``CommitMessage`` objects from all writers. For
   cross-process transport, it explicitly calls ``Serialize`` or
   ``SerializeList`` and carries ``CurrentVersion()`` alongside the payload.

5. For a supported local append-table commit, the engine passes the objects to
   ``FileStoreCommit``. For PK tables or object-store paths, it sends the
   serialized payload and version to an external control plane.

6. The local committer or external coordinator validates the messages, updates
   manifests/metadata, and finalizes the snapshot atomically.
