use std::sync::Arc;
use bytes::Bytes;
use parquet::arrow::async_reader::ParquetObjectReader;
use parquet::file::metadata::{PageIndexPolicy, ParquetMetaData, ParquetMetaDataReader, ParquetMetaDataWriter};
use crate::error::Result;
use crate::lake::Lake;
const PREFETCH: usize = 64 << 10;
pub(crate) async fn read(lake: &Lake, uri: &str, size: u64) -> Result<Bytes> {
if let Some(bytes) = lake.caches().footers.get(uri) {
return Ok(bytes);
}
let storage = lake.storage();
let mut reader = ParquetObjectReader::new(storage.object_store(), storage.path(uri)?).with_file_size(size);
let metadata = ParquetMetaDataReader::new()
.with_page_index_policy(PageIndexPolicy::Optional)
.with_prefetch_hint(Some(PREFETCH))
.load_and_finish(&mut reader, size)
.await?;
let bytes = encode(&metadata)?;
lake.caches().footers.insert(uri.to_string(), bytes.clone());
Ok(bytes)
}
pub(crate) fn encode(metadata: &ParquetMetaData) -> Result<Bytes> {
let mut buf = vec![];
ParquetMetaDataWriter::new(&mut buf, metadata).finish()?;
Ok(Bytes::from(buf))
}
pub(crate) fn decode(bytes: &Bytes) -> Result<Arc<ParquetMetaData>> {
let reader = ParquetMetaDataReader::new().with_page_index_policy(PageIndexPolicy::Optional);
Ok(Arc::new(reader.parse_and_finish(bytes)?))
}