blob: c4e108dbfef05b455e95d029e58fcd56671e0ca8 [file]
/*
* 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.
*/
#pragma once
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "arrow/c/abi.h"
#include "paimon/reader/batch_reader.h"
#include "paimon/realtime/offset_range.h"
#include "paimon/record_batch.h"
#include "paimon/result.h"
#include "paimon/statistics_mode.h"
#include "paimon/visibility.h"
struct ArrowSchema;
namespace paimon {
class MemoryPool;
class Predicate;
enum class PAIMON_EXPORT RealtimeStoreMode {
APPEND_ONLY,
PRIMARY_KEY,
};
/// Parameters used by a `RealtimeStoreFactory` to create a store.
struct PAIMON_EXPORT RealtimeStoreCreateRequest {
/// Schema whose ownership is transferred to the factory. Append mode receives the complete
/// append transport schema: [_REALTIME_OFFSET, table write fields]. Primary-key mode receives
/// the realtime primary-key transport schema:
/// [_VALUE_KIND, _SEQUENCE_NUMBER, _REALTIME_OFFSET, table write fields].
std::unique_ptr<::ArrowSchema> write_schema;
/// Table options available to the store implementation.
std::map<std::string, std::string> options;
/// Memory pool for allocations retained by the store.
std::shared_ptr<MemoryPool> memory_pool;
/// Table mode implemented by the store.
RealtimeStoreMode mode = RealtimeStoreMode::APPEND_ONLY;
/// Statistics collected by append-only stores.
StatisticsMode statistics_mode = StatisticsMode::NONE;
};
/// A record batch and its application-assigned offset bounds.
///
/// Append-mode batches use the append transport schema [_REALTIME_OFFSET, table write fields], and
/// offsets are strictly increasing before the batch enters the store. Primary-key batches use the
/// realtime primary-key transport schema, are sorted by full primary key then sequence number, and
/// retain the original offset in `_REALTIME_OFFSET`. `offset_range` is the left-closed, right-open
/// envelope from the first application offset through one past the last; offsets may have gaps, so
/// its count is not the batch row count.
struct PAIMON_EXPORT RealtimeWriteBatch {
/// Input batch whose ownership is transferred to `RealtimeStore::Write`.
std::unique_ptr<RecordBatch> batch;
/// Left-closed, right-open offset envelope covered by `batch`.
OffsetRange offset_range;
};
/// Opaque handle to an immutable segment returned by `RealtimeStore::SealForCommit`.
///
/// A plugin may store the segment in memory or in spill files. Callers use this handle only to
/// request commit readers and inspect its offset range and row count.
class PAIMON_EXPORT RealtimeSegmentHandle {
public:
virtual ~RealtimeSegmentHandle() = default;
/// Returns the left-closed, right-open offset range covered by this segment.
virtual OffsetRange GetOffsetRange() const = 0;
/// Returns the number of rows represented by this segment.
virtual int64_t GetRowCount() const = 0;
};
/// Opaque immutable view of the rows visible from one `RealtimeStore`.
///
/// A view pins all referenced resources until the readers created from it are closed. Later
/// writes, seals, and committed-offset reclamation do not change the contents of an existing view.
class PAIMON_EXPORT RealtimeReadView {
public:
virtual ~RealtimeReadView() = default;
/// Returns the left-closed, right-open offset range visible in this view, or no range when it
/// is empty.
virtual std::optional<OffsetRange> GetOffsetRange() const = 0;
};
/// Parameters used by a `RealtimeStore` to create readers for a query.
struct PAIMON_EXPORT RealtimeQueryContext {
/// Physical source schema the store must materialize. Query readers must include the mandatory
/// `_VALUE_KIND` field in returned batches. Paimon may subsequently convert physical fields
/// into the query's logical output schema, for example for selected-key MAP or VARIANT access.
/// This schema is borrowed and remains valid only during `CreateQueryReaders`; plugins must
/// import or copy it synchronously.
::ArrowSchema* read_schema;
/// Optional predicate using field indexes from `read_schema`. A non-null predicate allows the
/// plugin to prune candidate rows. Exact filtering is applied by the Paimon read framework.
std::shared_ptr<Predicate> predicate;
};
/// Customizable plugin interface for storing and querying real-time rows before Paimon data-file
/// generation.
///
/// Paimon serializes calls to `Write` and `SealForCommit` for the same store. After sealing,
/// `CreateCommitReaders` may read the immutable sealed segment while later `Write` calls append to
/// a new building segment. Paimon retains control of file format, rolling, indexes, and
/// commit-message generation. A store may choose its own in-memory representation, indexes, and
/// spill strategy. It may outlive an individual writer because the shared real-time context and
/// active read views retain it.
class PAIMON_EXPORT RealtimeStore {
public:
virtual ~RealtimeStore() = default;
/// Adds a batch to the current building segment.
///
/// The offset envelope may contain gaps.
virtual Status Write(RealtimeWriteBatch&& batch) = 0;
/// Seals the current building data and opens a new building segment.
///
/// Returns an immutable segment handle, or `std::nullopt` when there is no data to seal.
virtual Result<std::optional<std::shared_ptr<RealtimeSegmentHandle>>> SealForCommit() = 0;
/// Creates readers that expose all rows in a sealed segment for Paimon file writing.
///
/// The returned readers collectively expose every sealed row exactly once. Append-mode readers
/// preserve write order and contain `_VALUE_KIND`, `_REALTIME_OFFSET`, and table write fields.
/// Primary-key readers contain the realtime primary-key transport fields; each reader's
/// complete stream is sorted by full primary key then sequence number.
virtual Result<std::vector<std::unique_ptr<BatchReader>>> CreateCommitReaders(
const std::shared_ptr<RealtimeSegmentHandle>& segment) = 0;
/// Acquires an immutable view containing the current sealed and building rows.
///
/// This method may be called concurrently with query-reader creation and reclamation. It must
/// also provide a consistent snapshot when a write or seal is in progress.
virtual Result<std::shared_ptr<RealtimeReadView>> AcquireReadView() = 0;
/// Creates readers over rows in `view`. The readers collectively expose every candidate row
/// exactly once. Primary-key reader streams are sorted by full primary key then sequence
/// number. Paimon retains `view` for the lifetime of the resulting framework reader.
virtual Result<std::vector<std::unique_ptr<BatchReader>>> CreateQueryReaders(
const std::shared_ptr<RealtimeReadView>& view, const RealtimeQueryContext& context) = 0;
/// Notifies the store that its partition-bucket committed end offset has advanced.
///
/// Calls are monotonic and may repeat the same offset after a previous call reports an error,
/// so implementations must apply this notification idempotently.
///
/// An implementation may reclaim covered segments immediately, defer destruction, spill them,
/// or retain them. Existing read views continue to keep referenced resources alive.
virtual Status AdvanceCommittedOffset(int64_t committed_end_offset) = 0;
/// Returns the number of bytes currently retained by building and sealed segments.
virtual uint64_t GetMemoryUsage() const = 0;
};
/// Factory for application-provided `RealtimeStore` implementations.
class PAIMON_EXPORT RealtimeStoreFactory {
public:
virtual ~RealtimeStoreFactory() = default;
/// Creates a store configured with the supplied schema, statistics, options, and memory pool.
/// Creates a store for the requested table mode.
/// The factory consumes `request`, including ownership of `request.write_schema`.
virtual Result<std::shared_ptr<RealtimeStore>> Create(RealtimeStoreCreateRequest&& request) = 0;
};
} // namespace paimon