-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add upper bound for iterator #1060
add upper bound for iterator #1060
Conversation
Any benchmark? |
Please merge master to fix CI first. |
In theory, with upper bound key, iterator will return invalid as soon as it reach first key greater than or equal to the upper bound key, regardless of it is a normal key/value pair or deleted key. And I will bench it. |
LGTM |
@@ -324,7 +316,7 @@ mod tests { | |||
assert_eq!(data.len(), 2); | |||
assert_eq!(data, &base_data[1..3]); | |||
|
|||
let mut iter = snap.iter(); | |||
let mut iter = snap.iter(None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any test to cover not None key?
Ping @zhangjinpeng1987 |
87fd424
to
d5b5cf1
Compare
@BusyJay @disksing @siddontang PTAL |
pub fn iter(&self) -> RegionIterator { | ||
RegionIterator::new(self.snap.new_iterator(), self.region.clone()) | ||
pub fn iter(&self, upper_bound: Option<&[u8]>) -> RegionIterator { | ||
if upper_bound.is_none() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can use upper_bound.or_else()
to simplify the code.
end_key: &[u8], | ||
f: &mut F) | ||
-> Result<()> | ||
fn scan_impl<F>(&self, mut it: RegionIterator, start_key: &[u8], f: &mut F) -> Result<()> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have a test to check that we can't get the key >= upper bound key.
Ok(box RegionSnapshot::iter(self)) | ||
if upper_bound.is_none() { | ||
Ok(box RegionSnapshot::iter(self, | ||
Some(keys::enc_end_key(self.get_region()).as_slice()))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why enc_end_key
here?
@@ -179,7 +176,7 @@ impl<'a> MvccReader<'a> { | |||
where F: Fn(&Lock) -> bool | |||
{ | |||
if self.lock_cursor.is_none() { | |||
self.lock_cursor = Some(try!(self.snapshot.iter_cf(CF_LOCK))); | |||
self.lock_cursor = Some(try!(self.snapshot.iter_cf(CF_LOCK, None))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to add upper bound here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, RegionIterator will add region's end_key as upper bound.
.as_slice())), | ||
self.region.clone()) | ||
} else { | ||
RegionIterator::new(self.snap.new_iterator(upper_bound), self.region.clone()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think upper_bound
need to be encoded here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to add a new function in RegionIterator to handle the encode/decode thing.
cf: &str) | ||
-> RegionIterator<'a> { | ||
let encoded_upper = | ||
upper_bound.map_or_else(|| keys::enc_end_key(®ion), |v| keys::data_key(v)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just keys::data_key
should be ok.
@@ -140,7 +126,19 @@ pub struct RegionIterator<'a> { | |||
// we use rocksdb's style iterator, so omit the warning. | |||
#[allow(should_implement_trait)] | |||
impl<'a> RegionIterator<'a> { | |||
pub fn new(iter: DBIterator<'a>, region: Region) -> RegionIterator<'a> { | |||
pub fn new(snap: &'a Snapshot, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use two function new
and new_cf
here?
break; | ||
} | ||
} | ||
let expected_res = vec![(b"a1".to_vec(), b"v1".to_vec()), (b"a3".to_vec(), b"v3".to_vec())]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use base_data
like L373.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we can't, we add upper_bound for iterator and can't get all datas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can slice it like L328 :)
region: Region, | ||
upper_bound: Option<&[u8]>) | ||
-> RegionIterator<'a> { | ||
let encoded_upper = upper_bound.map_or_else(|| keys::enc_end_key(®ion), keys::data_key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if upper_bound is ""?
LGTM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rest LGTM
@@ -157,6 +159,14 @@ impl<'a> RegionIterator<'a> { | |||
} | |||
} | |||
|
|||
fn adjust_upper_bound(upper_bound: Option<&[u8]>) -> Option<&[u8]> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define as a local function instead.
LGTM |
Signed-off-by: hslam <[email protected]>
…by default (tikv#1060) * set override_priority with resource group priority Signed-off-by: glorv <[email protected]> * update go.mod Signed-off-by: glorv <[email protected]> * fix typo Signed-off-by: glorv <[email protected]> * fix Signed-off-by: glorv <[email protected]> --------- Signed-off-by: glorv <[email protected]>
Add upper bound for iterator to speed up region scan when there are a lot of deleted keys.