Skip to content

Commit 8e89a68

Browse files
committed
Don't needlessly call element destructors of CqlValue::Vector
1 parent faea1f9 commit 8e89a68

File tree

3 files changed

+60
-8
lines changed

3 files changed

+60
-8
lines changed

scylla-cql/src/frame/response/result.rs

+52-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use crate::types::deserialize::value::{
1212
use crate::types::deserialize::{DeserializationError, FrameSlice};
1313
use bytes::{Buf, Bytes};
1414
use std::borrow::Cow;
15-
use std::{convert::TryInto, net::IpAddr, result::Result as StdResult, str};
15+
use std::{convert::TryInto, mem, net::IpAddr, result::Result as StdResult, str};
16+
use std::mem::ManuallyDrop;
17+
use std::ops::Deref;
1618
use uuid::Uuid;
1719

1820
#[derive(Debug)]
@@ -96,7 +98,7 @@ pub enum CqlValue {
9698
List(Vec<CqlValue>),
9799
Map(Vec<(CqlValue, CqlValue)>),
98100
Set(Vec<CqlValue>),
99-
Vector(Vec<CqlValue>),
101+
Vector(DropOptimizedVec<CqlValue>),
100102
UserDefinedType {
101103
keyspace: String,
102104
type_name: String,
@@ -115,6 +117,50 @@ pub enum CqlValue {
115117
Varint(CqlVarint),
116118
}
117119

120+
121+
#[derive(Clone, Debug, PartialEq)]
122+
pub struct DropOptimizedVec<T> {
123+
data: Vec<T>,
124+
drop_elements: bool
125+
}
126+
127+
impl<T> DropOptimizedVec<T> {
128+
pub fn dropping(data: Vec<T>) -> DropOptimizedVec<T> {
129+
DropOptimizedVec {
130+
data,
131+
drop_elements: true,
132+
}
133+
}
134+
pub fn non_dropping(data: Vec<T>) -> DropOptimizedVec<T> {
135+
DropOptimizedVec {
136+
data,
137+
drop_elements: false,
138+
}
139+
}
140+
141+
pub fn into_vec(mut self) -> Vec<T> {
142+
let mut vec = vec![];
143+
mem::swap(&mut self.data, &mut vec);
144+
vec
145+
}
146+
}
147+
148+
impl<T> Deref for DropOptimizedVec<T> {
149+
type Target = Vec<T>;
150+
151+
fn deref(&self) -> &Self::Target {
152+
&self.data
153+
}
154+
}
155+
156+
impl<T> Drop for DropOptimizedVec<T> {
157+
fn drop(&mut self) {
158+
if !self.drop_elements {
159+
unsafe { self.data.set_len(0); }
160+
}
161+
}
162+
}
163+
118164
impl<'a> TableSpec<'a> {
119165
pub const fn borrowed(ks: &'a str, table: &'a str) -> Self {
120166
Self {
@@ -355,7 +401,7 @@ impl CqlValue {
355401
pub fn as_list(&self) -> Option<&Vec<CqlValue>> {
356402
match self {
357403
Self::List(s) => Some(s),
358-
Self::Vector(s) => Some(s),
404+
Self::Vector(s) => Some(&s),
359405
_ => None,
360406
}
361407
}
@@ -385,7 +431,7 @@ impl CqlValue {
385431
match self {
386432
Self::List(s) => Some(s),
387433
Self::Set(s) => Some(s),
388-
Self::Vector(s) => Some(s),
434+
Self::Vector(s) => Some(s.into_vec()),
389435
_ => None,
390436
}
391437
}
@@ -836,11 +882,11 @@ pub fn deser_cql_value(
836882
let v = VectorIterator::<CqlValue>::deserialize_vector_of_float_to_vec_of_cql_value(
837883
typ, v,
838884
)?;
839-
CqlValue::Vector(v)
885+
CqlValue::Vector(DropOptimizedVec::non_dropping(v))
840886
}
841887
Vector(_, _) => {
842888
let v = Vec::<CqlValue>::deserialize(typ, v)?;
843-
CqlValue::Vector(v)
889+
CqlValue::Vector(DropOptimizedVec::dropping(v))
844890
}
845891
})
846892
}

scylla-cql/src/types/serialize/value.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
44
use std::fmt::Display;
55
use std::hash::BuildHasher;
66
use std::net::IpAddr;
7+
use std::ops::Deref;
78
use std::sync::Arc;
89

910
use thiserror::Error;
@@ -576,7 +577,7 @@ fn serialize_cql_value<'b>(
576577
}
577578
CqlValue::Uuid(u) => <_ as SerializeValue>::serialize(&u, typ, writer),
578579
CqlValue::Varint(v) => <_ as SerializeValue>::serialize(&v, typ, writer),
579-
CqlValue::Vector(v) => <_ as SerializeValue>::serialize(&v, typ, writer),
580+
CqlValue::Vector(v) => <_ as SerializeValue>::serialize(v.deref(), typ, writer),
580581
}
581582
}
582583

scylla/src/utils/pretty.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,12 @@ where
116116
.fmt(f)?;
117117
f.write_str(")")?;
118118
}
119-
CqlValue::List(v) | CqlValue::Vector(v) => {
119+
CqlValue::List(v) => {
120+
f.write_str("[")?;
121+
CommaSeparatedDisplayer(v.iter().map(CqlValueDisplayer)).fmt(f)?;
122+
f.write_str("]")?;
123+
}
124+
CqlValue::Vector(v) => {
120125
f.write_str("[")?;
121126
CommaSeparatedDisplayer(v.iter().map(CqlValueDisplayer)).fmt(f)?;
122127
f.write_str("]")?;

0 commit comments

Comments
 (0)