|
| 1 | +/* |
| 2 | + * Copyright 2026-present Alibaba Inc. |
| 3 | + * |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + * you may not use this file except in compliance with the License. |
| 6 | + * You may obtain a copy of the License at |
| 7 | + * |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | + * |
| 10 | + * Unless required by applicable law or agreed to in writing, software |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + * See the License for the specific language governing permissions and |
| 14 | + * limitations under the License. |
| 15 | + */ |
| 16 | + |
| 17 | +#pragma once |
| 18 | + |
| 19 | +#include <cstdint> |
| 20 | +#include <map> |
| 21 | +#include <memory> |
| 22 | +#include <optional> |
| 23 | +#include <string> |
| 24 | +#include <vector> |
| 25 | + |
| 26 | +#include "paimon/reader/batch_reader.h" |
| 27 | +#include "paimon/record_batch.h" |
| 28 | +#include "paimon/result.h" |
| 29 | +#include "paimon/utils/range.h" |
| 30 | +#include "paimon/visibility.h" |
| 31 | + |
| 32 | +struct ArrowSchema; |
| 33 | + |
| 34 | +namespace paimon { |
| 35 | + |
| 36 | +class MemoryPool; |
| 37 | + |
| 38 | +/// A record batch and the contiguous offset range assigned to its rows. |
| 39 | +/// |
| 40 | +/// The batch contains only the table write fields. `_OFFSET` is carried separately by |
| 41 | +/// `offset_range`; row `i` corresponds to `offset_range.from + i`. Paimon adds the physical |
| 42 | +/// `_OFFSET` column when the sealed segment is written to data files. |
| 43 | +struct PAIMON_EXPORT RealtimeWriteBatch { |
| 44 | + /// Input batch whose ownership is transferred to `MemIndexer::Write`. |
| 45 | + std::unique_ptr<RecordBatch> batch; |
| 46 | + /// Inclusive `[from, to]` offset range covered by `batch`. |
| 47 | + Range offset_range; |
| 48 | +}; |
| 49 | + |
| 50 | +/// Opaque handle to an immutable segment returned by `MemIndexer::SealForCommit`. |
| 51 | +/// |
| 52 | +/// A plugin may store the segment in memory or in spill files. Callers use this handle only to |
| 53 | +/// request commit readers and inspect its offset range. |
| 54 | +class PAIMON_EXPORT RealtimeSegmentHandle { |
| 55 | + public: |
| 56 | + virtual ~RealtimeSegmentHandle() = default; |
| 57 | + |
| 58 | + /// Returns the inclusive offset range covered by this segment. |
| 59 | + virtual Range GetOffsetRange() const = 0; |
| 60 | +}; |
| 61 | + |
| 62 | +/// Plugin interface for buffering real-time writes before Paimon data-file generation. |
| 63 | +/// |
| 64 | +/// Paimon serializes calls to `Write` and `SealForCommit` for the same indexer. After sealing, |
| 65 | +/// `CreateCommitReaders` may read the immutable sealed segment while later `Write` calls append to |
| 66 | +/// a new building segment. Paimon retains control of file format, rolling, indexes, and |
| 67 | +/// commit-message generation. |
| 68 | +class PAIMON_EXPORT MemIndexer { |
| 69 | + public: |
| 70 | + virtual ~MemIndexer() = default; |
| 71 | + |
| 72 | + /// Adds a batch to the current building segment. |
| 73 | + /// |
| 74 | + /// The number of rows must equal the size of `offset_range`. |
| 75 | + virtual Status Write(RealtimeWriteBatch&& batch) = 0; |
| 76 | + |
| 77 | + /// Seals the current building data and opens a new building segment. |
| 78 | + /// |
| 79 | + /// Returns an immutable segment handle, or `std::nullopt` when there is no data to seal. |
| 80 | + virtual Result<std::optional<std::shared_ptr<RealtimeSegmentHandle>>> SealForCommit() = 0; |
| 81 | + |
| 82 | + /// Creates readers that expose all rows in a sealed segment for Paimon file writing. |
| 83 | + /// |
| 84 | + /// Concatenating the returned readers must produce every sealed row exactly once and in write |
| 85 | + /// order. Each output batch contains `_VALUE_KIND` followed by all fields from the factory's |
| 86 | + /// `write_schema`; it does not contain `_OFFSET`. |
| 87 | + virtual Result<std::vector<std::unique_ptr<BatchReader>>> CreateCommitReaders( |
| 88 | + const std::shared_ptr<RealtimeSegmentHandle>& segment) = 0; |
| 89 | + |
| 90 | + /// Returns the number of bytes currently retained by the building segment. |
| 91 | + virtual uint64_t GetMemoryUsage() const = 0; |
| 92 | + |
| 93 | + /// Releases resources owned by this indexer and rejects subsequent writes or seals. |
| 94 | + virtual Status Close() = 0; |
| 95 | +}; |
| 96 | + |
| 97 | +/// Factory for application-provided `MemIndexer` implementations. |
| 98 | +class PAIMON_EXPORT MemIndexerFactory { |
| 99 | + public: |
| 100 | + virtual ~MemIndexerFactory() = default; |
| 101 | + |
| 102 | + /// Creates an indexer configured with the supplied schema, options, and memory pool. |
| 103 | + /// |
| 104 | + /// `write_schema` uses the Arrow C Data Interface and contains the table fields accepted by |
| 105 | + /// `Write`. It is valid only during this call. An implementation may consume its contents by |
| 106 | + /// using an Arrow C Data Interface importer; otherwise Paimon releases them after this method |
| 107 | + /// returns. |
| 108 | + /// @param write_schema Table write schema without Paimon-generated real-time fields. |
| 109 | + /// @param options Effective table options available to the indexer. |
| 110 | + /// @param memory_pool Memory pool provided by the write context. |
| 111 | + virtual Result<std::shared_ptr<MemIndexer>> Create( |
| 112 | + ::ArrowSchema* write_schema, const std::map<std::string, std::string>& options, |
| 113 | + const std::shared_ptr<MemoryPool>& memory_pool) = 0; |
| 114 | +}; |
| 115 | + |
| 116 | +} // namespace paimon |
0 commit comments