use std::marker::PhantomData;
use super::Joiner;
pub fn overlapping<T, Fsa, Fea, Fsb, Feb>(
start_a: Fsa,
end_a: Fea,
start_b: Fsb,
end_b: Feb,
) -> OverlappingJoiner<Fsa, Fea, Fsb, Feb, T>
where
T: Ord,
Fsa: Send + Sync,
Fea: Send + Sync,
Fsb: Send + Sync,
Feb: Send + Sync,
{
OverlappingJoiner {
start_a,
end_a,
start_b,
end_b,
_phantom: PhantomData,
}
}
pub fn overlap_on<T, LS, LE, CS, CE>(
start_row: LS,
end_row: LE,
start_c: CS,
end_c: CE,
) -> OverlappingJoiner<LS, LE, CS, CE, T>
where
T: Ord,
LS: Send + Sync,
LE: Send + Sync,
CS: Send + Sync,
CE: Send + Sync,
{
OverlappingJoiner {
start_a: start_row,
end_a: end_row,
start_b: start_c,
end_b: end_c,
_phantom: PhantomData,
}
}
pub struct OverlappingJoiner<Fsa, Fea, Fsb, Feb, T> {
pub(super) start_a: Fsa,
pub(super) end_a: Fea,
pub(super) start_b: Fsb,
pub(super) end_b: Feb,
_phantom: PhantomData<fn() -> T>,
}
impl<Fsa, Fea, Fsb, Feb, T> OverlappingJoiner<Fsa, Fea, Fsb, Feb, T> {
pub fn and<J>(self, other: J) -> super::AndJoiner<Self, J> {
super::AndJoiner {
first: self,
second: other,
}
}
#[inline]
pub fn into_bounds(self) -> (Fsa, Fea, Fsb, Feb) {
(self.start_a, self.end_a, self.start_b, self.end_b)
}
}
impl<A, B, T, Fsa, Fea, Fsb, Feb> Joiner<A, B> for OverlappingJoiner<Fsa, Fea, Fsb, Feb, T>
where
T: Ord,
Fsa: Fn(&A) -> T + Send + Sync,
Fea: Fn(&A) -> T + Send + Sync,
Fsb: Fn(&B) -> T + Send + Sync,
Feb: Fn(&B) -> T + Send + Sync,
{
#[inline]
fn matches(&self, a: &A, b: &B) -> bool {
let start_a = (self.start_a)(a);
let end_a = (self.end_a)(a);
let start_b = (self.start_b)(b);
let end_b = (self.end_b)(b);
start_a < end_b && start_b < end_a
}
}