use crate::config::HudiConfigs;
use crate::file_group::log_file::log_block::LogBlock;
use crate::file_group::log_file::reader::LogFileReader;
use crate::storage::Storage;
use crate::timeline::selector::InstantRange;
use crate::Result;
use arrow_array::RecordBatch;
use std::collections::HashSet;
use std::sync::Arc;
#[derive(Debug)]
pub struct LogFileScanner {
hudi_configs: Arc<HudiConfigs>,
storage: Arc<Storage>,
}
impl LogFileScanner {
pub fn new(hudi_configs: Arc<HudiConfigs>, storage: Arc<Storage>) -> Self {
Self {
hudi_configs,
storage,
}
}
pub async fn scan(
&self,
relative_paths: Vec<String>,
instant_range: &InstantRange,
) -> Result<Vec<Vec<RecordBatch>>> {
let mut all_blocks: Vec<Vec<LogBlock>> = Vec::with_capacity(relative_paths.len());
let mut rollback_targets: HashSet<String> = HashSet::new();
for path in relative_paths {
let mut reader =
LogFileReader::new(self.hudi_configs.clone(), self.storage.clone(), &path).await?;
let blocks = reader.read_all_blocks(instant_range)?;
for block in &blocks {
if block.is_rollback_block() {
rollback_targets.insert(block.target_instant_time()?.to_string());
}
}
all_blocks.push(blocks);
}
let mut record_batches: Vec<Vec<RecordBatch>> = Vec::new();
for blocks in all_blocks {
for block in blocks {
if !rollback_targets.contains(block.instant_time()?) {
record_batches.push(block.record_batches);
}
}
}
Ok(record_batches)
}
}