Skip to content

Commit 72d1520

Browse files
andylokandyDillen Meijboom
authored and
Dillen Meijboom
committed
add ttl for raw client
Signed-off-by: andylokandy <[email protected]>
1 parent 027a7df commit 72d1520

File tree

9 files changed

+126
-20
lines changed

9 files changed

+126
-20
lines changed

src/kv/kvpair.rs

+25
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,25 @@ use proptest_derive::Arbitrary;
66
use std::{fmt, str};
77
use tikv_client_proto::kvrpcpb;
88

9+
/// A key/value pair with TTL (in seconds).
10+
///
11+
/// # Examples
12+
/// ```rust
13+
/// # use tikv_client::{Key, Value, KvPair};
14+
/// let key = "key".to_owned();
15+
/// let value = "value".to_owned();
16+
/// let pair = KvPair::new(key, value);
17+
/// let pair_with_ttl = pair.with_ttl(60);
18+
/// ```
19+
pub struct KvPairWithTTL(pub KvPair, pub u64);
20+
21+
/// Convert `Into<KvPair>` to a `KvPairWithTTL` with no TTL.
22+
impl<K: Into<KvPair>> From<K> for KvPairWithTTL {
23+
fn from(pair: K) -> Self {
24+
Self(pair.into(), 0)
25+
}
26+
}
27+
928
/// A key/value pair.
1029
///
1130
/// # Examples
@@ -78,6 +97,12 @@ impl KvPair {
7897
pub fn set_value(&mut self, v: impl Into<Value>) {
7998
self.1 = v.into();
8099
}
100+
101+
/// Convert the `KvPair` into a `KvPairWithTTL` with the given TTL (in seconds).
102+
#[inline]
103+
pub fn with_ttl(self, ttl: u64) -> KvPairWithTTL {
104+
KvPairWithTTL(self, ttl)
105+
}
81106
}
82107

83108
impl<K, V> From<(K, V)> for KvPair

src/kv/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ mod value;
99

1010
pub use bound_range::{BoundRange, IntoOwnedRange};
1111
pub use key::Key;
12-
pub use kvpair::KvPair;
12+
pub use kvpair::{KvPair, KvPairWithTTL};
1313
pub use value::Value;
1414

1515
struct HexRepr<'a>(pub &'a [u8]);

src/raw/client.rs

