Serialize blocktree writes by locking the database (#4008)
Move several private methods to free functions
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -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)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user