Exercise: Iterate over database contents
In this last part we'll create an Iterator for looping over everything stored in our database.
Preparation
The iterator functionality is exposed by the sys crate as follows:
leveldb_create_iterator: Creates an opaqueleveldb_iterator_thandleleveldb_iter_seek_to_first: Starts the iteration by seeking to the first itemleveldb_iter_next: Advances iteration by one elementleveldb_iter_value: Reads the value at the current iterator positionleveldb_iter_valid: Indicates whether the iterator is currently valid
An iterator is position invalid before seeking to the first item and after it has advanced beyond the last one. Reading its value returns non-owned data.
Your tasks
✅ Implement an iterator handle. It should fully encapsulate any unsafe code.
✅ Implement an Iterator type that holds the necessary state and makes use of the handle.
✅ Implement pub fn iter(&self) -> Iterator for your Database struct.
✅ Implement std::iter::Iterator for your Iterator type. Its items should be of type Box<[u8]>.
✅ Write a test case to verify that your iterator returns all items lexicographically sorted by key. Also test with an empty database.
✅ Make the Iterator type reference the Database that created it. What has changed and what are the benefits?
✅ Bonus task: what could be used instead of the Database reference that achieves the same goal but consumes no memory?