Skip to content

Commit

Permalink
Don't needlessly call element destructors of CqlValue::Vector
Browse files Browse the repository at this point in the history
  • Loading branch information
pkolaczk committed Aug 15, 2024
1 parent faea1f9 commit 9a19bbd
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
60 changes: 54 additions & 6 deletions scylla-cql/src/frame/response/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use crate::types::deserialize::value::{
use crate::types::deserialize::{DeserializationError, FrameSlice};
use bytes::{Buf, Bytes};
use std::borrow::Cow;
use std::{convert::TryInto, net::IpAddr, result::Result as StdResult, str};
use std::{convert::TryInto, mem, net::IpAddr, result::Result as StdResult, str};
use std::mem::ManuallyDrop;
use std::ops::Deref;
use uuid::Uuid;

#[derive(Debug)]
Expand Down Expand Up @@ -96,7 +98,7 @@ pub enum CqlValue {
List(Vec<CqlValue>),
Map(Vec<(CqlValue, CqlValue)>),
Set(Vec<CqlValue>),
Vector(Vec<CqlValue>),
Vector(DropOptimizedVec<CqlValue>),
UserDefinedType {
keyspace: String,
type_name: String,
Expand All @@ -115,6 +117,52 @@ pub enum CqlValue {
Varint(CqlVarint),
}


#[derive(Clone, Debug, PartialEq)]
pub struct DropOptimizedVec<T> {
data: Vec<T>,
drop_elements: bool
}

impl<T> DropOptimizedVec<T> {
pub fn new(data: Vec<T>, drop_elements: bool) -> DropOptimizedVec<T> {
DropOptimizedVec {
data,
drop_elements,
}
}

pub fn dropping(data: Vec<T>) -> DropOptimizedVec<T> {
Self::new(data, true)
}

pub fn non_dropping(data: Vec<T>) -> DropOptimizedVec<T> {
Self::new(data, false)
}

pub fn into_vec(mut self) -> Vec<T> {
let mut vec = vec![];
mem::swap(&mut self.data, &mut vec);
vec
}
}

impl<T> Deref for DropOptimizedVec<T> {
type Target = Vec<T>;

fn deref(&self) -> &Self::Target {
&self.data
}
}

impl<T> Drop for DropOptimizedVec<T> {
fn drop(&mut self) {
if !self.drop_elements {
unsafe { self.data.set_len(0); }
}
}
}

impl<'a> TableSpec<'a> {
pub const fn borrowed(ks: &'a str, table: &'a str) -> Self {
Self {
Expand Down Expand Up @@ -355,7 +403,7 @@ impl CqlValue {
pub fn as_list(&self) -> Option<&Vec<CqlValue>> {
match self {
Self::List(s) => Some(s),
Self::Vector(s) => Some(s),
Self::Vector(s) => Some(&s),
_ => None,
}
}
Expand Down Expand Up @@ -385,7 +433,7 @@ impl CqlValue {
match self {
Self::List(s) => Some(s),
Self::Set(s) => Some(s),
Self::Vector(s) => Some(s),
Self::Vector(s) => Some(s.into_vec()),
_ => None,
}
}
Expand Down Expand Up @@ -836,11 +884,11 @@ pub fn deser_cql_value(
let v = VectorIterator::<CqlValue>::deserialize_vector_of_float_to_vec_of_cql_value(
typ, v,
)?;
CqlValue::Vector(v)
CqlValue::Vector(DropOptimizedVec::non_dropping(v))
}
Vector(_, _) => {
let v = Vec::<CqlValue>::deserialize(typ, v)?;
CqlValue::Vector(v)
CqlValue::Vector(DropOptimizedVec::dropping(v))
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion scylla-cql/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub mod _macro_internal {
pub use crate::frame::response::cql_to_rust::{
FromCqlVal, FromCqlValError, FromRow, FromRowError,
};
pub use crate::frame::response::result::{ColumnSpec, ColumnType, CqlValue, Row};
pub use crate::frame::response::result::{ColumnSpec, ColumnType, CqlValue, DropOptimizedVec, Row};
pub use crate::frame::value::{
LegacySerializedValues, SerializedResult, Value, ValueList, ValueTooBig,
};
Expand Down
3 changes: 2 additions & 1 deletion scylla-cql/src/types/serialize/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::fmt::Display;
use std::hash::BuildHasher;
use std::net::IpAddr;
use std::ops::Deref;
use std::sync::Arc;

use thiserror::Error;
Expand Down Expand Up @@ -576,7 +577,7 @@ fn serialize_cql_value<'b>(
}
CqlValue::Uuid(u) => <_ as SerializeValue>::serialize(&u, typ, writer),
CqlValue::Varint(v) => <_ as SerializeValue>::serialize(&v, typ, writer),
CqlValue::Vector(v) => <_ as SerializeValue>::serialize(&v, typ, writer),
CqlValue::Vector(v) => <_ as SerializeValue>::serialize(v.deref(), typ, writer),
}
}

Expand Down
7 changes: 6 additions & 1 deletion scylla/src/utils/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@ where
.fmt(f)?;
f.write_str(")")?;
}
CqlValue::List(v) | CqlValue::Vector(v) => {
CqlValue::List(v) => {
f.write_str("[")?;
CommaSeparatedDisplayer(v.iter().map(CqlValueDisplayer)).fmt(f)?;
f.write_str("]")?;
}
CqlValue::Vector(v) => {
f.write_str("[")?;
CommaSeparatedDisplayer(v.iter().map(CqlValueDisplayer)).fmt(f)?;
f.write_str("]")?;
Expand Down

0 comments on commit 9a19bbd

Please sign in to comment.