Skip to content

Commit 50ac363

Browse files
committed
frame: store custom payload's values as Bytes
So far, Vec<u8> was used as the type for custom payload's values. Bytes are better because: - they allow shared ownership owned those values, - they fit the new deserialization framework (they are required to create a `FrameSlice`), which will allow migrating raw tablets parsing to the new deserialization framework.
1 parent e99d697 commit 50ac363

File tree

4 files changed

+21
-14
lines changed

4 files changed

+21
-14
lines changed

scylla-cql/src/frame/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ pub struct ResponseBodyWithExtensions {
184184
pub trace_id: Option<Uuid>,
185185
pub warnings: Vec<String>,
186186
pub body: Bytes,
187-
pub custom_payload: Option<HashMap<String, Vec<u8>>>,
187+
pub custom_payload: Option<HashMap<String, Bytes>>,
188188
}
189189

190190
pub fn parse_response_body_extensions(

scylla-cql/src/frame/types.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
use super::frame_errors::LowLevelDeserializationError;
44
use super::TryFromPrimitiveError;
55
use byteorder::{BigEndian, ReadBytesExt};
6+
use bytes::Bytes;
7+
#[cfg(test)]
8+
use bytes::BytesMut;
69
use bytes::{Buf, BufMut};
710
use std::collections::HashMap;
811
use std::convert::TryFrom;
@@ -314,12 +317,12 @@ pub fn write_short_bytes(v: &[u8], buf: &mut impl BufMut) -> Result<(), std::num
314317

315318
pub fn read_bytes_map(
316319
buf: &mut &[u8],
317-
) -> Result<HashMap<String, Vec<u8>>, LowLevelDeserializationError> {
320+
) -> Result<HashMap<String, Bytes>, LowLevelDeserializationError> {
318321
let len = read_short_length(buf)?;
319322
let mut v = HashMap::with_capacity(len);
320323
for _ in 0..len {
321324
let key = read_string(buf)?.to_owned();
322-
let val = read_bytes(buf)?.to_owned();
325+
let val = Bytes::copy_from_slice(read_bytes(buf)?);
323326
v.insert(key, val);
324327
}
325328
Ok(v)
@@ -344,10 +347,10 @@ where
344347
#[test]
345348
fn type_bytes_map() {
346349
let mut val = HashMap::new();
347-
val.insert("".to_owned(), vec![]);
348-
val.insert("EXTENSION1".to_owned(), vec![1, 2, 3]);
349-
val.insert("EXTENSION2".to_owned(), vec![4, 5, 6]);
350-
let mut buf = Vec::new();
350+
val.insert("".to_owned(), Bytes::new());
351+
val.insert("EXTENSION1".to_owned(), Bytes::from_static(&[1, 2, 3]));
352+
val.insert("EXTENSION2".to_owned(), Bytes::from_static(&[4, 5, 6]));
353+
let mut buf = BytesMut::new();
351354
write_bytes_map(&val, &mut buf).unwrap();
352355
assert_eq!(read_bytes_map(&mut &*buf).unwrap(), val);
353356
}

scylla/src/transport/connection.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ pub(crate) struct QueryResponse {
217217
pub(crate) tracing_id: Option<Uuid>,
218218
pub(crate) warnings: Vec<String>,
219219
#[allow(dead_code)] // This is not exposed to user (yet?)
220-
pub(crate) custom_payload: Option<HashMap<String, Vec<u8>>>,
220+
pub(crate) custom_payload: Option<HashMap<String, Bytes>>,
221221
}
222222

223223
// A QueryResponse in which response can not be Response::Error

scylla/src/transport/locator/tablets.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use bytes::Bytes;
12
use itertools::Itertools;
23
use lazy_static::lazy_static;
34
use scylla_cql::cql_to_rust::FromCqlVal;
@@ -52,10 +53,10 @@ const CUSTOM_PAYLOAD_TABLETS_V1_KEY: &str = "tablets-routing-v1";
5253

5354
impl RawTablet {
5455
pub(crate) fn from_custom_payload(
55-
payload: &HashMap<String, Vec<u8>>,
56+
payload: &HashMap<String, Bytes>,
5657
) -> Option<Result<RawTablet, TabletParsingError>> {
5758
let payload = payload.get(CUSTOM_PAYLOAD_TABLETS_V1_KEY)?;
58-
let cql_value = match deser_cql_value(&RAW_TABLETS_CQL_TYPE, &mut payload.as_slice()) {
59+
let cql_value = match deser_cql_value(&RAW_TABLETS_CQL_TYPE, &mut payload.as_ref()) {
5960
Ok(r) => r,
6061
Err(e) => return Some(Err(e.into())),
6162
};
@@ -590,6 +591,7 @@ mod tests {
590591
use std::collections::{HashMap, HashSet};
591592
use std::sync::Arc;
592593

594+
use bytes::Bytes;
593595
use scylla_cql::frame::response::result::{ColumnType, CqlValue, TableSpec};
594596
use scylla_cql::types::serialize::value::SerializeValue;
595597
use scylla_cql::types::serialize::CellWriter;
@@ -618,8 +620,10 @@ mod tests {
618620

619621
#[test]
620622
fn test_raw_tablet_deser_trash() {
621-
let custom_payload =
622-
HashMap::from([(CUSTOM_PAYLOAD_TABLETS_V1_KEY.to_string(), vec![1, 2, 3])]);
623+
let custom_payload = HashMap::from([(
624+
CUSTOM_PAYLOAD_TABLETS_V1_KEY.to_string(),
625+
Bytes::from_static(&[1, 2, 3]),
626+
)]);
623627
assert_matches::assert_matches!(
624628
RawTablet::from_custom_payload(&custom_payload),
625629
Some(Err(TabletParsingError::Deserialization(_)))
@@ -648,7 +652,7 @@ mod tests {
648652
SerializeValue::serialize(&value, &col_type, CellWriter::new(&mut data)).unwrap();
649653
debug!("{:?}", data);
650654

651-
custom_payload.insert(CUSTOM_PAYLOAD_TABLETS_V1_KEY.to_string(), data);
655+
custom_payload.insert(CUSTOM_PAYLOAD_TABLETS_V1_KEY.to_string(), Bytes::from(data));
652656

653657
assert_matches::assert_matches!(
654658
RawTablet::from_custom_payload(&custom_payload),
@@ -688,7 +692,7 @@ mod tests {
688692
// Skipping length because `SerializeValue::serialize` adds length at the
689693
// start of serialized value while Scylla sends the value without initial
690694
// length.
691-
data[4..].to_vec(),
695+
Bytes::copy_from_slice(&data[4..]),
692696
);
693697

694698
let tablet = RawTablet::from_custom_payload(&custom_payload)

0 commit comments

Comments
 (0)