Revert "avoid allocations"

This reverts commit dba195bdfa.
This commit is contained in:
Nikita Sivukhin
2025-10-22 20:21:39 +04:00
parent 53957b6d22
commit 91ffb4e249
3 changed files with 34 additions and 36 deletions

View File

@@ -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<std::cmp::Ordering>
where
ValueRef<'a>: From<&'a T>,
{
) -> Result<std::cmp::Ordering> {
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<std::cmp::Ordering>
where
ValueRef<'a>: From<&'a T>,
{
) -> Result<std::cmp::Ordering> {
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 {

View File

@@ -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,

View File

@@ -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<ValueRef<'a>> {
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!(