From 91ffb4e249e726593f1cfc726071fd0a2340f8cc Mon Sep 17 00:00:00 2001 From: Nikita Sivukhin Date: Wed, 22 Oct 2025 20:21:39 +0400 Subject: [PATCH] Revert "avoid allocations" This reverts commit dba195bdfa331ab3e3533031f96c1632517d24eb. --- core/types.rs | 34 +++++++++++----------------------- core/vdbe/execute.rs | 23 ++++++++++++++++------- core/vdbe/mod.rs | 13 +++++++------ 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/core/types.rs b/core/types.rs index 8183450fa..cb9c99082 100644 --- a/core/types.rs +++ b/core/types.rs @@ -219,12 +219,6 @@ pub enum ValueRef<'a> { Blob(&'a [u8]), } -impl<'a, 'b> From<&'b ValueRef<'a>> for ValueRef<'a> { - fn from(value: &'b ValueRef<'a>) -> Self { - *value - } -} - impl Debug for ValueRef<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -1820,15 +1814,12 @@ fn compare_records_int( /// 4. **Length comparison**: If strings are equal, compares lengths /// 5. **Remaining fields**: If first field is equal and more fields exist, /// delegates to `compare_records_generic()` with `skip=1` -fn compare_records_string<'a, T>( +fn compare_records_string( serialized: &ImmutableRecord, - unpacked: &'a [T], + unpacked: &[ValueRef], index_info: &IndexInfo, tie_breaker: std::cmp::Ordering, -) -> Result -where - ValueRef<'a>: From<&'a T>, -{ +) -> Result { turso_assert!( index_info.key_info.len() >= unpacked.len(), "index_info.key_info.len() < unpacked.len()" @@ -1856,7 +1847,7 @@ where return compare_records_generic(serialized, unpacked, index_info, 0, tie_breaker); } - let ValueRef::Text(rhs_text, _) = (&unpacked[0]).into() else { + let ValueRef::Text(rhs_text, _) = &unpacked[0] else { return compare_records_generic(serialized, unpacked, index_info, 0, tie_breaker); }; @@ -1935,16 +1926,13 @@ where /// The serialized and unpacked records do not have to contain the same number /// of fields. If all fields that appear in both records are equal, then /// `tie_breaker` is returned. -pub fn compare_records_generic<'a, T>( +pub fn compare_records_generic( serialized: &ImmutableRecord, - unpacked: &'a [T], + unpacked: &[ValueRef], index_info: &IndexInfo, skip: usize, tie_breaker: std::cmp::Ordering, -) -> Result -where - ValueRef<'a>: From<&'a T>, -{ +) -> Result { turso_assert!( index_info.key_info.len() >= unpacked.len(), "index_info.key_info.len() < unpacked.len()" @@ -1984,7 +1972,7 @@ where header_pos += bytes_read; let serial_type = SerialType::try_from(serial_type_raw)?; - let rhs_value = (&unpacked[field_idx]).into(); + let rhs_value = &unpacked[field_idx]; let lhs_value = match serial_type.kind() { SerialTypeKind::ConstInt0 => ValueRef::Integer(0), @@ -2006,14 +1994,14 @@ where } (ValueRef::Integer(lhs_int), ValueRef::Float(rhs_float)) => { - sqlite_int_float_compare(*lhs_int, rhs_float) + sqlite_int_float_compare(*lhs_int, *rhs_float) } (ValueRef::Float(lhs_float), ValueRef::Integer(rhs_int)) => { - sqlite_int_float_compare(rhs_int, *lhs_float).reverse() + sqlite_int_float_compare(*rhs_int, *lhs_float).reverse() } - _ => lhs_value.partial_cmp(&rhs_value).unwrap(), + _ => lhs_value.partial_cmp(rhs_value).unwrap(), }; let final_comparison = match index_info.key_info[field_idx].sort_order { diff --git a/core/vdbe/execute.rs b/core/vdbe/execute.rs index c671a81a7..247960d16 100644 --- a/core/vdbe/execute.rs +++ b/core/vdbe/execute.rs @@ -21,7 +21,7 @@ use crate::util::{ normalize_ident, rewrite_column_references_if_needed, rewrite_fk_parent_cols_if_self_ref, }; use crate::vdbe::insn::InsertFlags; -use crate::vdbe::TxnCleanup; +use crate::vdbe::{registers_to_ref_values, TxnCleanup}; use crate::vector::{vector32_sparse, vector_concat, vector_distance_jaccard, vector_slice}; use crate::{ error::{ @@ -3384,11 +3384,13 @@ pub fn op_idx_ge( let pc = if let Some(idx_record) = return_if_io!(cursor.record()) { // Create the comparison record from registers + let values = + registers_to_ref_values(&state.registers[*start_reg..*start_reg + *num_regs]); let tie_breaker = get_tie_breaker_from_idx_comp_op(insn); let ord = compare_records_generic( - &idx_record, // The serialized record from the index - &state.registers[*start_reg..*start_reg + *num_regs], // The record built from registers - cursor.get_index_info(), // Sort order flags + &idx_record, // The serialized record from the index + &values, // The record built from registers + cursor.get_index_info(), // Sort order flags 0, tie_breaker, )?; @@ -3450,10 +3452,12 @@ pub fn op_idx_le( let cursor = cursor.as_btree_mut(); let pc = if let Some(idx_record) = return_if_io!(cursor.record()) { + let values = + registers_to_ref_values(&state.registers[*start_reg..*start_reg + *num_regs]); let tie_breaker = get_tie_breaker_from_idx_comp_op(insn); let ord = compare_records_generic( &idx_record, - &state.registers[*start_reg..*start_reg + *num_regs], + &values, cursor.get_index_info(), 0, tie_breaker, @@ -3499,10 +3503,12 @@ pub fn op_idx_gt( let cursor = cursor.as_btree_mut(); let pc = if let Some(idx_record) = return_if_io!(cursor.record()) { + let values = + registers_to_ref_values(&state.registers[*start_reg..*start_reg + *num_regs]); let tie_breaker = get_tie_breaker_from_idx_comp_op(insn); let ord = compare_records_generic( &idx_record, - &state.registers[*start_reg..*start_reg + *num_regs], + &values, cursor.get_index_info(), 0, tie_breaker, @@ -3548,10 +3554,13 @@ pub fn op_idx_lt( let cursor = cursor.as_btree_mut(); let pc = if let Some(idx_record) = return_if_io!(cursor.record()) { + let values = + registers_to_ref_values(&state.registers[*start_reg..*start_reg + *num_regs]); + let tie_breaker = get_tie_breaker_from_idx_comp_op(insn); let ord = compare_records_generic( &idx_record, - &state.registers[*start_reg..*start_reg + *num_regs], + &values, cursor.get_index_info(), 0, tie_breaker, diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index 3aec5900c..b462b8f82 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -251,12 +251,6 @@ pub enum Register { Record(ImmutableRecord), } -impl<'a> From<&'a Register> for ValueRef<'a> { - fn from(value: &'a Register) -> Self { - value.get_value().as_ref() - } -} - impl Register { #[inline] pub fn is_null(&self) -> bool { @@ -1028,6 +1022,13 @@ fn make_record(registers: &[Register], start_reg: &usize, count: &usize) -> Immu ImmutableRecord::from_registers(regs, regs.len()) } +pub fn registers_to_ref_values<'a>(registers: &'a [Register]) -> Vec> { + registers + .iter() + .map(|reg| reg.get_value().as_ref()) + .collect() +} + #[instrument(skip(program), level = Level::DEBUG)] fn trace_insn(program: &Program, addr: InsnReference, insn: &Insn) { tracing::trace!(