Skip to content

Commit 9a19bbd

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

File tree

4 files changed

+63
-9
lines changed

4 files changed

+63
-9
lines changed

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

+54-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,52 @@ 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 new(data: Vec<T>, drop_elements: bool) -> DropOptimizedVec<T> {
129+
DropOptimizedVec {
130+
data,
131+
drop_elements,
132+
}
133+
}
134+
135+
pub fn dropping(data: Vec<T>) -> DropOptimizedVec<T> {
136+
Self::new(data, true)
137+
}
138+
139+
pub fn non_dropping(data: Vec<T>) -> DropOptimizedVec<T> {
140+
Self::new(data, false)
141+
}
142+
143+
pub fn into_vec(mut self) -> Vec<T> {
144+
let mut vec = vec![];
145+
mem::swap(&mut self.data, &mut vec);
146+
vec
147+
}
148+
}
149+
150+
impl<T> Deref for DropOptimizedVec<T> {
151+
type Target = Vec<T>;
152+
153+
fn deref(&self) -> &Self::Target {
154+
&self.data
155+
}
156+
}
157+
158+
impl<T> Drop for DropOptimizedVec<T> {
159+
fn drop(&mut self) {
160+
if !self.drop_elements {
161+
unsafe { self.data.set_len(0); }
162+
}
163+
}
164+
}
165+
118166
impl<'a> TableSpec<'a> {
119167
pub const fn borrowed(ks: &'a str, table: &'a str) -> Self {
120168
Self {
@@ -355,7 +403,7 @@ impl CqlValue {
355403
pub fn as_list(&self) -> Option<&Vec<CqlValue>> {
356404
match self {
357405
Self::List(s) => Some(s),
358-
Self::Vector(s) => Some(s),
406+
Self::Vector(s) => Some(&s),
359407
_ => None,
360408
}
361409
}
@@ -385,7 +433,7 @@ impl CqlValue {
385433
match self {
386434
Self::List(s) => Some(s),
387435
Self::Set(s) => Some(s),
388-
Self::Vector(s) => Some(s),
436+
Self::Vector(s) => Some(s.into_vec()),
389437
_ => None,
390438
}
391439
}
@@ -836,11 +884,11 @@ pub fn deser_cql_value(
836884
let v = VectorIterator::<CqlValue>::deserialize_vector_of_float_to_vec_of_cql_value(
837885
typ, v,
838886
)?;
839-
CqlValue::Vector(v)
887+
CqlValue::Vector(DropOptimizedVec::non_dropping(v))
840888
}
841889
Vector(_, _) => {
842890
let v = Vec::<CqlValue>::deserialize(typ, v)?;
843-
CqlValue::Vector(v)
891+
CqlValue::Vector(DropOptimizedVec::dropping(v))
844892
}
845893
})
846894
}

scylla-cql/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub mod _macro_internal {
2929
pub use crate::frame::response::cql_to_rust::{
3030
FromCqlVal, FromCqlValError, FromRow, FromRowError,
3131
};
32-
pub use crate::frame::response::result::{ColumnSpec, ColumnType, CqlValue, Row};
32+
pub use crate::frame::response::result::{ColumnSpec, ColumnType, CqlValue, DropOptimizedVec, Row};
3333
pub use crate::frame::value::{
3434
LegacySerializedValues, SerializedResult, Value, ValueList, ValueTooBig,
3535
};

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)