Skip to content
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

Reverse iterators start off-by-one. #44

Open
palkeo opened this issue Dec 22, 2020 · 2 comments
Open

Reverse iterators start off-by-one. #44

palkeo opened this issue Dec 22, 2020 · 2 comments

Comments

@palkeo
Copy link

palkeo commented Dec 22, 2020

If I instantiate a reverse iterator like so:

            leveldb
                .iter(ReadOptions::new())
                .reverse()
                .from(start_key)
                .to(stop_key)

The first key it yields is the a key that's not in the [stop_key, start_key] range, but is actually the first one after start_key.

Example: if my db has keys ["a", "c", "e", "g"] and start_key is "d", stop_key is "a".
Then the first key yielded is "e", which is outside of the "d"->"a" range I am asking.

@skade
Copy link
Owner

skade commented Jan 6, 2021

This is probably a bug that slipped review. The leveldb iterator protocol is annoying in the way that the first step of iteration is a little different from the following.

@palkeo
Copy link
Author

palkeo commented Jan 7, 2021

Ok, so actually this happens only if the from() key is not present in the DB: then the first key given will be out of range. Otherwise it's fine.

This tests both this bug and that it ends before the to() passed.
When fixing it would be nice to test with .from(&9) as well, in my workaround this needed to be handled differently.

#[test]
fn test_key_iterator_iterate_reverse_from_to() {
  let tmp = tmpdir("key_iter");
  let database = &mut open_database(tmp.path(), true);
  db_put_simple(database, 2, &[2]);
  db_put_simple(database, 4, &[4]);
  db_put_simple(database, 6, &[6]);
  db_put_simple(database, 8, &[8]);

  let iterable: &mut Iterable<i32> = database;

  let read_opts = ReadOptions::new();
  let mut iter = iterable.keys_iter(read_opts).reverse().from(&7).to(&3);
  let vec: Vec<i32> = iter.collect();
  assert_eq!(vec, vec![6, 4]);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants