1
1
// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
2
2
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
-
12
3
use super :: RawRpcRequest ;
13
4
use crate :: collect_single;
5
+ use crate :: kv:: KvPairTTL ;
14
6
use crate :: pd:: PdClient ;
15
7
use crate :: proto:: kvrpcpb;
16
8
use crate :: proto:: metapb;
@@ -41,6 +33,13 @@ use crate::Key;
41
33
use crate :: KvPair ;
42
34
use crate :: Result ;
43
35
use 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 ;
44
43
45
44
pub fn new_raw_get_request ( key : Vec < u8 > , cf : Option < ColumnFamily > ) -> kvrpcpb:: RawGetRequest {
46
45
let mut req = kvrpcpb:: RawGetRequest :: default ( ) ;
@@ -190,23 +189,28 @@ impl KvRequest for kvrpcpb::RawBatchPutRequest {
190
189
}
191
190
192
191
impl Shardable for kvrpcpb:: RawBatchPutRequest {
193
- type Shard = Vec < kvrpcpb:: KvPair > ;
192
+ type Shard = Vec < ( kvrpcpb:: KvPair , u64 ) > ;
194
193
195
194
fn shards (
196
195
& self ,
197
196
pd_client : & Arc < impl PdClient > ,
198
197
) -> 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 ( ) )
205
207
}
206
208
207
209
fn apply_shard ( & mut self , shard : Self :: Shard , store : & RegionStore ) -> Result < ( ) > {
210
+ let ( pairs, ttls) = shard. into_iter ( ) . unzip ( ) ;
208
211
self . set_leader ( & store. region_with_leader ) ?;
209
- self . pairs = shard;
212
+ self . pairs = pairs;
213
+ self . ttls = ttls;
210
214
Ok ( ( ) )
211
215
}
212
216
}
@@ -531,21 +535,35 @@ impl_raw_rpc_request!(RawDeleteRangeRequest);
531
535
impl_raw_rpc_request ! ( RawCasRequest ) ;
532
536
533
537
impl HasLocks for kvrpcpb:: RawGetResponse { }
538
+
534
539
impl HasLocks for kvrpcpb:: RawBatchGetResponse { }
540
+
535
541
impl HasLocks for kvrpcpb:: RawGetKeyTtlResponse { }
542
+
536
543
impl HasLocks for kvrpcpb:: RawPutResponse { }
544
+
537
545
impl HasLocks for kvrpcpb:: RawBatchPutResponse { }
546
+
538
547
impl HasLocks for kvrpcpb:: RawDeleteResponse { }
548
+
539
549
impl HasLocks for kvrpcpb:: RawBatchDeleteResponse { }
550
+
540
551
impl HasLocks for kvrpcpb:: RawScanResponse { }
552
+
541
553
impl HasLocks for kvrpcpb:: RawBatchScanResponse { }
554
+
542
555
impl HasLocks for kvrpcpb:: RawDeleteRangeResponse { }
556
+
543
557
impl HasLocks for kvrpcpb:: RawCasResponse { }
558
+
544
559
impl HasLocks for kvrpcpb:: RawCoprocessorResponse { }
545
560
546
561
#[ cfg( test) ]
547
562
mod test {
548
563
use std:: any:: Any ;
564
+ use std:: collections:: HashMap ;
565
+ use std:: ops:: Deref ;
566
+ use std:: sync:: Mutex ;
549
567
550
568
use super :: * ;
551
569
use crate :: backoff:: DEFAULT_REGION_BACKOFF ;
@@ -555,7 +573,6 @@ mod test {
555
573
use crate :: proto:: kvrpcpb;
556
574
use crate :: request:: Keyspace ;
557
575
use crate :: request:: Plan ;
558
- use crate :: Key ;
559
576
560
577
#[ rstest:: rstest]
561
578
#[ case( Keyspace :: Disable ) ]
@@ -600,4 +617,58 @@ mod test {
600
617
assert_eq ! ( scan. len( ) , 49 ) ;
601
618
// FIXME test the keys returned.
602
619
}
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
+ }
603
674
}
0 commit comments