Skip to content

Commit 4e0044f

Browse files
committed
refactor: projection executor to reuse arena tmp values buffer
1 parent f5793f6 commit 4e0044f

3 files changed

Lines changed: 36 additions & 19 deletions

File tree

src/execution/dql/join/nested_loop_join.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
//! [`JoinType::RightOuter`], [`JoinType::Cross`], [`JoinType::Full`].
1717
1818
use crate::errors::DatabaseError;
19-
use crate::execution::dql::projection::Projection;
2019
use crate::execution::{
2120
build_read, ExecArena, ExecId, ExecNode, ExecutionCaches, ExecutorNode, ReadExecutor,
2221
};
@@ -65,10 +64,14 @@ impl EqualCondition {
6564
if self.on_left_keys.is_empty() {
6665
return Ok(true);
6766
}
68-
let left_values = Projection::projection(left_tuple, &self.on_left_keys)?;
69-
let right_values = Projection::projection(right_tuple, &self.on_right_keys)?;
7067

71-
Ok(left_values == right_values)
68+
for (left_expr, right_expr) in self.on_left_keys.iter().zip(self.on_right_keys.iter()) {
69+
if left_expr.eval(Some(left_tuple))? != right_expr.eval(Some(right_tuple))? {
70+
return Ok(false);
71+
}
72+
}
73+
74+
Ok(true)
7275
}
7376
}
7477

@@ -458,6 +461,7 @@ mod test {
458461
use crate::utils::lru::SharedLruCache;
459462
use std::collections::HashSet;
460463
use std::hash::RandomState;
464+
use std::sync::Arc;
461465
use tempfile::TempDir;
462466

463467
fn optimize_exprs(plan: LogicalPlan) -> Result<LogicalPlan, DatabaseError> {

src/execution/dql/projection.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ use crate::planner::LogicalPlan;
2020
use crate::storage::Transaction;
2121
use crate::types::tuple::Tuple;
2222
use crate::types::value::DataValue;
23+
2324
pub struct Projection {
2425
exprs: Vec<ScalarExpression>,
2526
input: ExecId,
26-
scratch: Tuple,
2727
}
2828

2929
impl<'a, T: Transaction + 'a> ExecutorNode<'a, T> for Projection {
@@ -36,11 +36,7 @@ impl<'a, T: Transaction + 'a> ExecutorNode<'a, T> for Projection {
3636
transaction: *mut T,
3737
) -> ExecId {
3838
let input = build_read(arena, input, cache, transaction);
39-
arena.push(ExecNode::Projection(Projection {
40-
exprs,
41-
input,
42-
scratch: Tuple::default(),
43-
}))
39+
arena.push(ExecNode::Projection(Projection { exprs, input }))
4440
}
4541

4642
fn next_tuple(&mut self, arena: &mut ExecArena<'a, T>) -> Result<(), DatabaseError> {
@@ -49,15 +45,14 @@ impl<'a, T: Transaction + 'a> ExecutorNode<'a, T> for Projection {
4945
return Ok(());
5046
}
5147

52-
std::mem::swap(&mut self.scratch, arena.result_tuple_mut());
53-
let tuple = &self.scratch;
54-
let output = arena.result_tuple_mut();
55-
output.pk.clone_from(&tuple.pk);
56-
output.values.clear();
57-
output.values.reserve(self.exprs.len());
58-
for expr in self.exprs.iter() {
59-
output.values.push(expr.eval(Some(tuple))?);
60-
}
48+
arena.with_projection_tmp(|tuple, projection_tmp| {
49+
projection_tmp.clear();
50+
projection_tmp.reserve(self.exprs.len());
51+
for expr in self.exprs.iter() {
52+
projection_tmp.push(expr.eval(Some(tuple))?);
53+
}
54+
Ok::<_, DatabaseError>(())
55+
})?;
6156
arena.resume();
6257
Ok(())
6358
}

src/execution/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ use crate::planner::LogicalPlan;
6363
use crate::storage::{StatisticsMetaCache, TableCache, Transaction, ViewCache};
6464
use crate::types::index::RuntimeIndexProbe;
6565
use crate::types::tuple::Tuple;
66+
use crate::types::value::DataValue;
6667

6768
pub(crate) type ExecutionCaches<'a> = (&'a TableCache, &'a ViewCache, &'a StatisticsMetaCache);
6869
pub(crate) type ExecId = usize;
@@ -264,6 +265,7 @@ impl<'a, T: Transaction + 'a> ExecNode<'a, T> {
264265
pub(crate) struct ExecArena<'a, T: Transaction + 'a> {
265266
nodes: Vec<ExecNode<'a, T>>,
266267
result: ExecResult,
268+
projection_tmp: Vec<DataValue>,
267269
cache: Option<ExecutionCaches<'a>>,
268270
transaction: *mut T,
269271
runtime_probe_stack: Vec<RuntimeIndexProbe>,
@@ -274,6 +276,7 @@ impl<'a, T: Transaction + 'a> Default for ExecArena<'a, T> {
274276
Self {
275277
nodes: Vec::new(),
276278
result: ExecResult::default(),
279+
projection_tmp: Vec::new(),
277280
cache: None,
278281
transaction: std::ptr::null_mut(),
279282
runtime_probe_stack: Vec::new(),
@@ -344,6 +347,21 @@ impl<'a, T: Transaction + 'a> ExecArena<'a, T> {
344347
&mut self.result.tuple
345348
}
346349

350+
#[inline]
351+
pub(crate) fn with_projection_tmp<R, E>(
352+
&mut self,
353+
f: impl FnOnce(&Tuple, &mut Vec<DataValue>) -> Result<R, E>,
354+
) -> Result<R, E> {
355+
let ExecArena {
356+
result,
357+
projection_tmp,
358+
..
359+
} = self;
360+
let ret = f(&result.tuple, projection_tmp)?;
361+
std::mem::swap(&mut result.tuple.values, projection_tmp);
362+
Ok(ret)
363+
}
364+
347365
#[inline]
348366
pub(crate) fn resume(&mut self) {
349367
self.result.status = Some(ExecStatus::Continue);

0 commit comments

Comments
 (0)