add raw delete/batch_delete

Signed-off-by: ekexium <ekexium@gmail.com>
This commit is contained in:
ekexium 2020-09-07 15:38:50 +08:00
parent 266dbc4419
commit cee82fd81d
2 changed files with 80 additions and 8 deletions

View File

@ -164,9 +164,11 @@ mod test {
let mock_client = MockRawClient::new(Config::default()).await.unwrap();
// empty; get non-existent key
let res = mock_client.get("k1".to_owned()).await;
assert_eq!(res.unwrap().unwrap(), vec![]);
// empty; put then batch_get
let _ = mock_client
.put("k1".to_owned(), "v1".to_owned())
.await
@ -184,9 +186,7 @@ mod test {
assert_eq!(res[1].1, "v2".as_bytes());
assert_eq!(res[2].1, "".as_bytes());
let res = mock_client.get("k1".to_owned()).await;
assert_eq!(res.unwrap().unwrap(), "v1".as_bytes());
// k1,k2; batch_put then batch_get
let _ = mock_client
.batch_put(vec![
KvPair::new("k3".to_owned(), "v3".to_owned()),
@ -202,6 +202,49 @@ mod test {
assert_eq!(res[0].1, "v4".as_bytes());
assert_eq!(res[1].1, "v3".as_bytes());
// k1,k2,k3,k4; delete then get
let res = mock_client.delete("k3".to_owned()).await;
assert!(res.is_ok());
let res = mock_client.delete("key-not-exist".to_owned()).await;
assert!(res.is_err());
let res = mock_client.get("k3".to_owned()).await;
assert_eq!(res.unwrap().unwrap(), "".as_bytes());
// k1,k2,k4; batch_delete then batch_get
let res = mock_client
.batch_delete(vec![
"k1".to_owned(),
"k2".to_owned(),
"k3".to_owned(),
"k4".to_owned(),
])
.await;
assert!(res.is_err());
let res = mock_client
.batch_delete(vec![
"k1".to_owned(),
"k2".to_owned(),
"k4".to_owned(),
])
.await;
assert!(res.is_ok());
let res = mock_client
.batch_get(vec![
"k1".to_owned(),
"k2".to_owned(),
"k3".to_owned(),
"k4".to_owned(),
])
.await
.unwrap();
for i in 0..3 {
assert_eq!(res[i].1, "".as_bytes());
}
let _ = server.shutdown().await;
}
}

View File

@ -5,7 +5,7 @@ use grpcio::{ChannelBuilder, EnvBuilder, Environment, ResourceQuota, Server, Ser
use io::Read;
use kvproto::{kvrpcpb::*, tikvpb::*};
use std::{
collections::BTreeMap,
collections::HashMap,
io,
sync::{Arc, RwLock},
thread,
@ -16,13 +16,13 @@ pub const PORT: u16 = 50019;
#[derive(Debug, Clone)]
pub struct MockTikv {
data: Arc<RwLock<BTreeMap<Vec<u8>, Vec<u8>>>>,
data: Arc<RwLock<HashMap<Vec<u8>, Vec<u8>>>>,
}
impl MockTikv {
fn new() -> MockTikv {
MockTikv {
data: Arc::new(RwLock::new(BTreeMap::new())),
data: Arc::new(RwLock::new(HashMap::new())),
}
}
}
@ -272,7 +272,18 @@ impl Tikv for MockTikv {
req: kvproto::kvrpcpb::RawDeleteRequest,
sink: grpcio::UnarySink<kvproto::kvrpcpb::RawDeleteResponse>,
) {
todo!()
let key = req.get_key();
let mut data = self.data.write().unwrap();
let res = data.remove(key);
let mut resp = RawDeleteResponse::default();
if res.is_none() {
resp.set_error("Key not exist".to_owned());
}
let f = sink
.success(resp)
.map_err(move |e| panic!("failed to reply {:?}: {:?}", req, e))
.map(|_| ());
ctx.spawn(f)
}
fn raw_batch_delete(
@ -281,7 +292,25 @@ impl Tikv for MockTikv {
req: kvproto::kvrpcpb::RawBatchDeleteRequest,
sink: grpcio::UnarySink<kvproto::kvrpcpb::RawBatchDeleteResponse>,
) {
todo!()
let keys: &[Vec<u8>] = req.get_keys();
let mut data = self.data.write().unwrap();
let mut pairs = vec![];
keys.iter()
.filter(|&key| !data.contains_key(key))
.for_each(|key| pairs.push(std::str::from_utf8(key).unwrap()));
let mut resp = RawBatchDeleteResponse::default();
if pairs.is_empty() {
keys.iter().for_each(|key| {
data.remove(key).unwrap();
});
} else {
resp.set_error(format!("Non-existent keys:[{}]", pairs.join(", ")).to_owned());
}
let f = sink
.success(resp)
.map_err(move |e| panic!("failed to reply {:?}: {:?}", req, e))
.map(|_| ());
ctx.spawn(f)
}
fn raw_scan(