Mercurial > lbo > hg > leveldb-rs
changeset 188:ba0516209e6c
table_reader: Remove lifetime param from TableIterator.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 23 Aug 2017 19:59:04 +0200 |
parents | 82c2b63653c5 |
children | b731f7b7c1f3 |
files | src/table_reader.rs |
diffstat | 1 files changed, 20 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/table_reader.rs Wed Aug 23 19:46:55 2017 +0200 +++ b/src/table_reader.rs Wed Aug 23 19:59:04 2017 +0200 @@ -84,8 +84,10 @@ /// Creates a new table reader operating on unformatted keys (i.e., UserKey). fn new_raw(opt: Options, file: Arc<Box<RandomAccess>>, size: usize) -> Result<Table> { let footer = try!(read_footer(file.as_ref().as_ref(), size)); - let indexblock = try!(TableBlock::read_block(opt.clone(), file.as_ref().as_ref(), &footer.index)); - let metaindexblock = try!(TableBlock::read_block(opt.clone(), file.as_ref().as_ref(), &footer.meta_index)); + let indexblock = + try!(TableBlock::read_block(opt.clone(), file.as_ref().as_ref(), &footer.index)); + let metaindexblock = + try!(TableBlock::read_block(opt.clone(), file.as_ref().as_ref(), &footer.meta_index)); if !indexblock.verify() || !metaindexblock.verify() { return Err(Status::new(StatusCode::InvalidData, @@ -151,7 +153,8 @@ } // Two times as_ref(): First time to get a ref from Arc<>, then one from Box<>. - let b = try!(TableBlock::read_block(self.opt.clone(), self.file.as_ref().as_ref(), location)); + let b = + try!(TableBlock::read_block(self.opt.clone(), self.file.as_ref().as_ref(), location)); if !b.verify() { return Err(Status::new(StatusCode::InvalidData, "Data block failed verification")); @@ -179,14 +182,13 @@ } /// Iterators read from the file; thus only one iterator can be borrowed (mutably) per scope - pub fn iter<'a>(&'a self) -> TableIterator<'a> { + pub fn iter(&self) -> TableIterator { let iter = TableIterator { current_block: self.indexblock.iter(), init: false, current_block_off: 0, index_block: self.indexblock.iter(), - opt: self.opt.clone(), - table: self, + table: self.clone(), }; iter } @@ -242,9 +244,14 @@ /// This iterator is a "TwoLevelIterator"; it uses an index block in order to get an offset hint /// into the data blocks. -pub struct TableIterator<'a> { - table: &'a Table, - opt: Options, +pub struct TableIterator { + // A TableIterator is independent of its table (on the syntax level -- it doesn't know its + // Table's lifetime). This is mainly required by the dynamic iterators used everywhere, where a + // lifetime makes things like returning an iterator from a function neigh-impossible. + // + // Instead, reference-counted pointers and locks inside the Table ensure that all + // TableIterators still share a table. + table: Table, // We're not using Option<BlockIter>, but instead a separate `init` field. That makes it easier // working with the current block in the iterator methods (no borrowing annoyance as with // Option<>) @@ -254,7 +261,7 @@ index_block: BlockIter, } -impl<'a> TableIterator<'a> { +impl TableIterator { // Skips to the entry referenced by the next entry in the index block. // This is called once a block has run out of entries. // Err means corruption or I/O error; Ok(true) means a new block was loaded; Ok(false) means @@ -280,7 +287,7 @@ } } -impl<'a> Iterator for TableIterator<'a> { +impl Iterator for TableIterator { type Item = (Vec<u8>, Vec<u8>); fn next(&mut self) -> Option<Self::Item> { @@ -312,7 +319,7 @@ } } -impl<'a> LdbIterator for TableIterator<'a> { +impl LdbIterator for TableIterator { // A call to valid() after seeking is necessary to ensure that the seek worked (e.g., no error // while reading from disk) fn seek(&mut self, to: &[u8]) { @@ -322,7 +329,7 @@ self.index_block.seek(to); if let Some((past_block, handle)) = self.index_block.current() { - if self.opt.cmp.cmp(to, &past_block) <= Ordering::Equal { + if self.table.opt.cmp.cmp(to, &past_block) <= Ordering::Equal { // ok, found right block: continue if let Ok(()) = self.load_block(&handle) { self.current_block.seek(to);