use std::collections::HashSet;
use futures::{TryStreamExt, stream};
use crate::Result;
use crate::io::FileIO;
use crate::table::Table;
const DELETE_CONCURRENCY: usize = 10;
pub async fn drop_table_data(table_info: &Table) -> Result<()> {
let mut manifest_lists_to_delete: HashSet<String> = HashSet::new();
let mut manifests_to_delete: HashSet<String> = HashSet::new();
let metadata = table_info.metadata_ref();
let io = table_info.file_io();
let results: Vec<_> =
futures::future::try_join_all(metadata.snapshots().map(|snapshot| async {
let manifest_list = table_info.manifest_list_reader(snapshot).load().await?;
Ok::<_, crate::Error>((snapshot.manifest_list().to_string(), manifest_list))
}))
.await?;
for (manifest_list_location, manifest_list) in results {
if !manifest_list_location.is_empty() {
manifest_lists_to_delete.insert(manifest_list_location);
}
for manifest_file in manifest_list.entries() {
manifests_to_delete.insert(manifest_file.manifest_path.clone());
}
}
if metadata.table_properties()?.gc_enabled {
delete_data_files(io, &manifests_to_delete).await?;
}
io.delete_stream(stream::iter(manifests_to_delete)).await?;
io.delete_stream(stream::iter(manifest_lists_to_delete))
.await?;
let prev_metadata_paths: Vec<String> = metadata
.metadata_log()
.iter()
.map(|m| m.metadata_file.clone())
.collect();
io.delete_stream(stream::iter(prev_metadata_paths)).await?;
let stats_paths: Vec<String> = metadata
.statistics_iter()
.map(|s| s.statistics_path.clone())
.collect();
io.delete_stream(stream::iter(stats_paths)).await?;
let partition_stats_paths: Vec<String> = metadata
.partition_statistics_iter()
.map(|s| s.statistics_path.clone())
.collect();
io.delete_stream(stream::iter(partition_stats_paths))
.await?;
if let Some(location) = table_info.metadata_location() {
io.delete(location).await?;
}
Ok(())
}
async fn delete_data_files(io: &FileIO, manifest_paths: &HashSet<String>) -> Result<()> {
stream::iter(manifest_paths.iter().map(Ok))
.try_for_each_concurrent(DELETE_CONCURRENCY, |manifest_path| async move {
let input = io.new_input(manifest_path)?;
let manifest_content = input.read().await?;
let manifest = crate::spec::Manifest::parse_avro(&manifest_content)?;
let data_file_paths = manifest
.entries()
.iter()
.map(|entry| entry.data_file.file_path().to_string())
.collect::<Vec<_>>();
io.delete_stream(stream::iter(data_file_paths)).await
})
.await
}