use super::data_writer::{IncrementalPartitionWriter, StaticMergedOp, StreamingPartitionSession};
use super::stats_fold;
use super::{PromotedIndexBlock, SSTableWriter, StatisticsMetadata};
use crate::error::{Error, Result};
use crate::schema::TableSchema;
use crate::storage::sstable::writer::data_writer::PartitionEmitCounts;
use crate::storage::write_engine::mutation::{
DecoratedKey, Mutation, PartitionTombstone, RangeTombstone,
};
impl SSTableWriter {
pub(crate) fn schema(&self) -> &TableSchema {
&self.schema
}
pub(crate) fn begin_partition_incremental<'w, 'r>(
&'w mut self,
key: &DecoratedKey,
partition_tombstone: Option<&PartitionTombstone>,
range_tombstones: &'r [RangeTombstone],
) -> Result<IncrementalPartitionWriter<'w, 'r>> {
debug_assert!(
self.baselines_locked,
"begin_partition_incremental requires pre-seeded encoding baselines \
(call pre_seed_encoding_baselines before streaming partitions) — \
see the precondition doc on this method, issue #1668"
);
if let Some(last_token) = self.last_token {
if key.token <= last_token {
return Err(Error::InvalidInput(format!(
"Partitions must be written in token order: got token {} after {}",
key.token, last_token
)));
}
}
self.last_token = Some(key.token);
self.stats.update_key_range(&key.key);
self.data_writer.begin_partition_incremental(
key,
partition_tombstone,
range_tombstones,
&self.schema,
)
}
pub(crate) fn complete_partition_incremental(
&mut self,
key: &DecoratedKey,
partition_tombstone: Option<&PartitionTombstone>,
data_offset: u64,
promoted_blocks: &[PromotedIndexBlock],
emit_counts: PartitionEmitCounts,
partition_stats: &StatisticsMetadata,
) -> Result<()> {
stats_fold::merge_stats_fold(&mut self.stats, partition_stats);
self.stats.row_count += emit_counts.rows;
self.stats.column_count += emit_counts.columns;
let partition_serialized_size = self.data_writer.position().saturating_sub(data_offset);
self.stats
.record_partition(partition_serialized_size, emit_counts.columns);
let entry_info =
self.index_writer
.add_partition_with_promoted(key, data_offset, promoted_blocks)?;
if let Some(ref mut filter) = self.filter_writer {
filter.add_key(key);
}
self.queue_bti_partition(key, data_offset, promoted_blocks, partition_tombstone);
self.summary_writer.note_partition(key);
if self.summary_sample_counter % self.summary_sample_interval == 0 {
self.summary_writer
.add_entry(key, entry_info.index_offset)?;
}
self.summary_sample_counter += 1;
self.partition_count += 1;
self.stats.increment_partition_count();
crate::observability::add_counter(crate::observability::catalog::WRITE_PARTITIONS, 1, &[]);
Ok(())
}
pub(crate) fn begin_streaming_partition(
&mut self,
key: &DecoratedKey,
partition_tombstone: Option<&PartitionTombstone>,
range_tombstones: &[RangeTombstone],
) -> Result<StreamingPartitionSession> {
debug_assert!(
self.baselines_locked,
"begin_streaming_partition requires pre-seeded encoding baselines \
(call pre_seed_encoding_baselines before streaming partitions) — \
see begin_partition_incremental's precondition doc, issue #1668"
);
if let Some(last_token) = self.last_token {
if key.token <= last_token {
return Err(Error::InvalidInput(format!(
"Partitions must be written in token order: got token {} after {}",
key.token, last_token
)));
}
}
self.last_token = Some(key.token);
self.stats.update_key_range(&key.key);
self.data_writer.begin_streaming_partition(
key,
partition_tombstone,
range_tombstones,
&self.schema,
)
}
pub(crate) fn feed_streaming_row(
&mut self,
session: &mut StreamingPartitionSession,
mutation: &Mutation,
) -> Result<()> {
session.feed_row(&mut self.data_writer, mutation, &self.schema)
}
pub(crate) fn feed_streaming_static_row(
&mut self,
session: &mut StreamingPartitionSession,
merged: &[StaticMergedOp],
first_mutation_ts: i64,
) -> Result<()> {
session.feed_static_row(
&mut self.data_writer,
merged,
first_mutation_ts,
&self.schema,
)
}
pub(crate) fn finish_streaming_partition(
&mut self,
session: StreamingPartitionSession,
) -> Result<(u64, Vec<PromotedIndexBlock>, PartitionEmitCounts)> {
session.finish(&mut self.data_writer, &self.schema)
}
}