use crate::column::Column;
use crate::error::{CudfError, Result};
use crate::table::Table;
pub struct JoinResult {
pub left_indices: Column,
pub right_indices: Column,
}
pub struct SemiJoinResult {
pub left_indices: Column,
}
impl Table {
pub fn inner_join(&self, right_keys: &Table) -> Result<JoinResult> {
let maps = cudf_cxx::join::ffi::inner_join(&self.inner, &right_keys.inner)
.map_err(CudfError::from_cxx)?;
extract_join_result(maps)
}
pub fn left_join(&self, right_keys: &Table) -> Result<JoinResult> {
let maps = cudf_cxx::join::ffi::left_join(&self.inner, &right_keys.inner)
.map_err(CudfError::from_cxx)?;
extract_join_result(maps)
}
pub fn full_join(&self, right_keys: &Table) -> Result<JoinResult> {
let maps = cudf_cxx::join::ffi::full_join(&self.inner, &right_keys.inner)
.map_err(CudfError::from_cxx)?;
extract_join_result(maps)
}
pub fn left_semi_join(&self, right_keys: &Table) -> Result<SemiJoinResult> {
let maps = cudf_cxx::join::ffi::left_semi_join(&self.inner, &right_keys.inner)
.map_err(CudfError::from_cxx)?;
extract_semi_join_result(maps)
}
pub fn left_anti_join(&self, right_keys: &Table) -> Result<SemiJoinResult> {
let maps = cudf_cxx::join::ffi::left_anti_join(&self.inner, &right_keys.inner)
.map_err(CudfError::from_cxx)?;
extract_semi_join_result(maps)
}
pub fn mark_semi_join(&self, right_keys: &Table) -> Result<SemiJoinResult> {
let maps = cudf_cxx::join::ffi::mark_semi_join(&self.inner, &right_keys.inner)
.map_err(CudfError::from_cxx)?;
extract_semi_join_result(maps)
}
pub fn mark_anti_join(&self, right_keys: &Table) -> Result<SemiJoinResult> {
let maps = cudf_cxx::join::ffi::mark_anti_join(&self.inner, &right_keys.inner)
.map_err(CudfError::from_cxx)?;
extract_semi_join_result(maps)
}
pub fn cross_join(&self, right: &Table) -> Result<Table> {
let raw = cudf_cxx::join::ffi::cross_join(&self.inner, &right.inner)
.map_err(CudfError::from_cxx)?;
Ok(Table { inner: raw })
}
}
fn extract_semi_join_result(
mut maps: cxx::UniquePtr<cudf_cxx::table::ffi::OwnedTable>,
) -> Result<SemiJoinResult> {
let left = cudf_cxx::table::ffi::table_release_column(maps.pin_mut(), 0)
.map_err(CudfError::from_cxx)?;
Ok(SemiJoinResult {
left_indices: Column { inner: left },
})
}
fn extract_join_result(
mut maps: cxx::UniquePtr<cudf_cxx::table::ffi::OwnedTable>,
) -> Result<JoinResult> {
let right = cudf_cxx::table::ffi::table_release_column(maps.pin_mut(), 1)
.map_err(CudfError::from_cxx)?;
let left = cudf_cxx::table::ffi::table_release_column(maps.pin_mut(), 0)
.map_err(CudfError::from_cxx)?;
Ok(JoinResult {
left_indices: Column { inner: left },
right_indices: Column { inner: right },
})
}
pub struct HashJoin<'a> {
_build: std::marker::PhantomData<&'a Table>,
inner: cxx::UniquePtr<cudf_cxx::join::ffi::OwnedHashJoin>,
}
unsafe impl Send for HashJoin<'_> {}
impl<'a> HashJoin<'a> {
pub fn new(build: &'a Table) -> Result<Self> {
let inner =
cudf_cxx::join::ffi::hash_join_create(&build.inner).map_err(CudfError::from_cxx)?;
Ok(Self {
_build: std::marker::PhantomData,
inner,
})
}
pub fn inner_join(&self, probe: &Table) -> Result<JoinResult> {
let maps = cudf_cxx::join::ffi::hash_join_inner(&self.inner, &probe.inner)
.map_err(CudfError::from_cxx)?;
extract_join_result(maps)
}
pub fn left_join(&self, probe: &Table) -> Result<JoinResult> {
let maps = cudf_cxx::join::ffi::hash_join_left(&self.inner, &probe.inner)
.map_err(CudfError::from_cxx)?;
extract_join_result(maps)
}
pub fn full_join(&self, probe: &Table) -> Result<JoinResult> {
let maps = cudf_cxx::join::ffi::hash_join_full(&self.inner, &probe.inner)
.map_err(CudfError::from_cxx)?;
extract_join_result(maps)
}
pub fn inner_join_size(&self, probe: &Table) -> Result<usize> {
let sz = cudf_cxx::join::ffi::hash_join_inner_size(&self.inner, &probe.inner)
.map_err(CudfError::from_cxx)?;
if sz < 0 {
return Err(CudfError::InvalidArgument(format!(
"join size returned negative value: {}",
sz
)));
}
Ok(sz as usize)
}
pub fn left_join_size(&self, probe: &Table) -> Result<usize> {
let sz = cudf_cxx::join::ffi::hash_join_left_size(&self.inner, &probe.inner)
.map_err(CudfError::from_cxx)?;
if sz < 0 {
return Err(CudfError::InvalidArgument(format!(
"join size returned negative value: {}",
sz
)));
}
Ok(sz as usize)
}
pub fn full_join_size(&self, probe: &Table) -> Result<usize> {
let sz = cudf_cxx::join::ffi::hash_join_full_size(&self.inner, &probe.inner)
.map_err(CudfError::from_cxx)?;
if sz < 0 {
return Err(CudfError::InvalidArgument(format!(
"join size returned negative value: {}",
sz
)));
}
Ok(sz as usize)
}
}