,
/// Database path
path: PathBuf,
}
@@ -60,61 +116,71 @@ pub struct Database {
impl Database {
/// Opens blooms database.
pub fn open(path: P) -> io::Result where P: AsRef {
- let path = path.as_ref();
+ let path: PathBuf = path.as_ref().to_path_buf();
let database = Database {
- top: File::open(path.join("top.bdb"))?,
- mid: File::open(path.join("mid.bdb"))?,
- bot: File::open(path.join("bot.bdb"))?,
- path: path.to_owned(),
+ db_files: Some(DatabaseFiles::open(&path)?),
+ path: path,
};
Ok(database)
}
- /// Reopens the database at the same location.
- pub fn reopen(&mut self) -> io::Result<()> {
- self.top = File::open(self.path.join("top.bdb"))?;
- self.mid = File::open(self.path.join("mid.bdb"))?;
- self.bot = File::open(self.path.join("bot.bdb"))?;
+ /// Close the inner-files
+ pub fn close(&mut self) -> io::Result<()> {
+ self.db_files = None;
Ok(())
}
- /// Insert consecutive blooms into database starting with positon from.
+ /// Reopens the database at the same location.
+ pub fn reopen(&mut self) -> io::Result<()> {
+ self.db_files = Some(DatabaseFiles::open(&self.path)?);
+ Ok(())
+ }
+
+ /// Insert consecutive blooms into database starting at the given positon.
pub fn insert_blooms<'a, I, B>(&mut self, from: u64, blooms: I) -> io::Result<()>
where ethbloom::BloomRef<'a>: From, I: Iterator- {
- for (index, bloom) in (from..).into_iter().zip(blooms.map(Into::into)) {
- let pos = Positions::from_index(index);
+ match self.db_files {
+ Some(ref mut db_files) => {
+ for (index, bloom) in (from..).into_iter().zip(blooms.map(Into::into)) {
+ let pos = Positions::from_index(index);
- // constant forks make lead to increased ration of false positives in bloom filters
- // since we do not rebuild top or mid level, but we should not be worried about that
- // most of the time events at block n(a) occur also on block n(b) or n+1(b)
- self.top.accrue_bloom::(pos.top, bloom)?;
- self.mid.accrue_bloom::(pos.mid, bloom)?;
- self.bot.replace_bloom::(pos.bot, bloom)?;
+ // Constant forks may lead to increased ratio of false positives in bloom filters
+ // since we do not rebuild top or mid level, but we should not be worried about that
+ // because most of the time events at block n(a) occur also on block n(b) or n+1(b)
+ db_files.accrue_bloom(pos, bloom)?;
+ }
+ db_files.flush()?;
+ Ok(())
+ },
+ None => Err(other_io_err("Database is closed")),
}
- self.top.flush()?;
- self.mid.flush()?;
- self.bot.flush()
}
/// Returns an iterator yielding all indexes containing given bloom.
pub fn iterate_matching<'a, 'b, B, I, II>(&'a mut self, from: u64, to: u64, blooms: II) -> io::Result>
where ethbloom::BloomRef<'b>: From, 'b: 'a, II: IntoIterator
- + Copy, I: Iterator
- {
- let index = from / 256 * 256;
- let pos = Positions::from_index(index);
+ match self.db_files {
+ Some(ref mut db_files) => {
+ let index = from / 256 * 256;
+ let pos = Positions::from_index(index);
+ let files_iter = db_files.iterator_from(pos)?;
- let iter = DatabaseIterator {
- top: self.top.iterator_from(pos.top)?,
- mid: self.mid.iterator_from(pos.mid)?,
- bot: self.bot.iterator_from(pos.bot)?,
- state: IteratorState::Top,
- from,
- to,
- index,
- blooms,
- };
+ let iter = DatabaseIterator {
+ top: files_iter.top,
+ mid: files_iter.mid,
+ bot: files_iter.bot,
+ state: IteratorState::Top,
+ from,
+ to,
+ index,
+ blooms,
+ };
- Ok(iter)
+ Ok(iter)
+ },
+ None => Err(other_io_err("Database is closed")),
+ }
}
}
@@ -285,4 +351,19 @@ mod tests {
let matches = database.iterate_matching(256, 257, Some(&Bloom::from(0x10))).unwrap().collect::, _>>().unwrap();
assert_eq!(matches, vec![256, 257]);
}
+
+ #[test]
+ fn test_db_close() {
+ let tempdir = TempDir::new("").unwrap();
+ let blooms = vec![Bloom::from(0x100), Bloom::from(0x01), Bloom::from(0x10), Bloom::from(0x11)];
+ let mut database = Database::open(tempdir.path()).unwrap();
+
+ // Close the DB and ensure inserting blooms errors
+ database.close().unwrap();
+ assert!(database.insert_blooms(254, blooms.iter()).is_err());
+
+ // Reopen it and ensure inserting blooms is OK
+ database.reopen().unwrap();
+ assert!(database.insert_blooms(254, blooms.iter()).is_ok());
+ }
}
diff --git a/util/blooms-db/src/lib.rs b/util/blooms-db/src/lib.rs
index c63815422..a810b9732 100644
--- a/util/blooms-db/src/lib.rs
+++ b/util/blooms-db/src/lib.rs
@@ -54,6 +54,11 @@ impl Database {
Ok(result)
}
+ /// Closes the inner database
+ pub fn close(&self) -> io::Result<()> {
+ self.database.lock().close()
+ }
+
/// Reopens database at the same location.
pub fn reopen(&self) -> io::Result<()> {
self.database.lock().reopen()