From e867f033830ee519323e89804b617f4a8b6cae2f Mon Sep 17 00:00:00 2001 From: Pavel Kirilin Date: Sat, 9 Sep 2023 22:30:09 +0400 Subject: [PATCH 1/2] Added custom hashers support for HashSet and HashMap. Signed-off-by: Pavel Kirilin --- scylla-cql/src/frame/response/cql_to_rust.rs | 8 +++-- scylla-cql/src/frame/value.rs | 31 +++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/scylla-cql/src/frame/response/cql_to_rust.rs b/scylla-cql/src/frame/response/cql_to_rust.rs index ec66d1e98e..f5facfef13 100644 --- a/scylla-cql/src/frame/response/cql_to_rust.rs +++ b/scylla-cql/src/frame/response/cql_to_rust.rs @@ -4,7 +4,7 @@ use bigdecimal::BigDecimal; use chrono::{DateTime, Duration, NaiveDate, TimeZone, Utc}; use num_bigint::BigInt; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; -use std::hash::Hash; +use std::hash::{BuildHasher, Hash}; use std::net::IpAddr; use thiserror::Error; use uuid::Uuid; @@ -213,14 +213,16 @@ impl + Eq + Hash, T2: FromCqlVal> FromCqlVal< } } -impl + Eq + Hash> FromCqlVal for HashSet { +impl + Eq + Hash, S: BuildHasher + Default> FromCqlVal + for HashSet +{ fn from_cql(cql_val: CqlValue) -> Result { cql_val .into_vec() .ok_or(FromCqlValError::BadCqlType)? .into_iter() .map(T::from_cql) - .collect::, FromCqlValError>>() + .collect::, FromCqlValError>>() } } diff --git a/scylla-cql/src/frame/value.rs b/scylla-cql/src/frame/value.rs index 9e927be3a3..4e00a6d56e 100644 --- a/scylla-cql/src/frame/value.rs +++ b/scylla-cql/src/frame/value.rs @@ -8,6 +8,7 @@ use num_bigint::BigInt; use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::convert::TryInto; +use std::hash::BuildHasher; use std::net::IpAddr; use thiserror::Error; use uuid::Uuid; @@ -662,13 +663,13 @@ fn serialize_list_or_set<'a, V: 'a + Value>( Ok(()) } -impl Value for HashSet { +impl Value for HashSet { fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { serialize_list_or_set(self.iter(), self.len(), buf) } } -impl Value for HashMap { +impl Value for HashMap { fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { serialize_map(self.iter(), self.len(), buf) } @@ -851,7 +852,7 @@ impl ValueList for Vec { } // Implement ValueList for maps, which serializes named values -macro_rules! impl_value_list_for_map { +macro_rules! impl_value_list_for_btree_map { ($map_type:ident, $key_type:ty) => { impl ValueList for $map_type<$key_type, T> { fn serialized(&self) -> SerializedResult<'_> { @@ -866,10 +867,26 @@ macro_rules! impl_value_list_for_map { }; } -impl_value_list_for_map!(HashMap, String); -impl_value_list_for_map!(HashMap, &str); -impl_value_list_for_map!(BTreeMap, String); -impl_value_list_for_map!(BTreeMap, &str); +// Implement ValueList for maps, which serializes named values +macro_rules! impl_value_list_for_hash_map { + ($map_type:ident, $key_type:ty) => { + impl ValueList for $map_type<$key_type, T, S> { + fn serialized(&self) -> SerializedResult<'_> { + let mut result = SerializedValues::with_capacity(self.len()); + for (key, val) in self { + result.add_named_value(key, val)?; + } + + Ok(Cow::Owned(result)) + } + } + }; +} + +impl_value_list_for_hash_map!(HashMap, String); +impl_value_list_for_hash_map!(HashMap, &str); +impl_value_list_for_btree_map!(BTreeMap, String); +impl_value_list_for_btree_map!(BTreeMap, &str); // Implement ValueList for tuples of Values of size up to 16 From 30c6e12d4920104271b45a099b2eb1feb083f6a0 Mon Sep 17 00:00:00 2001 From: Pavel Kirilin Date: Wed, 13 Sep 2023 00:00:19 +0400 Subject: [PATCH 2/2] Added custom hasher in one missing place, simplified proc_macro. Signed-off-by: Pavel Kirilin --- scylla-cql/src/frame/response/cql_to_rust.rs | 6 +++--- scylla-cql/src/frame/value.rs | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/scylla-cql/src/frame/response/cql_to_rust.rs b/scylla-cql/src/frame/response/cql_to_rust.rs index f5facfef13..9a95ffc803 100644 --- a/scylla-cql/src/frame/response/cql_to_rust.rs +++ b/scylla-cql/src/frame/response/cql_to_rust.rs @@ -200,12 +200,12 @@ impl> FromCqlVal for Vec { } } -impl + Eq + Hash, T2: FromCqlVal> FromCqlVal - for HashMap +impl + Eq + Hash, T2: FromCqlVal, T3: BuildHasher + Default> + FromCqlVal for HashMap { fn from_cql(cql_val: CqlValue) -> Result { let vec = cql_val.into_pair_vec().ok_or(FromCqlValError::BadCqlType)?; - let mut res = HashMap::with_capacity(vec.len()); + let mut res = HashMap::with_capacity_and_hasher(vec.len(), T3::default()); for (key, value) in vec { res.insert(T1::from_cql(key)?, T2::from_cql(value)?); } diff --git a/scylla-cql/src/frame/value.rs b/scylla-cql/src/frame/value.rs index 4e00a6d56e..e62469f4ef 100644 --- a/scylla-cql/src/frame/value.rs +++ b/scylla-cql/src/frame/value.rs @@ -853,8 +853,8 @@ impl ValueList for Vec { // Implement ValueList for maps, which serializes named values macro_rules! impl_value_list_for_btree_map { - ($map_type:ident, $key_type:ty) => { - impl ValueList for $map_type<$key_type, T> { + ($key_type:ty) => { + impl ValueList for BTreeMap<$key_type, T> { fn serialized(&self) -> SerializedResult<'_> { let mut result = SerializedValues::with_capacity(self.len()); for (key, val) in self { @@ -869,8 +869,8 @@ macro_rules! impl_value_list_for_btree_map { // Implement ValueList for maps, which serializes named values macro_rules! impl_value_list_for_hash_map { - ($map_type:ident, $key_type:ty) => { - impl ValueList for $map_type<$key_type, T, S> { + ($key_type:ty) => { + impl ValueList for HashMap<$key_type, T, S> { fn serialized(&self) -> SerializedResult<'_> { let mut result = SerializedValues::with_capacity(self.len()); for (key, val) in self { @@ -883,10 +883,10 @@ macro_rules! impl_value_list_for_hash_map { }; } -impl_value_list_for_hash_map!(HashMap, String); -impl_value_list_for_hash_map!(HashMap, &str); -impl_value_list_for_btree_map!(BTreeMap, String); -impl_value_list_for_btree_map!(BTreeMap, &str); +impl_value_list_for_hash_map!(String); +impl_value_list_for_hash_map!(&str); +impl_value_list_for_btree_map!(String); +impl_value_list_for_btree_map!(&str); // Implement ValueList for tuples of Values of size up to 16