use crate::DecodeResult;
use crate::arrow::arrow_reader::{ParquetRecordBatchReader, RowGroupPlan};
use crate::arrow::push_decoder::reader_builder::{
RowGroupBuildResult, RowGroupReaderBuilder, RowGroupReaderBuilderParts,
};
use crate::arrow::push_decoder::scan_plan::{NextRowGroup, RowBudget, RowGroupFrontier, ScanPlan};
use crate::errors::ParquetError;
use crate::file::metadata::ParquetMetaData;
use arrow_schema::SchemaRef;
use bytes::Bytes;
use std::ops::Range;
use std::sync::Arc;
#[derive(Debug)]
pub(crate) struct RemainingRowGroups {
schema: SchemaRef,
frontier: RowGroupFrontier,
row_group_reader_builder: RowGroupReaderBuilder,
active_row_group: Option<NextRowGroup>,
}
#[derive(Debug)]
pub(crate) struct RemainingRowGroupsParts {
pub schema: SchemaRef,
pub metadata: Arc<ParquetMetaData>,
pub row_group_plan: RowGroupPlan,
pub offset: Option<usize>,
pub limit: Option<usize>,
pub reader_builder: RowGroupReaderBuilderParts,
}
impl RemainingRowGroups {
pub fn new(
schema: SchemaRef,
parquet_metadata: Arc<ParquetMetaData>,
row_group_plan: RowGroupPlan,
budget: RowBudget,
has_predicates: bool,
row_group_reader_builder: RowGroupReaderBuilder,
) -> Result<Self, ParquetError> {
Ok(Self {
schema,
frontier: RowGroupFrontier::new(
parquet_metadata,
row_group_plan,
budget,
has_predicates,
)?,
row_group_reader_builder,
active_row_group: None,
})
}
pub(crate) fn into_parts(self) -> RemainingRowGroupsParts {
let Self {
schema,
frontier,
row_group_reader_builder,
active_row_group: _,
} = self;
let (parquet_metadata, row_group_plan, budget) = frontier.into_parts();
RemainingRowGroupsParts {
schema,
metadata: parquet_metadata,
row_group_plan,
offset: budget.offset(),
limit: budget.limit(),
reader_builder: row_group_reader_builder.into_parts(),
}
}
pub(super) fn scan_plan(&self) -> ScanPlan {
self.row_group_reader_builder
.scan_plan_builder(self.frontier.clone())
.with_active_row_group(self.active_row_group.clone())
.build()
}
pub fn push_data(
&mut self,
ranges: Vec<Range<u64>>,
buffers: Vec<Bytes>,
) -> Result<(), ParquetError> {
self.row_group_reader_builder.push_data(ranges, buffers)
}
pub fn buffered_bytes(&self) -> u64 {
self.row_group_reader_builder.buffered_bytes()
}
pub fn clear_all_ranges(&mut self) {
self.row_group_reader_builder.clear_all_ranges();
}
pub fn is_at_row_group_boundary(&self) -> bool {
self.row_group_reader_builder.is_finished()
}
pub fn row_groups_remaining(&self) -> usize {
self.frontier.row_groups_remaining()
}
pub fn peek_next_row_group(&self) -> Result<Option<usize>, ParquetError> {
if self.row_group_reader_builder.has_active_row_group() {
return Ok(None);
}
self.frontier.peek_next_row_group()
}
pub fn release_unread_bytes(&mut self) {
self.row_group_reader_builder
.release_unread_bytes(self.frontier.queued_row_groups());
}
fn release_row_group(&mut self, row_group_idx: Option<usize>) {
if let Some(row_group_idx) = row_group_idx
&& !self.frontier.is_queued(row_group_idx)
{
self.row_group_reader_builder
.release_row_group(row_group_idx);
}
}
pub fn try_next_reader(
&mut self,
) -> Result<DecodeResult<ParquetRecordBatchReader>, ParquetError> {
loop {
if !self.row_group_reader_builder.has_active_row_group() {
match self.frontier.next_readable_row_group()? {
Some(next_row_group) => {
self.active_row_group = Some(next_row_group.clone());
let NextRowGroup {
row_group_idx,
row_count,
selection,
budget,
} = next_row_group;
self.row_group_reader_builder.next_row_group(
row_group_idx,
row_count,
selection,
budget,
)?;
}
None => return Ok(DecodeResult::Finished),
}
}
let row_group_idx = self.row_group_reader_builder.active_row_group_idx();
match self.row_group_reader_builder.try_build()? {
RowGroupBuildResult::Finished { remaining_budget } => {
self.active_row_group = None;
self.frontier
.update_budget_after_row_group(remaining_budget);
self.release_row_group(row_group_idx);
}
RowGroupBuildResult::NeedsData(ranges) => {
return Ok(DecodeResult::NeedsData(ranges));
}
RowGroupBuildResult::Data {
batch_reader,
remaining_budget,
} => {
self.active_row_group = None;
self.frontier
.update_budget_after_row_group(remaining_budget);
self.release_row_group(row_group_idx);
return Ok(DecodeResult::Data(batch_reader));
}
}
}
}
}