use super::grace_partitioner::GraceSpec;
use super::hash::{HashIndex, ProbeParams, emit_unmatched_right_into, probe_rows_into};
use super::row_source::RowSource;
use crate::data::executor::core_loop::CoreLoop;
use crate::data::executor::handlers::scan_budget::budget_exceeded;
impl CoreLoop {
pub(super) fn stream_probe_against_index(
&self,
probe_source: &RowSource,
build_docs: &[(String, Vec<u8>)],
spec: &GraceSpec<'_>,
budget: usize,
) -> crate::Result<Vec<Vec<u8>>> {
let index = HashIndex::build(build_docs, spec.build_keys);
let is_right = spec.join_type == "right" || spec.join_type == "full";
let mut index_matched: Vec<bool> = if is_right {
vec![false; build_docs.len()]
} else {
Vec::new()
};
let mut results: Vec<Vec<u8>> = Vec::new();
let mut batch: Vec<(String, Vec<u8>)> = Vec::new();
let mut batch_bytes: usize = 0;
let flush = |batch: &mut Vec<(String, Vec<u8>)>,
batch_bytes: &mut usize,
results: &mut Vec<Vec<u8>>,
index_matched: &mut [bool]| {
if batch.is_empty() {
return;
}
probe_rows_into(
&ProbeParams {
probe_docs: batch,
index: &index,
index_docs: build_docs,
probe_keys: spec.probe_keys,
join_type: spec.join_type,
limit: spec.limit,
probe_collection: spec.probe_collection,
index_collection: spec.index_collection,
join_filters: &[],
emit_unmatched_right: spec.emit_unmatched_right,
},
results,
index_matched,
);
batch.clear();
*batch_bytes = 0;
};
probe_source.for_each(self, |id, bytes| {
batch_bytes = batch_bytes
.saturating_add(bytes.len())
.saturating_add(id.len());
batch.push((String::new(), bytes.to_vec()));
if budget_exceeded(batch_bytes, budget) {
flush(
&mut batch,
&mut batch_bytes,
&mut results,
&mut index_matched,
);
}
Ok(())
})?;
flush(
&mut batch,
&mut batch_bytes,
&mut results,
&mut index_matched,
);
if is_right && spec.emit_unmatched_right {
emit_unmatched_right_into(
&ProbeParams {
probe_docs: &[],
index: &index,
index_docs: build_docs,
probe_keys: spec.probe_keys,
join_type: spec.join_type,
limit: spec.limit,
probe_collection: spec.probe_collection,
index_collection: spec.index_collection,
join_filters: &[],
emit_unmatched_right: spec.emit_unmatched_right,
},
&mut results,
&index_matched,
);
}
Ok(results)
}
}