11// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
22
3- use std:: any:: Any ;
4- use std:: ops:: Range ;
5- use std:: sync:: Arc ;
6- use std:: time:: Duration ;
7-
8- use async_trait:: async_trait;
9- use futures:: stream:: BoxStream ;
10- use tonic:: transport:: Channel ;
11-
123use super :: RawRpcRequest ;
134use crate :: collect_single;
5+ use crate :: kv:: KvPairTTL ;
146use crate :: pd:: PdClient ;
157use crate :: proto:: kvrpcpb;
168use crate :: proto:: metapb;
@@ -41,6 +33,13 @@ use crate::Key;
4133use crate :: KvPair ;
4234use crate :: Result ;
4335use crate :: Value ;
36+ use async_trait:: async_trait;
37+ use futures:: stream:: BoxStream ;
38+ use std:: any:: Any ;
39+ use std:: ops:: Range ;
40+ use std:: sync:: Arc ;
41+ use std:: time:: Duration ;
42+ use tonic:: transport:: Channel ;
4443
4544pub fn new_raw_get_request ( key : Vec < u8 > , cf : Option < ColumnFamily > ) -> kvrpcpb:: RawGetRequest {
4645 let mut req = kvrpcpb:: RawGetRequest :: default ( ) ;
@@ -190,23 +189,28 @@ impl KvRequest for kvrpcpb::RawBatchPutRequest {
190189}
191190
192191impl Shardable for kvrpcpb:: RawBatchPutRequest {
193- type Shard = Vec < kvrpcpb:: KvPair > ;
192+ type Shard = Vec < ( kvrpcpb:: KvPair , u64 ) > ;
194193
195194 fn shards (
196195 & self ,
197196 pd_client : & Arc < impl PdClient > ,
198197 ) -> BoxStream < ' static , Result < ( Self :: Shard , RegionStore ) > > {
199- let mut pairs = self . pairs . clone ( ) ;
200- pairs. sort_by ( |a, b| a. key . cmp ( & b. key ) ) ;
201- store_stream_for_keys (
202- pairs. into_iter ( ) . map ( Into :: < KvPair > :: into) ,
203- pd_client. clone ( ) ,
204- )
198+ let kvs = self . pairs . clone ( ) ;
199+ let ttls = self . ttls . clone ( ) ;
200+ let mut kv_ttl: Vec < KvPairTTL > = kvs
201+ . into_iter ( )
202+ . zip ( ttls)
203+ . map ( |( kv, ttl) | KvPairTTL ( kv, ttl) )
204+ . collect ( ) ;
205+ kv_ttl. sort_by ( |a, b| a. 0 . key . cmp ( & b. 0 . key ) ) ;
206+ store_stream_for_keys ( kv_ttl. into_iter ( ) , pd_client. clone ( ) )
205207 }
206208
207209 fn apply_shard ( & mut self , shard : Self :: Shard , store : & RegionStore ) -> Result < ( ) > {
210+ let ( pairs, ttls) = shard. into_iter ( ) . unzip ( ) ;
208211 self . set_leader ( & store. region_with_leader ) ?;
209- self . pairs = shard;
212+ self . pairs = pairs;
213+ self . ttls = ttls;
210214 Ok ( ( ) )
211215 }
212216}
@@ -531,21 +535,35 @@ impl_raw_rpc_request!(RawDeleteRangeRequest);
531535impl_raw_rpc_request ! ( RawCasRequest ) ;
532536
533537impl HasLocks for kvrpcpb:: RawGetResponse { }
538+
534539impl HasLocks for kvrpcpb:: RawBatchGetResponse { }
540+
535541impl HasLocks for kvrpcpb:: RawGetKeyTtlResponse { }
542+
536543impl HasLocks for kvrpcpb:: RawPutResponse { }
544+
537545impl HasLocks for kvrpcpb:: RawBatchPutResponse { }
546+
538547impl HasLocks for kvrpcpb:: RawDeleteResponse { }
548+
539549impl HasLocks for kvrpcpb:: RawBatchDeleteResponse { }
550+
540551impl HasLocks for kvrpcpb:: RawScanResponse { }
552+
541553impl HasLocks for kvrpcpb:: RawBatchScanResponse { }
554+
542555impl HasLocks for kvrpcpb:: RawDeleteRangeResponse { }
556+
543557impl HasLocks for kvrpcpb:: RawCasResponse { }
558+
544559impl HasLocks for kvrpcpb:: RawCoprocessorResponse { }
545560
546561#[ cfg( test) ]
547562mod test {
548563 use std:: any:: Any ;
564+ use std:: collections:: HashMap ;
565+ use std:: ops:: Deref ;
566+ use std:: sync:: Mutex ;
549567
550568 use super :: * ;
551569 use crate :: backoff:: DEFAULT_REGION_BACKOFF ;
@@ -555,7 +573,6 @@ mod test {
555573 use crate :: proto:: kvrpcpb;
556574 use crate :: request:: Keyspace ;
557575 use crate :: request:: Plan ;
558- use crate :: Key ;
559576
560577 #[ rstest:: rstest]
561578 #[ case( Keyspace :: Disable ) ]
@@ -600,4 +617,58 @@ mod test {
600617 assert_eq ! ( scan. len( ) , 49 ) ;
601618 // FIXME test the keys returned.
602619 }
620+
621+ #[ tokio:: test]
622+ async fn test_raw_batch_put ( ) -> Result < ( ) > {
623+ let region1_kvs = vec ! [ KvPair ( vec![ 9 ] . into( ) , vec![ 12 ] ) ] ;
624+ let region1_ttls = vec ! [ 0 ] ;
625+ let region2_kvs = vec ! [
626+ KvPair ( vec![ 11 ] . into( ) , vec![ 12 ] ) ,
627+ KvPair ( "FFF" . to_string( ) . as_bytes( ) . to_vec( ) . into( ) , vec![ 12 ] ) ,
628+ ] ;
629+ let region2_ttls = vec ! [ 0 , 1 ] ;
630+
631+ let expected_map = HashMap :: from ( [
632+ ( region1_kvs. clone ( ) , region1_ttls. clone ( ) ) ,
633+ ( region2_kvs. clone ( ) , region2_ttls. clone ( ) ) ,
634+ ] ) ;
635+
636+ let pairs: Vec < kvrpcpb:: KvPair > = [ region1_kvs, region2_kvs]
637+ . concat ( )
638+ . into_iter ( )
639+ . map ( |kv| kv. into ( ) )
640+ . collect ( ) ;
641+ let ttls = [ region1_ttls, region2_ttls] . concat ( ) ;
642+ let cf = ColumnFamily :: Default ;
643+
644+ let actual_map: Arc < Mutex < HashMap < Vec < KvPair > , Vec < u64 > > > > =
645+ Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ;
646+ let fut_actual_map = actual_map. clone ( ) ;
647+ let client = Arc :: new ( MockPdClient :: new ( MockKvClient :: with_dispatch_hook (
648+ move |req : & dyn Any | {
649+ let req: & kvrpcpb:: RawBatchPutRequest = req. downcast_ref ( ) . unwrap ( ) ;
650+ let kv_pair = req
651+ . pairs
652+ . clone ( )
653+ . into_iter ( )
654+ . map ( |p| p. into ( ) )
655+ . collect :: < Vec < KvPair > > ( ) ;
656+ let ttls = req. ttls . clone ( ) ;
657+ fut_actual_map. lock ( ) . unwrap ( ) . insert ( kv_pair, ttls) ;
658+ let resp = kvrpcpb:: RawBatchPutResponse :: default ( ) ;
659+ Ok ( Box :: new ( resp) as Box < dyn Any > )
660+ } ,
661+ ) ) ) ;
662+
663+ let batch_put_request =
664+ new_raw_batch_put_request ( pairs. clone ( ) , ttls. clone ( ) , Some ( cf) , false ) ;
665+ let keyspace = Keyspace :: Enable { keyspace_id : 0 } ;
666+ let plan = crate :: request:: PlanBuilder :: new ( client, keyspace, batch_put_request)
667+ . resolve_lock ( OPTIMISTIC_BACKOFF , keyspace)
668+ . retry_multi_region ( DEFAULT_REGION_BACKOFF )
669+ . plan ( ) ;
670+ let _ = plan. execute ( ) . await ;
671+ assert_eq ! ( actual_map. lock( ) . unwrap( ) . deref( ) , & expected_map) ;
672+ Ok ( ( ) )
673+ }
603674}
0 commit comments