+24-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use tikv_client_proto::metapb;
1010
use crate::{
1111
backoff::DEFAULT_REGION_BACKOFF,
1212
config::Config,
13+
kv::KvPairWithTTL,
1314
pd::{PdClient, PdRpcClient},
1415
raw::lowering::*,
1516
request::{Collect, CollectSingle, Plan},
@@ -245,6 +246,17 @@ impl<PdC: PdClient> Client<PdC> {
245246
.map(|r| r.into_iter().map(Into::into).collect())
246247
}
247248

249+
pub async fn get_key_ttl_secs(&self, key: impl Into<Key>) -> Result<Option<u64>> {
250+
debug!(self.logger, "invoking raw get_key_ttl_secs request");
251+
let request = new_raw_get_key_ttl_request(key.into(), self.cf.clone());
252+
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
253+
.retry_multi_region(DEFAULT_REGION_BACKOFF)
254+
.merge(CollectSingle)
255+
.post_process_default()
256+
.plan();
257+
plan.execute().await
258+
}
259+
248260
/// Create a new 'put' request.
249261
///
250262
/// Once resolved this request will result in the setting of the value associated with the given key.
@@ -262,18 +274,25 @@ impl<PdC: PdClient> Client<PdC> {
262274
/// # });
263275
/// ```
264276
pub async fn put(&self, key: impl Into<Key>, value: impl Into<Value>) -> Result<()> {
265-
self.put_opt(key, value, DEFAULT_REGION_BACKOFF).await
277+
self.put_opt(key, value, DEFAULT_REGION_BACKOFF, 0).await
266278
}
267279

268-
/// Same as [`put`](Client::put) but with custom [`backoff`](crate::Backoff) strategy.
280+
/// Same as [`put`](Client::put) but with custom [`backoff`](crate::Backoff) strategy and ttl.
269281
pub async fn put_opt(
270282
&self,
271283
key: impl Into<Key>,
272284
value: impl Into<Value>,
273285
backoff: Backoff,
286+
ttl_secs: u64,
274287
) -> Result<()> {
275288
debug!(self.logger, "invoking raw put request");
276-
let request = new_raw_put_request(key.into(), value.into(), self.cf.clone(), self.atomic);
289+
let request = new_raw_put_request(
290+
key.into(),
291+
value.into(),
292+
self.cf.clone(),
293+
ttl_secs,
294+
self.atomic,
295+
);
277296
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
278297
.retry_multi_region(backoff)
279298
.merge(CollectSingle)
@@ -307,10 +326,10 @@ impl<PdC: PdClient> Client<PdC> {
307326
self.batch_put_opt(pairs, DEFAULT_REGION_BACKOFF).await
308327
}
309328

310-
/// Same as [`batch_put`](Client::batch_put) but with custom [`backoff`](crate::Backoff) strategy.
329+
/// Same as [`batch_put`](Client::batch_put) but with custom [`backoff`](crate::Backoff) strategy and the optionally add a TTL to the key value pairs.
311330
pub async fn batch_put_opt(
312331
&self,
313-
pairs: impl IntoIterator<Item = impl Into<KvPair>>,
332+
pairs: impl IntoIterator<Item = impl Into<KvPairWithTTL>>,
314333
backoff: Backoff,
315334
) -> Result<()> {
316335
debug!(self.logger, "invoking raw batch_put request");

src/raw/lowering.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{iter::Iterator, ops::Range, sync::Arc};
88

99
use tikv_client_proto::{kvrpcpb, metapb};
1010

11-
use crate::{raw::requests, BoundRange, ColumnFamily, Key, KvPair, Value};
11+
use crate::{kv::KvPairWithTTL, raw::requests, BoundRange, ColumnFamily, Key, Value};
1212

1313
pub fn new_raw_get_request(key: Key, cf: Option<ColumnFamily>) -> kvrpcpb::RawGetRequest {
1414
requests::new_raw_get_request(key.into(), cf)
@@ -21,21 +21,33 @@ pub fn new_raw_batch_get_request(
2121
requests::new_raw_batch_get_request(keys.map(Into::into).collect(), cf)
2222
}
2323

24+
pub fn new_raw_get_key_ttl_request(
25+
key: Key,
26+
cf: Option<ColumnFamily>,
27+
) -> kvrpcpb::RawGetKeyTtlRequest {
28+
requests::new_raw_get_key_ttl_request(key.into(), cf)
29+
}
30+
2431
pub fn new_raw_put_request(
2532
key: Key,
2633
value: Value,
2734
cf: Option<ColumnFamily>,
35+
ttl: u64,
2836
atomic: bool,
2937
) -> kvrpcpb::RawPutRequest {
30-
requests::new_raw_put_request(key.into(), value, cf, atomic)
38+
requests::new_raw_put_request(key.into(), value, cf, ttl, atomic)
3139
}
3240

3341
pub fn new_raw_batch_put_request(
34-
pairs: impl Iterator<Item = KvPair>,
42+
pairs_with_ttl: impl Iterator<Item = KvPairWithTTL>,
3543
cf: Option<ColumnFamily>,
3644
atomic: bool,
3745
) -> kvrpcpb::RawBatchPutRequest {
38-
requests::new_raw_batch_put_request(pairs.map(Into::into).collect(), cf, atomic)
46+
let (pairs, ttls) = pairs_with_ttl
47+
.into_iter()
48+
.map(|pair_with_ttl| (pair_with_ttl.0.into(), pair_with_ttl.1))
49+
.unzip();
50+
requests::new_raw_batch_put_request(pairs, cf, ttls, atomic)
3951
}
4052

4153
pub fn new_raw_delete_request(

src/raw/requests.rs

+48-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use tikv_client_store::Request;
1010

1111
use super::RawRpcRequest;
1212
use crate::{
13-
collect_first,
13+
collect_single,
1414
pd::PdClient,
1515
request::{
1616
plan::ResponseWithShard, Collect, CollectSingle, DefaultProcessor, KvRequest, Merge,
@@ -35,7 +35,7 @@ impl KvRequest for kvrpcpb::RawGetRequest {
3535
}
3636

3737
shardable_key!(kvrpcpb::RawGetRequest);
38-
collect_first!(kvrpcpb::RawGetResponse);
38+
collect_single!(kvrpcpb::RawGetResponse);
3939

4040
impl SingleKey for kvrpcpb::RawGetRequest {
4141
fn key(&self) -> &Vec<u8> {
@@ -84,16 +84,55 @@ impl Merge<kvrpcpb::RawBatchGetResponse> for Collect {
8484
}
8585
}
8686

87+
pub fn new_raw_get_key_ttl_request(
88+
key: Vec<u8>,
89+
cf: Option<ColumnFamily>,
90+
) -> kvrpcpb::RawGetKeyTtlRequest {
91+
let mut req = kvrpcpb::RawGetKeyTtlRequest::default();
92+
req.set_key(key);
93+
req.maybe_set_cf(cf);
94+
95+
req
96+
}
97+
98+
impl KvRequest for kvrpcpb::RawGetKeyTtlRequest {
99+
type Response = kvrpcpb::RawGetKeyTtlResponse;
100+
}
101+
102+
shardable_key!(kvrpcpb::RawGetKeyTtlRequest);
103+
collect_single!(kvrpcpb::RawGetKeyTtlResponse);
104+
105+
impl SingleKey for kvrpcpb::RawGetKeyTtlRequest {
106+
fn key(&self) -> &Vec<u8> {
107+
&self.key
108+
}
109+
}
110+
111+
impl Process<kvrpcpb::RawGetKeyTtlResponse> for DefaultProcessor {
112+
type Out = Option<u64>;
113+
114+
fn process(&self, input: Result<kvrpcpb::RawGetKeyTtlResponse>) -> Result<Self::Out> {
115+
let input = input?;
116+
Ok(if input.not_found {
117+
None
118+
} else {
119+
Some(input.ttl)
120+
})
121+
}
122+
}
123+
87124
pub fn new_raw_put_request(
88125
key: Vec<u8>,
89126
value: Vec<u8>,
90127
cf: Option<ColumnFamily>,
128+
ttl: u64,
91129
atomic: bool,
92130
) -> kvrpcpb::RawPutRequest {
93131
let mut req = kvrpcpb::RawPutRequest::default();
94132
req.set_key(key);
95133
req.set_value(value);
96134
req.maybe_set_cf(cf);
135+
req.set_ttl(ttl);
97136
req.set_for_cas(atomic);
98137

99138
req
@@ -104,7 +143,7 @@ impl KvRequest for kvrpcpb::RawPutRequest {
104143
}
105144

106145
shardable_key!(kvrpcpb::RawPutRequest);
107-
collect_first!(kvrpcpb::RawPutResponse);
146+
collect_single!(kvrpcpb::RawPutResponse);
108147
impl SingleKey for kvrpcpb::RawPutRequest {
109148
fn key(&self) -> &Vec<u8> {
110149
&self.key
@@ -114,11 +153,13 @@ impl SingleKey for kvrpcpb::RawPutRequest {
114153
pub fn new_raw_batch_put_request(
115154
pairs: Vec<kvrpcpb::KvPair>,
116155
cf: Option<ColumnFamily>,
156+
ttls: Vec<u64>,
117157
atomic: bool,
118158
) -> kvrpcpb::RawBatchPutRequest {
119159
let mut req = kvrpcpb::RawBatchPutRequest::default();
120160
req.set_pairs(pairs);
121161
req.maybe_set_cf(cf);
162+
req.set_ttls(ttls);
122163
req.set_for_cas(atomic);
123164

124165
req
@@ -168,7 +209,7 @@ impl KvRequest for kvrpcpb::RawDeleteRequest {
168209
}
169210

170211
shardable_key!(kvrpcpb::RawDeleteRequest);
171-
collect_first!(kvrpcpb::RawDeleteResponse);
212+
collect_single!(kvrpcpb::RawDeleteResponse);
172213
impl SingleKey for kvrpcpb::RawDeleteRequest {
173214
fn key(&self) -> &Vec<u8> {
174215
&self.key
@@ -314,7 +355,7 @@ impl KvRequest for kvrpcpb::RawCasRequest {
314355
}
315356

316357
shardable_key!(kvrpcpb::RawCasRequest);
317-
collect_first!(kvrpcpb::RawCasResponse);
358+
collect_single!(kvrpcpb::RawCasResponse);
318359
impl SingleKey for kvrpcpb::RawCasRequest {
319360
fn key(&self) -> &Vec<u8> {
320361
&self.key
@@ -445,6 +486,7 @@ macro_rules! impl_raw_rpc_request {
445486

446487
impl_raw_rpc_request!(RawGetRequest);
447488
impl_raw_rpc_request!(RawBatchGetRequest);
489+
impl_raw_rpc_request!(RawGetKeyTtlRequest);
448490
impl_raw_rpc_request!(RawPutRequest);
449491
impl_raw_rpc_request!(RawBatchPutRequest);
450492
impl_raw_rpc_request!(RawDeleteRequest);
@@ -456,6 +498,7 @@ impl_raw_rpc_request!(RawCasRequest);
456498

457499
impl HasLocks for kvrpcpb::RawGetResponse {}
458500
impl HasLocks for kvrpcpb::RawBatchGetResponse {}
501+
impl HasLocks for kvrpcpb::RawGetKeyTtlResponse {}
459502
impl HasLocks for kvrpcpb::RawPutResponse {}
460503
impl HasLocks for kvrpcpb::RawBatchPutResponse {}
461504
impl HasLocks for kvrpcpb::RawDeleteResponse {}

src/request/plan.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ pub struct Collect;
333333
pub struct CollectSingle;
334334

335335
#[macro_export]
336-
macro_rules! collect_first {
336+
macro_rules! collect_single {
337337
($type_: ty) => {
338338
impl Merge<$type_> for CollectSingle {
339339
type Out = $type_;

src/transaction/requests.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0.
22

33
use crate::{
4-
collect_first,
4+
collect_single,
55
pd::PdClient,
66
request::{
77
Collect, CollectSingle, CollectWithShard, DefaultProcessor, KvRequest, Merge, Process,
@@ -75,7 +75,7 @@ impl KvRequest for kvrpcpb::GetRequest {
7575
}
7676

7777
shardable_key!(kvrpcpb::GetRequest);
78-
collect_first!(kvrpcpb::GetResponse);
78+
collect_single!(kvrpcpb::GetResponse);
7979
impl SingleKey for kvrpcpb::GetRequest {
8080
fn key(&self) -> &Vec<u8> {
8181
&self.key
@@ -191,7 +191,7 @@ impl KvRequest for kvrpcpb::CleanupRequest {
191191
}
192192

193193
shardable_key!(kvrpcpb::CleanupRequest);
194-
collect_first!(kvrpcpb::CleanupResponse);
194+
collect_single!(kvrpcpb::CleanupResponse);
195195
impl SingleKey for kvrpcpb::CleanupRequest {
196196
fn key(&self) -> &Vec<u8> {
197197
&self.key
@@ -515,7 +515,7 @@ impl Shardable for kvrpcpb::TxnHeartBeatRequest {
515515
}
516516
}
517517

518-
collect_first!(TxnHeartBeatResponse);
518+
collect_single!(TxnHeartBeatResponse);
519519

520520
impl SingleKey for kvrpcpb::TxnHeartBeatRequest {
521521
fn key(&self) -> &Vec<u8> {

tikv-client-store/src/errors.rs

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ has_region_error!(kvrpcpb::DeleteRangeResponse);
5757
has_region_error!(kvrpcpb::GcResponse);
5858
has_region_error!(kvrpcpb::RawGetResponse);
5959
has_region_error!(kvrpcpb::RawBatchGetResponse);
60+
has_region_error!(kvrpcpb::RawGetKeyTtlResponse);
6061
has_region_error!(kvrpcpb::RawPutResponse);
6162
has_region_error!(kvrpcpb::RawBatchPutResponse);
6263
has_region_error!(kvrpcpb::RawDeleteResponse);
@@ -109,6 +110,7 @@ macro_rules! has_str_error {
109110
}
110111

111112
has_str_error!(kvrpcpb::RawGetResponse);
113+
has_str_error!(kvrpcpb::RawGetKeyTtlResponse);
112114
has_str_error!(kvrpcpb::RawPutResponse);
113115
has_str_error!(kvrpcpb::RawBatchPutResponse);
114116
has_str_error!(kvrpcpb::RawDeleteResponse);

tikv-client-store/src/request.rs

+5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ macro_rules! impl_request {
4747

4848
impl_request!(RawGetRequest, raw_get_async_opt, "raw_get");
4949
impl_request!(RawBatchGetRequest, raw_batch_get_async_opt, "raw_batch_get");
50+
impl_request!(
51+
RawGetKeyTtlRequest,
52+
raw_get_key_ttl_async_opt,
53+
"raw_get_key_ttl"
54+
);
5055
impl_request!(RawPutRequest, raw_put_async_opt, "raw_put");
5156
impl_request!(RawBatchPutRequest, raw_batch_put_async_opt, "raw_batch_put");
5257
impl_request!(RawDeleteRequest, raw_delete_async_opt, "raw_delete");

0 commit comments

Comments
 (0)