use crate::io::FileIO;
use crate::spec::{DataField, IndexFileMeta};
use crate::table::bucket_assigner_constant::ConstantBucketAssigner;
use crate::table::bucket_assigner_cross::CrossPartitionAssigner;
use crate::table::bucket_assigner_dynamic::DynamicBucketAssigner;
use crate::table::bucket_assigner_fixed::FixedBucketAssigner;
use crate::Result;
use arrow_array::RecordBatch;
use std::collections::HashMap;
pub(crate) type PartitionBucketKey = (Vec<u8>, i32);
pub(crate) struct BatchAssignOutput {
pub partition_bytes: Vec<Vec<u8>>,
pub buckets: Vec<i32>,
pub deletes: Vec<(usize, Vec<u8>, i32)>,
pub skips: Vec<usize>,
}
pub(crate) trait BucketAssigner: Send {
fn assign_batch(
&mut self,
batch: &RecordBatch,
fields: &[DataField],
) -> impl std::future::Future<Output = Result<BatchAssignOutput>> + Send;
fn prepare_commit_index(
&mut self,
file_io: &FileIO,
index_dir: &str,
) -> impl std::future::Future<Output = Result<HashMap<PartitionBucketKey, Vec<IndexFileMeta>>>> + Send;
}
pub(crate) enum BucketAssignerEnum {
Constant(ConstantBucketAssigner),
Fixed(FixedBucketAssigner),
Dynamic(DynamicBucketAssigner),
CrossPartition(Box<CrossPartitionAssigner>),
}
impl BucketAssignerEnum {
pub async fn assign_batch(
&mut self,
batch: &RecordBatch,
fields: &[DataField],
) -> Result<BatchAssignOutput> {
match self {
Self::Constant(a) => a.assign_batch(batch, fields).await,
Self::Fixed(a) => a.assign_batch(batch, fields).await,
Self::Dynamic(a) => a.assign_batch(batch, fields).await,
Self::CrossPartition(a) => a.assign_batch(batch, fields).await,
}
}
pub async fn prepare_commit_index(
&mut self,
file_io: &FileIO,
index_dir: &str,
) -> Result<HashMap<PartitionBucketKey, Vec<IndexFileMeta>>> {
match self {
Self::Constant(a) => a.prepare_commit_index(file_io, index_dir).await,
Self::Fixed(a) => a.prepare_commit_index(file_io, index_dir).await,
Self::Dynamic(a) => a.prepare_commit_index(file_io, index_dir).await,
Self::CrossPartition(a) => a.prepare_commit_index(file_io, index_dir).await,
}
}
pub fn set_overwrite(&mut self, is_overwrite: bool) {
if let Self::Dynamic(a) = self {
a.set_overwrite(is_overwrite);
}
}
}