1
1
//! Provides types for dealing with CQL value deserialization.
2
2
3
- use std:: {
4
- collections:: { BTreeMap , BTreeSet , HashMap , HashSet } ,
5
- hash:: { BuildHasher , Hash } ,
6
- net:: IpAddr ,
7
- } ;
8
-
9
3
use bytes:: Bytes ;
4
+ use std:: { collections:: { BTreeMap , BTreeSet , HashMap , HashSet } , hash:: { BuildHasher , Hash } , mem, net:: IpAddr } ;
10
5
use uuid:: Uuid ;
11
6
12
7
use std:: fmt:: { Display , Pointer } ;
@@ -759,7 +754,7 @@ pub struct VectorIterator<'frame, T> {
759
754
}
760
755
761
756
impl < ' frame , T > VectorIterator < ' frame , T > {
762
- fn new (
757
+ pub fn new (
763
758
coll_typ : & ' frame ColumnType ,
764
759
elem_typ : & ' frame ColumnType ,
765
760
count : usize ,
@@ -774,6 +769,57 @@ impl<'frame, T> VectorIterator<'frame, T> {
774
769
phantom_data : std:: marker:: PhantomData ,
775
770
}
776
771
}
772
+
773
+ /// Faster specialization for deserializing a `vector<float>` into `Vec<CqlValue>`.
774
+ /// The generic code `Vec<CqlValue>::deserialize(...)` is much slower because it has to
775
+ /// match on the element type for every item in the vector.
776
+ /// Here we just hardcode `f32` and we can shortcut a lot of code.
777
+ ///
778
+ /// This could be nicer if Rust had generic type specialization in stable,
779
+ /// but for now we need a separate method.
780
+ pub fn deserialize_vector_of_float_to_vec_of_cql_value (
781
+ typ : & ' frame ColumnType ,
782
+ v : Option < FrameSlice < ' frame > > ,
783
+ ) -> Result < Vec < CqlValue > , DeserializationError > {
784
+
785
+ // Typecheck would make sure those never happen:
786
+ let ColumnType :: Vector ( elem_type, elem_count) = typ else {
787
+ panic ! ( "Wrong column type: {:?}. Expected vector<>" , typ) ;
788
+ } ;
789
+ if !matches ! ( elem_type. as_ref( ) , ColumnType :: Float ) {
790
+ panic ! ( "Wrong element type: {:?}. Expected float" , typ) ;
791
+ }
792
+
793
+ let elem_count = * elem_count as usize ;
794
+ let mut frame = v. map ( |s| s. as_slice ( ) ) . unwrap_or_default ( ) ;
795
+ let mut result = Vec :: with_capacity ( elem_count) ;
796
+
797
+ unsafe {
798
+ type Float = f32 ;
799
+
800
+ // Check length only once
801
+ if frame. len ( ) < size_of :: < Float > ( ) * elem_count {
802
+ return Err ( mk_deser_err :: < Vec < CqlValue > > (
803
+ typ,
804
+ BuiltinDeserializationErrorKind :: RawCqlBytesReadError (
805
+ LowLevelDeserializationError :: TooFewBytesReceived {
806
+ expected : size_of :: < Float > ( ) * elem_count,
807
+ received : frame. len ( ) ,
808
+ } ,
809
+ ) ,
810
+ ) ) ;
811
+ }
812
+ // We know we have enough elements in the buffer, so now we can skip the checks
813
+ for _ in 0 ..elem_count {
814
+ // we did check for frame length earlier, so we can safely not check again
815
+ let ( elem, remaining) = frame. split_first_chunk ( ) . unwrap_unchecked ( ) ;
816
+ let elem = Float :: from_be_bytes ( * elem) ;
817
+ result. push ( CqlValue :: Float ( elem) ) ;
818
+ frame = remaining;
819
+ }
820
+ }
821
+ Ok ( result)
822
+ }
777
823
}
778
824
779
825
impl < ' frame , T > DeserializeValue < ' frame > for VectorIterator < ' frame , T >
@@ -828,6 +874,7 @@ where
828
874
{
829
875
type Item = Result < T , DeserializationError > ;
830
876
877
+ #[ inline]
831
878
fn next ( & mut self ) -> Option < Self :: Item > {
832
879
let raw = self . raw_iter . next ( ) ?. map_err ( |err| {
833
880
mk_deser_err :: < Self > (
@@ -883,6 +930,7 @@ where
883
930
. and_then ( |it| it. collect :: < Result < _ , DeserializationError > > ( ) )
884
931
. map_err ( deser_error_replace_rust_name :: < Self > )
885
932
}
933
+
886
934
ColumnType :: Vector ( _, _) => VectorIterator :: < ' frame , T > :: deserialize ( typ, v)
887
935
. and_then ( |it| it. collect :: < Result < _ , DeserializationError > > ( ) )
888
936
. map_err ( deser_error_replace_rust_name :: < Self > ) ,
@@ -1435,6 +1483,7 @@ impl<'frame> VectorBytesSequenceIterator<'frame> {
1435
1483
impl < ' frame > Iterator for VectorBytesSequenceIterator < ' frame > {
1436
1484
type Item = Result < Option < FrameSlice < ' frame > > , LowLevelDeserializationError > ;
1437
1485
1486
+ #[ inline]
1438
1487
fn next ( & mut self ) -> Option < Self :: Item > {
1439
1488
self . remaining = self . remaining . checked_sub ( 1 ) ?;
1440
1489
Some ( self . slice . read_subslice ( self . elem_len ) )
0 commit comments