Skip to content

Commit 1178d79

Browse files
authored
implement the complete keyspace feature (#439)
Signed-off-by: Andy Lok <[email protected]>
1 parent bbaf317 commit 1178d79

35 files changed

+953
-562
lines changed

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@ prometheus = { version = "0.13", default-features = false }
3838
prost = "0.12"
3939
rand = "0.8"
4040
regex = "1"
41+
reqwest = { version = "0.11", features = ["json", "native-tls-vendored"] }
4142
semver = "1.0"
4243
serde = "1.0"
4344
serde_derive = "1.0"
45+
serde_json = "1"
46+
take_mut = "0.2.2"
4447
thiserror = "1"
4548
tokio = { version = "1", features = ["sync", "rt-multi-thread", "macros"] }
4649
tonic = { version = "0.10", features = ["tls"] }
@@ -51,9 +54,7 @@ env_logger = "0.10"
5154
fail = { version = "0.4", features = ["failpoints"] }
5255
proptest = "1"
5356
proptest-derive = "0.3"
54-
reqwest = { version = "0.11", default-features = false, features = [
55-
"native-tls-vendored",
56-
] }
57+
rstest = "0.18.2"
5758
serde_json = "1"
5859
serial_test = "0.5.0"
5960
simple_logger = "1"

config/tikv.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ max-open-files = 10000
1515

1616
[raftdb]
1717
max-open-files = 10000
18+
19+
[storage]
20+
api-version = 2
21+
enable-ttl = true

examples/pessimistic.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ async fn main() {
2424
Config::default().with_security(ca, cert, key)
2525
} else {
2626
Config::default()
27-
};
27+
}
28+
// This example uses the default keyspace, so api-v2 must be enabled on the server.
29+
.with_default_keyspace();
2830

2931
// init
3032
let client = Client::new_with_config(args.pd, config)

examples/raw.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ async fn main() -> Result<()> {
3131
Config::default().with_security(ca, cert, key)
3232
} else {
3333
Config::default()
34-
};
34+
}
35+
// This example uses the default keyspace, so api-v2 must be enabled on the server.
36+
.with_default_keyspace();
3537

3638
// When we first create a client we receive a `Connect` structure which must be resolved before
3739
// the client is actually connected and usable.
@@ -136,6 +138,8 @@ async fn main() -> Result<()> {
136138
);
137139
println!("Scanning batch scan from {batch_scan_keys:?} gives: {vals:?}");
138140

139-
// Cleanly exit.
141+
// Delete all keys in the whole range.
142+
client.delete_range("".to_owned().."".to_owned()).await?;
143+
140144
Ok(())
141145
}

examples/transaction.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ async fn main() {
8787
Config::default().with_security(ca, cert, key)
8888
} else {
8989
Config::default()
90-
};
90+
}
91+
// This example uses the default keyspace, so api-v2 must be enabled on the server.
92+
.with_default_keyspace();
9193

9294
let txn = Client::new_with_config(args.pd, config)
9395
.await

