Skip to content

Commit 453602c

Browse files
committed
tablets: migrate parsing to new deserialization framework
The new deserialization framework lets us elide a number of allocations there.
1 parent 50ac363 commit 453602c

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

scylla/src/transport/locator/tablets.rs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use bytes::Bytes;
22
use itertools::Itertools;
33
use lazy_static::lazy_static;
4-
use scylla_cql::cql_to_rust::FromCqlVal;
5-
use scylla_cql::frame::response::result::{deser_cql_value, ColumnType, TableSpec};
6-
use scylla_cql::types::deserialize::DeserializationError;
4+
use scylla_cql::frame::response::result::{ColumnType, TableSpec};
5+
use scylla_cql::types::deserialize::value::ListlikeIterator;
6+
use scylla_cql::types::deserialize::{
7+
DeserializationError, DeserializeValue, FrameSlice, TypeCheckError,
8+
};
79
use thiserror::Error;
810
use tracing::warn;
911
use uuid::Uuid;
@@ -12,12 +14,15 @@ use crate::routing::{Shard, Token};
1214
use crate::transport::Node;
1315

1416
use std::collections::{HashMap, HashSet};
17+
use std::ops::Deref;
1518
use std::sync::Arc;
1619

1720
#[derive(Error, Debug)]
1821
pub(crate) enum TabletParsingError {
1922
#[error(transparent)]
2023
Deserialization(#[from] DeserializationError),
24+
#[error(transparent)]
25+
TypeCheck(#[from] TypeCheckError),
2126
#[error("Shard id for tablet is negative: {0}")]
2227
ShardNum(i32),
2328
}
@@ -36,7 +41,8 @@ pub(crate) struct RawTablet {
3641
replicas: RawTabletReplicas,
3742
}
3843

39-
type RawTabletPayload = (i64, i64, Vec<(Uuid, i32)>);
44+
type RawTabletPayload<'frame, 'metadata> =
45+
(i64, i64, ListlikeIterator<'frame, 'metadata, (Uuid, i32)>);
4046

4147
lazy_static! {
4248
static ref RAW_TABLETS_CQL_TYPE: ColumnType<'static> = ColumnType::Tuple(vec![
@@ -56,26 +62,34 @@ impl RawTablet {
5662
payload: &HashMap<String, Bytes>,
5763
) -> Option<Result<RawTablet, TabletParsingError>> {
5864
let payload = payload.get(CUSTOM_PAYLOAD_TABLETS_V1_KEY)?;
59-
let cql_value = match deser_cql_value(&RAW_TABLETS_CQL_TYPE, &mut payload.as_ref()) {
60-
Ok(r) => r,
61-
Err(e) => return Some(Err(e.into())),
65+
66+
if let Err(err) =
67+
<RawTabletPayload as DeserializeValue<'_, '_>>::type_check(RAW_TABLETS_CQL_TYPE.deref())
68+
{
69+
return Some(Err(err.into()));
6270
};
6371

64-
// This could only fail if the type was wrong, but we do pass correct type
65-
// to `deser_cql_value`.
6672
let (first_token, last_token, replicas): RawTabletPayload =
67-
FromCqlVal::from_cql(cql_value).unwrap();
73+
match <RawTabletPayload as DeserializeValue<'_, '_>>::deserialize(
74+
RAW_TABLETS_CQL_TYPE.deref(),
75+
Some(FrameSlice::new(payload)),
76+
) {
77+
Ok(tuple) => tuple,
78+
Err(err) => return Some(Err(err.into())),
79+
};
6880

6981
let replicas = match replicas
70-
.into_iter()
71-
.map(|(uuid, shard_num)| match shard_num.try_into() {
72-
Ok(s) => Ok((uuid, s)),
73-
Err(_) => Err(shard_num),
82+
.map(|res| {
83+
res.map_err(TabletParsingError::from)
84+
.and_then(|(uuid, shard_num)| match shard_num.try_into() {
85+
Ok(s) => Ok((uuid, s)),
86+
Err(_) => Err(TabletParsingError::ShardNum(shard_num)),
87+
})
7488
})
75-
.collect::<Result<Vec<(Uuid, Shard)>, _>>()
89+
.collect::<Result<Vec<(Uuid, Shard)>, TabletParsingError>>()
7690
{
7791
Ok(r) => r,
78-
Err(shard_num) => return Some(Err(TabletParsingError::ShardNum(shard_num))),
92+
Err(err) => return Some(Err(err)),
7993
};
8094

8195
Some(Ok(RawTablet {

0 commit comments

Comments
 (0)