Serialize blocktree writes by locking the database (#4008)

Move several private methods to free functions
This commit is contained in:
Mark E. Sinclair
2019-04-26 10:52:10 -05:00
committed by GitHub
parent eebdfe8d73
commit 8b1724bb70
2 changed files with 839 additions and 737 deletions

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,6 @@ use std::borrow::Borrow;
use std::collections::HashMap; use std::collections::HashMap;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use std::sync::Arc;
pub mod columns { pub mod columns {
#[derive(Debug)] #[derive(Debug)]
@ -133,7 +132,7 @@ where
B: Backend, B: Backend,
C: Column<B>, C: Column<B>,
{ {
pub db: Arc<Database<B>>, backend: PhantomData<B>,
column: PhantomData<C>, column: PhantomData<C>,
} }
@ -171,7 +170,7 @@ where
.get_cf(self.cf_handle::<C>(), C::key(key).borrow()) .get_cf(self.cf_handle::<C>(), C::key(key).borrow())
} }
pub fn put_bytes<C>(&self, key: C::Index, data: &[u8]) -> Result<()> pub fn put_bytes<C>(&mut self, key: C::Index, data: &[u8]) -> Result<()>
where where
C: Column<B>, C: Column<B>,
{ {
@ -179,7 +178,7 @@ where
.put_cf(self.cf_handle::<C>(), C::key(key).borrow(), data) .put_cf(self.cf_handle::<C>(), C::key(key).borrow(), data)
} }
pub fn delete<C>(&self, key: C::Index) -> Result<()> pub fn delete<C>(&mut self, key: C::Index) -> Result<()>
where where
C: Column<B>, C: Column<B>,
{ {
@ -203,7 +202,7 @@ where
} }
} }
pub fn put<C>(&self, key: C::Index, value: &C::Type) -> Result<()> pub fn put<C>(&mut self, key: C::Index, value: &C::Type) -> Result<()>
where where
C: TypedColumn<B>, C: TypedColumn<B>,
{ {
@ -241,7 +240,7 @@ where
Ok(iter) Ok(iter)
} }
pub fn batch(&self) -> Result<WriteBatch<B>> { pub fn batch(&mut self) -> Result<WriteBatch<B>> {
let db_write_batch = self.backend.batch()?; let db_write_batch = self.backend.batch()?;
let map = self let map = self
.backend .backend
@ -257,7 +256,7 @@ where
}) })
} }
pub fn write(&self, batch: WriteBatch<B>) -> Result<()> { pub fn write(&mut self, batch: WriteBatch<B>) -> Result<()> {
self.backend.write(batch.write_batch) self.backend.write(batch.write_batch)
} }
@ -268,6 +267,16 @@ where
{ {
self.backend.cf_handle(C::NAME).clone() self.backend.cf_handle(C::NAME).clone()
} }
pub fn column<C>(&self) -> LedgerColumn<B, C>
where
C: Column<B>,
{
LedgerColumn {
backend: PhantomData,
column: PhantomData,
}
}
} }
impl<B, C> Cursor<B, C> impl<B, C> Cursor<B, C>
@ -324,43 +333,24 @@ where
B: Backend, B: Backend,
C: Column<B>, C: Column<B>,
{ {
pub fn new(db: &Arc<Database<B>>) -> Self { pub fn get_bytes(&self, db: &Database<B>, key: C::Index) -> Result<Option<Vec<u8>>> {
LedgerColumn { db.backend.get_cf(self.handle(db), C::key(key).borrow())
db: Arc::clone(db),
column: PhantomData,
}
} }
pub fn put_bytes(&self, key: C::Index, value: &[u8]) -> Result<()> { pub fn cursor(&self, db: &Database<B>) -> Result<Cursor<B, C>> {
self.db db.cursor()
.backend
.put_cf(self.handle(), C::key(key).borrow(), value)
} }
pub fn get_bytes(&self, key: C::Index) -> Result<Option<Vec<u8>>> { pub fn iter(&self, db: &Database<B>) -> Result<impl Iterator<Item = (C::Index, Vec<u8>)>> {
self.db.backend.get_cf(self.handle(), C::key(key).borrow()) db.iter::<C>()
} }
pub fn delete(&self, key: C::Index) -> Result<()> { pub fn handle(&self, db: &Database<B>) -> B::ColumnFamily {
self.db db.cf_handle::<C>()
.backend
.delete_cf(self.handle(), C::key(key).borrow())
} }
pub fn cursor(&self) -> Result<Cursor<B, C>> { pub fn is_empty(&self, db: &Database<B>) -> Result<bool> {
self.db.cursor() let mut cursor = self.cursor(db)?;
}
pub fn iter(&self) -> Result<impl Iterator<Item = (C::Index, Vec<u8>)>> {
self.db.iter::<C>()
}
pub fn handle(&self) -> B::ColumnFamily {
self.db.cf_handle::<C>()
}
pub fn is_empty(&self) -> Result<bool> {
let mut cursor = self.cursor()?;
cursor.seek_to_first(); cursor.seek_to_first();
Ok(!cursor.valid()) Ok(!cursor.valid())
} }
@ -369,14 +359,35 @@ where
impl<B, C> LedgerColumn<B, C> impl<B, C> LedgerColumn<B, C>
where where
B: Backend, B: Backend,
C: TypedColumn<B>, C: Column<B>,
{ {
pub fn put(&self, key: C::Index, value: &C::Type) -> Result<()> { pub fn put_bytes(&self, db: &mut Database<B>, key: C::Index, value: &[u8]) -> Result<()> {
self.db.put::<C>(key, value) db.backend
.put_cf(self.handle(db), C::key(key).borrow(), value)
} }
pub fn get(&self, key: C::Index) -> Result<Option<C::Type>> { pub fn delete(&self, db: &mut Database<B>, key: C::Index) -> Result<()> {
self.db.get::<C>(key) db.backend.delete_cf(self.handle(db), C::key(key).borrow())
}
}
impl<B, C> LedgerColumn<B, C>
where
B: Backend,
C: TypedColumn<B>,
{
pub fn get(&self, db: &Database<B>, key: C::Index) -> Result<Option<C::Type>> {
db.get::<C>(key)
}
}
impl<B, C> LedgerColumn<B, C>
where
B: Backend,
C: TypedColumn<B>,
{
pub fn put(&self, db: &mut Database<B>, key: C::Index, value: &C::Type) -> Result<()> {
db.put::<C>(key, value)
} }
} }