src/common/errors.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,14 @@ pub enum Error {
5050
/// Wraps a `grpcio::Error`.
5151
#[error("gRPC error: {0}")]
5252
Grpc(#[from] tonic::transport::Error),
53+
/// Wraps a `reqwest::Error`.
54+
#[error("http error: {0}")]
55+
Http(#[from] reqwest::Error),
5356
/// Wraps a `grpcio::Error`.
5457
#[error("gRPC api error: {0}")]
5558
GrpcAPI(#[from] tonic::Status),
59+
#[error("Http request failed: unknown respond {0}")]
60+
UnknownHttpRespond(String),
5661
/// Wraps a `grpcio::Error`.
5762
#[error("url error: {0}")]
5863
Url(#[from] tonic::codegen::http::uri::InvalidUri),

src/config.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub struct Config {
1919
pub cert_path: Option<PathBuf>,
2020
pub key_path: Option<PathBuf>,
2121
pub timeout: Duration,
22+
pub keyspace: Option<String>,
2223
}
2324

2425
const DEFAULT_REQUEST_TIMEOUT: Duration = Duration::from_secs(2);
@@ -30,6 +31,7 @@ impl Default for Config {
3031
cert_path: None,
3132
key_path: None,
3233
timeout: DEFAULT_REQUEST_TIMEOUT,
34+
keyspace: None,
3335
}
3436
}
3537
}
@@ -83,4 +85,21 @@ impl Config {
8385
self.timeout = timeout;
8486
self
8587
}
88+
89+
/// Set to use default keyspace.
90+
///
91+
/// Server should enable `storage.api-version = 2` to use this feature.
92+
#[must_use]
93+
pub fn with_default_keyspace(self) -> Self {
94+
self.with_keyspace("DEFAULT")
95+
}
96+
97+
/// Set the use keyspace for the client.
98+
///
99+
/// Server should enable `storage.api-version = 2` to use this feature.
100+
#[must_use]
101+
pub fn with_keyspace(mut self, keyspace: &str) -> Self {
102+
self.keyspace = Some(keyspace.to_owned());
103+
self
104+
}
86105
}

src/kv/bound_range.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,11 @@ impl BoundRange {
136136
pub fn into_keys(self) -> (Key, Option<Key>) {
137137
let start = match self.from {
138138
Bound::Included(v) => v,
139-
Bound::Excluded(mut v) => {
140-
v.push_zero();
141-
v
142-
}
139+
Bound::Excluded(v) => v.next_key(),
143140
Bound::Unbounded => Key::EMPTY,
144141
};
145142
let end = match self.to {
146-
Bound::Included(mut v) => {
147-
v.push_zero();
148-
Some(v)
149-
}
143+
Bound::Included(v) => Some(v.next_key()),
150144
Bound::Excluded(v) => Some(v),
151145
Bound::Unbounded => None,
152146
};

src/kv/key.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ pub struct Key(
7171
test,
7272
proptest(strategy = "any_with::<Vec<u8>>((size_range(_PROPTEST_KEY_MAX), ()))")
7373
)]
74-
pub(super) Vec<u8>,
74+
pub(crate) Vec<u8>,
7575
);
7676

7777
impl AsRef<Key> for kvrpcpb::Mutation {
@@ -98,10 +98,11 @@ impl Key {
9898

9999
/// Push a zero to the end of the key.
100100
///
101-
/// Extending a zero makes the new key the smallest key that is greater than than the original one, i.e. the succeeder.
101+
/// Extending a zero makes the new key the smallest key that is greater than than the original one.
102102
#[inline]
103-
pub(super) fn push_zero(&mut self) {
104-
self.0.push(0)
103+
pub(crate) fn next_key(mut self) -> Self {
104+
self.0.push(0);
105+
self
105106
}
106107

107108
/// Convert the key to a lower bound. The key is treated as inclusive.

src/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@
9494

9595
pub mod backoff;
9696
#[doc(hidden)]
97-
pub mod proto; // export `proto` to enable user customized codec
98-
#[doc(hidden)]
9997
pub mod raw;
10098
pub mod request;
10199
#[doc(hidden)]
@@ -106,6 +104,7 @@ mod compat;
106104
mod config;
107105
mod kv;
108106
mod pd;
107+
mod proto;
109108
mod region;
110109
mod region_cache;
111110
mod stats;
@@ -146,8 +145,6 @@ pub use crate::raw::Client as RawClient;
146145
#[doc(inline)]
147146
pub use crate::raw::ColumnFamily;
148147
#[doc(inline)]
149-
pub use crate::request::codec;
150-
#[doc(inline)]
151148
pub use crate::request::RetryOptions;
152149
#[doc(inline)]
153150
pub use crate::timestamp::Timestamp;

src/mock.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use crate::proto::metapb::RegionEpoch;
1818
use crate::proto::metapb::{self};
1919
use crate::region::RegionId;
2020
use crate::region::RegionWithLeader;
21-
use crate::request::codec::ApiV1TxnCodec;
2221
use crate::store::KvConnect;
2322
use crate::store::RegionStore;
2423
use crate::store::Request;
@@ -31,7 +30,7 @@ use crate::Timestamp;
3130

3231
/// Create a `PdRpcClient` with it's internals replaced with mocks so that the
3332
/// client can be tested without doing any RPC calls.
34-
pub async fn pd_rpc_client() -> PdRpcClient<ApiV1TxnCodec, MockKvConnect, MockCluster> {
33+
pub async fn pd_rpc_client() -> PdRpcClient<MockKvConnect, MockCluster> {
3534
let config = Config::default();
3635
PdRpcClient::new(
3736
config.clone(),
@@ -44,7 +43,6 @@ pub async fn pd_rpc_client() -> PdRpcClient<ApiV1TxnCodec, MockKvConnect, MockCl
4443
))
4544
},
4645
false,
47-
Some(ApiV1TxnCodec::default()),
4846
)
4947
.await
5048
.unwrap()
@@ -73,18 +71,9 @@ pub struct MockKvConnect;
7371

7472
pub struct MockCluster;
7573

74+
#[derive(new)]
7675
pub struct MockPdClient {
7776
client: MockKvClient,
78-
codec: ApiV1TxnCodec,
79-
}
80-
81-
impl MockPdClient {
82-
pub fn new(client: MockKvClient) -> MockPdClient {
83-
MockPdClient {
84-
client,
85-
codec: ApiV1TxnCodec::default(),
86-
}
87-
}
8877
}
8978

9079
#[async_trait]
@@ -113,7 +102,6 @@ impl MockPdClient {
113102
pub fn default() -> MockPdClient {
114103
MockPdClient {
115104
client: MockKvClient::default(),
116-
codec: ApiV1TxnCodec::default(),
117105
}
118106
}
119107

@@ -177,7 +165,6 @@ impl MockPdClient {
177165

178166
#[async_trait]
179167
impl PdClient for MockPdClient {
180-
type Codec = ApiV1TxnCodec;
181168
type KvClient = MockKvClient;
182169

183170
async fn map_region_to_store(self: Arc<Self>, region: RegionWithLeader) -> Result<RegionStore> {
@@ -228,7 +215,7 @@ impl PdClient for MockPdClient {
228215

229216
async fn invalidate_region_cache(&self, _ver_id: crate::region::RegionVerId) {}
230217

231-
fn get_codec(&self) -> &Self::Codec {
232-
&self.codec
218+
async fn get_keyspace_id(&self, _keyspace: &str) -> Result<u32> {
219+
unimplemented!()
233220
}
234221
}

0 commit comments

Comments
 (0)