From ca0d760cf1724449f933ef6efe738d189542dee2 Mon Sep 17 00:00:00 2001 From: efyang Date: Sun, 22 Oct 2017 20:58:06 -0500 Subject: [PATCH] Iterate over both buffered and unbuffered database entries --- Cargo.toml | 1 + src/lib.rs | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e055c85..f2eb569 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ parking_lot = "0.4" regex = "0.2" rlp = { path = "../rlp" } rocksdb = { git = "https://github.com/paritytech/rust-rocksdb" } +interleaved-ordered = "0.1.0" [dev-dependencies] tempdir = "0.3" diff --git a/src/lib.rs b/src/lib.rs index d08c8ec..69b8164 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ extern crate elastic_array; extern crate parking_lot; extern crate regex; extern crate rocksdb; +extern crate interleaved_ordered; extern crate ethcore_bigint as bigint; extern crate kvdb; @@ -36,6 +37,7 @@ use rocksdb::{ DB, Writable, WriteBatch, WriteOptions, IteratorMode, DBIterator, Options, DBCompactionStyle, BlockBasedOptions, Direction, Cache, Column, ReadOptions }; +use interleaved_ordered::{interleave_ordered, InterleaveOrdered}; use elastic_array::ElasticArray32; use rlp::{UntrustedRlp, RlpType, Compressible}; @@ -197,14 +199,14 @@ impl Default for DatabaseConfig { // inner DB (to prevent closing via restoration) may be re-evaluated in the future. // pub struct DatabaseIterator<'a> { - iter: DBIterator, + iter: InterleaveOrdered<::std::vec::IntoIter<(Box<[u8]>, Box<[u8]>)>, DBIterator>, _marker: PhantomData<&'a Database>, } impl<'a> Iterator for DatabaseIterator<'a> { type Item = (Box<[u8]>, Box<[u8]>); - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { self.iter.next() } } @@ -510,9 +512,17 @@ impl Database { /// Get database iterator for flushed data. pub fn iter(&self, col: Option) -> Option { - //TODO: iterate over overlay match *self.db.read() { Some(DBAndColumns { ref db, ref cfs }) => { + let overlay = &self.overlay.read()[Self::to_overlay_column(col)]; + let overlay_data = overlay.iter() + .filter_map(|(k, v)| match v { + &KeyState::Insert(ref value) | + &KeyState::InsertCompressed(ref value) => + Some((k.clone().into_vec().into_boxed_slice(), value.clone().into_vec().into_boxed_slice())), + &KeyState::Delete => None, + }).collect::>(); + let iter = col.map_or_else( || db.iterator_opt(IteratorMode::Start, &self.read_opts), |c| db.iterator_cf_opt(cfs[c as usize], IteratorMode::Start, &self.read_opts) @@ -520,7 +530,7 @@ impl Database { ); Some(DatabaseIterator { - iter: iter, + iter: interleave_ordered(overlay_data, iter), _marker: PhantomData, }) }, @@ -536,7 +546,7 @@ impl Database { .expect("iterator params are valid; qed")); Some(DatabaseIterator { - iter: iter, + iter: interleave_ordered(Vec::new(), iter), _marker: PhantomData, }) },