Skip to content

Commit 89aee91

Browse files
authored
Merge pull request #45 from tikv/scan-range-fix
Fix Range bug.
2 parents 9865e95 + cf7b5e3 commit 89aee91

File tree

1 file changed

+41
-27
lines changed

1 file changed

+41
-27
lines changed

src/kv.rs

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,6 @@ impl Key {
6868
pub(crate) fn into_inner(self) -> Vec<u8> {
6969
self.0
7070
}
71-
72-
#[inline]
73-
pub(crate) fn push(&mut self, v: u8) {
74-
self.0.push(v)
75-
}
76-
77-
#[inline]
78-
pub(crate) fn pop(&mut self) {
79-
self.0.pop();
80-
}
8171
}
8272

8373
impl From<Vec<u8>> for Key {
@@ -389,6 +379,33 @@ impl fmt::Debug for KvPair {
389379
/// which means all of the above types can be passed directly to those functions.
390380
pub trait KeyRange: Sized {
391381
fn into_bounds(self) -> (Bound<Key>, Bound<Key>);
382+
/// Ranges used in scanning TiKV have a particularity to them.
383+
///
384+
/// The **start** of a scan is inclusive, unless appended with an '\0', then it is exclusive.
385+
///
386+
/// The **end** of a scan is exclusive, unless appended with an '\0', then it is inclusive.
387+
///
388+
/// ```rust
389+
/// use tikv_client::{KeyRange, Key};
390+
/// // Exclusive
391+
/// let range = "a".."z";
392+
/// assert_eq!(
393+
/// range.into_keys().unwrap(),
394+
/// (Key::from("a"), Some(Key::from("z")))
395+
/// );
396+
/// // Inclusive
397+
/// let range = "a"..="z";
398+
/// assert_eq!(
399+
/// range.into_keys().unwrap(),
400+
/// (Key::from("a"), Some(Key::from("z\0")))
401+
/// );
402+
/// // Open
403+
/// let range = "a"..;
404+
/// assert_eq!(
405+
/// range.into_keys().unwrap(),
406+
/// (Key::from("a"), None)
407+
/// );
408+
// ```
392409
fn into_keys(self) -> Result<(Key, Option<Key>)> {
393410
range_to_keys(self.into_bounds())
394411
}
@@ -398,24 +415,17 @@ fn range_to_keys(range: (Bound<Key>, Bound<Key>)) -> Result<(Key, Option<Key>)>
398415
let start = match range.0 {
399416
Bound::Included(v) => v,
400417
Bound::Excluded(mut v) => {
401-
match v.last_mut() {
402-
None | Some(&mut u8::MAX) => v.push(0),
403-
Some(v) => *v += 1,
404-
}
418+
v.0.push(b"\0"[0]);
405419
v
406420
}
407421
Bound::Unbounded => Err(Error::invalid_key_range())?,
408422
};
409423
let end = match range.1 {
410-
Bound::Included(v) => Some(v),
411-
Bound::Excluded(mut v) => Some({
412-
match v.last_mut() {
413-
None => (),
414-
Some(&mut u8::MIN) => v.pop(),
415-
Some(v) => *v -= 1,
416-
}
417-
v
418-
}),
424+
Bound::Included(mut v) => {
425+
v.0.push(b"\0"[0]);
426+
Some(v)
427+
}
428+
Bound::Excluded(v) => Some(v),
419429
Bound::Unbounded => None,
420430
};
421431
Ok((start, end))
@@ -467,10 +477,14 @@ impl<T: Into<Key>> KeyRange for (Bound<T>, Bound<T>) {
467477
}
468478
}
469479

470-
fn convert_to_bound_key(b: Bound<impl Into<Key>>) -> Bound<Key> {
480+
fn convert_to_bound_key<K>(b: Bound<K>) -> Bound<Key>
481+
where
482+
K: Into<Key>,
483+
{
484+
use std::ops::Bound::*;
471485
match b {
472-
Bound::Included(k) => Bound::Included(k.into()),
473-
Bound::Excluded(k) => Bound::Excluded(k.into()),
474-
Bound::Unbounded => Bound::Unbounded,
486+
Included(k) => Included(k.into()),
487+
Excluded(k) => Excluded(k.into()),
488+
Unbounded => Unbounded,
475489
}
476490
}

0 commit comments

Comments
 (0)