remove internal locking from DBTransaction (#2003)
This commit is contained in:
parent
b18407b9e3
commit
2aef81cf90
@ -380,7 +380,7 @@ impl BlockChain {
|
|||||||
children: vec![]
|
children: vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
let batch = DBTransaction::new(&db);
|
let mut batch = DBTransaction::new(&db);
|
||||||
batch.put(db::COL_HEADERS, &hash, block.header_rlp().as_raw());
|
batch.put(db::COL_HEADERS, &hash, block.header_rlp().as_raw());
|
||||||
batch.put(db::COL_BODIES, &hash, &Self::block_to_body(genesis));
|
batch.put(db::COL_BODIES, &hash, &Self::block_to_body(genesis));
|
||||||
|
|
||||||
@ -419,7 +419,7 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
batch.put(db::COL_EXTRA, b"first", &hash);
|
batch.put(db::COL_EXTRA, b"first", &hash);
|
||||||
db.write(batch).expect("Low level database error.");
|
db.write(batch).expect("Low level database error.");
|
||||||
|
|
||||||
@ -451,7 +451,7 @@ impl BlockChain {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn rewind(&self) -> Option<H256> {
|
fn rewind(&self) -> Option<H256> {
|
||||||
use db::Key;
|
use db::Key;
|
||||||
let batch = self.db.transaction();
|
let mut batch =self.db.transaction();
|
||||||
// track back to the best block we have in the blocks database
|
// track back to the best block we have in the blocks database
|
||||||
if let Some(best_block_hash) = self.db.get(db::COL_EXTRA, b"best").unwrap() {
|
if let Some(best_block_hash) = self.db.get(db::COL_EXTRA, b"best").unwrap() {
|
||||||
let best_block_hash = H256::from_slice(&best_block_hash);
|
let best_block_hash = H256::from_slice(&best_block_hash);
|
||||||
@ -604,7 +604,7 @@ impl BlockChain {
|
|||||||
|
|
||||||
assert!(self.pending_best_block.read().is_none());
|
assert!(self.pending_best_block.read().is_none());
|
||||||
|
|
||||||
let batch = self.db.transaction();
|
let mut batch = self.db.transaction();
|
||||||
|
|
||||||
let block_rlp = UntrustedRlp::new(bytes);
|
let block_rlp = UntrustedRlp::new(bytes);
|
||||||
let compressed_header = block_rlp.at(0).unwrap().compress(RlpType::Blocks);
|
let compressed_header = block_rlp.at(0).unwrap().compress(RlpType::Blocks);
|
||||||
@ -625,7 +625,7 @@ impl BlockChain {
|
|||||||
location: BlockLocation::CanonChain,
|
location: BlockLocation::CanonChain,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.prepare_update(&batch, ExtrasUpdate {
|
self.prepare_update(&mut batch, ExtrasUpdate {
|
||||||
block_hashes: self.prepare_block_hashes_update(bytes, &info),
|
block_hashes: self.prepare_block_hashes_update(bytes, &info),
|
||||||
block_details: self.prepare_block_details_update(bytes, &info),
|
block_details: self.prepare_block_details_update(bytes, &info),
|
||||||
block_receipts: self.prepare_block_receipts_update(receipts, &info),
|
block_receipts: self.prepare_block_receipts_update(receipts, &info),
|
||||||
@ -659,7 +659,7 @@ impl BlockChain {
|
|||||||
let mut update = HashMap::new();
|
let mut update = HashMap::new();
|
||||||
update.insert(hash, block_details);
|
update.insert(hash, block_details);
|
||||||
|
|
||||||
self.prepare_update(&batch, ExtrasUpdate {
|
self.prepare_update(&mut batch, ExtrasUpdate {
|
||||||
block_hashes: self.prepare_block_hashes_update(bytes, &info),
|
block_hashes: self.prepare_block_hashes_update(bytes, &info),
|
||||||
block_details: update,
|
block_details: update,
|
||||||
block_receipts: self.prepare_block_receipts_update(receipts, &info),
|
block_receipts: self.prepare_block_receipts_update(receipts, &info),
|
||||||
@ -682,7 +682,7 @@ impl BlockChain {
|
|||||||
let mut parent_details = self.block_details(&block_hash)
|
let mut parent_details = self.block_details(&block_hash)
|
||||||
.unwrap_or_else(|| panic!("Invalid block hash: {:?}", block_hash));
|
.unwrap_or_else(|| panic!("Invalid block hash: {:?}", block_hash));
|
||||||
|
|
||||||
let batch = self.db.transaction();
|
let mut batch = self.db.transaction();
|
||||||
parent_details.children.push(child_hash);
|
parent_details.children.push(child_hash);
|
||||||
|
|
||||||
let mut update = HashMap::new();
|
let mut update = HashMap::new();
|
||||||
@ -701,7 +701,7 @@ impl BlockChain {
|
|||||||
/// Inserts the block into backing cache database.
|
/// Inserts the block into backing cache database.
|
||||||
/// Expects the block to be valid and already verified.
|
/// Expects the block to be valid and already verified.
|
||||||
/// If the block is already known, does nothing.
|
/// If the block is already known, does nothing.
|
||||||
pub fn insert_block(&self, batch: &DBTransaction, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
|
pub fn insert_block(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
|
||||||
// create views onto rlp
|
// create views onto rlp
|
||||||
let block = BlockView::new(bytes);
|
let block = BlockView::new(bytes);
|
||||||
let header = block.header_view();
|
let header = block.header_view();
|
||||||
@ -782,7 +782,7 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prepares extras update.
|
/// Prepares extras update.
|
||||||
fn prepare_update(&self, batch: &DBTransaction, update: ExtrasUpdate, is_best: bool) {
|
fn prepare_update(&self, batch: &mut DBTransaction, update: ExtrasUpdate, is_best: bool) {
|
||||||
{
|
{
|
||||||
let block_hashes: Vec<_> = update.block_details.keys().cloned().collect();
|
let block_hashes: Vec<_> = update.block_details.keys().cloned().collect();
|
||||||
|
|
||||||
@ -1147,8 +1147,8 @@ mod tests {
|
|||||||
assert_eq!(bc.best_block_number(), 0);
|
assert_eq!(bc.best_block_number(), 0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
bc.insert_block(&batch, &first, vec![]);
|
bc.insert_block(&mut batch, &first, vec![]);
|
||||||
assert_eq!(bc.best_block_number(), 0);
|
assert_eq!(bc.best_block_number(), 0);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
// NOTE no db.write here (we want to check if best block is cached)
|
// NOTE no db.write here (we want to check if best block is cached)
|
||||||
@ -1177,8 +1177,8 @@ mod tests {
|
|||||||
assert_eq!(bc.block_hash(1), None);
|
assert_eq!(bc.block_hash(1), None);
|
||||||
assert_eq!(bc.block_details(&genesis_hash).unwrap().children, vec![]);
|
assert_eq!(bc.block_details(&genesis_hash).unwrap().children, vec![]);
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
bc.insert_block(&batch, &first, vec![]);
|
bc.insert_block(&mut batch, &first, vec![]);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
bc.commit();
|
bc.commit();
|
||||||
|
|
||||||
@ -1203,11 +1203,11 @@ mod tests {
|
|||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
||||||
|
|
||||||
let mut block_hashes = vec![genesis_hash.clone()];
|
let mut block_hashes = vec![genesis_hash.clone()];
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let block = canon_chain.generate(&mut finalizer).unwrap();
|
let block = canon_chain.generate(&mut finalizer).unwrap();
|
||||||
block_hashes.push(BlockView::new(&block).header_view().sha3());
|
block_hashes.push(BlockView::new(&block).header_view().sha3());
|
||||||
bc.insert_block(&batch, &block, vec![]);
|
bc.insert_block(&mut batch, &block, vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
}
|
}
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
@ -1238,20 +1238,20 @@ mod tests {
|
|||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
for b in &[&b1a, &b1b, &b2a, &b2b, &b3a, &b3b, &b4a, &b4b, &b5a, &b5b] {
|
for b in &[&b1a, &b1b, &b2a, &b2b, &b3a, &b3b, &b4a, &b4b, &b5a, &b5b] {
|
||||||
bc.insert_block(&batch, b, vec![]);
|
bc.insert_block(&mut batch, b, vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
}
|
}
|
||||||
bc.insert_block(&batch, &b1b, vec![]);
|
bc.insert_block(&mut batch, &b1b, vec![]);
|
||||||
bc.insert_block(&batch, &b2a, vec![]);
|
bc.insert_block(&mut batch, &b2a, vec![]);
|
||||||
bc.insert_block(&batch, &b2b, vec![]);
|
bc.insert_block(&mut batch, &b2b, vec![]);
|
||||||
bc.insert_block(&batch, &b3a, vec![]);
|
bc.insert_block(&mut batch, &b3a, vec![]);
|
||||||
bc.insert_block(&batch, &b3b, vec![]);
|
bc.insert_block(&mut batch, &b3b, vec![]);
|
||||||
bc.insert_block(&batch, &b4a, vec![]);
|
bc.insert_block(&mut batch, &b4a, vec![]);
|
||||||
bc.insert_block(&batch, &b4b, vec![]);
|
bc.insert_block(&mut batch, &b4b, vec![]);
|
||||||
bc.insert_block(&batch, &b5a, vec![]);
|
bc.insert_block(&mut batch, &b5a, vec![]);
|
||||||
bc.insert_block(&batch, &b5b, vec![]);
|
bc.insert_block(&mut batch, &b5b, vec![]);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -1286,17 +1286,17 @@ mod tests {
|
|||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
let ir1 = bc.insert_block(&batch, &b1, vec![]);
|
let ir1 = bc.insert_block(&mut batch, &b1, vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
let ir2 = bc.insert_block(&batch, &b2, vec![]);
|
let ir2 = bc.insert_block(&mut batch, &b2, vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
let ir3b = bc.insert_block(&batch, &b3b, vec![]);
|
let ir3b = bc.insert_block(&mut batch, &b3b, vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
assert_eq!(bc.block_hash(3).unwrap(), b3b_hash);
|
assert_eq!(bc.block_hash(3).unwrap(), b3b_hash);
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
let ir3a = bc.insert_block(&batch, &b3a, vec![]);
|
let ir3a = bc.insert_block(&mut batch, &b3a, vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
|
|
||||||
@ -1402,8 +1402,8 @@ mod tests {
|
|||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
||||||
assert_eq!(bc.best_block_hash(), genesis_hash);
|
assert_eq!(bc.best_block_hash(), genesis_hash);
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
bc.insert_block(&batch, &first, vec![]);
|
bc.insert_block(&mut batch, &first, vec![]);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
bc.commit();
|
bc.commit();
|
||||||
assert_eq!(bc.best_block_hash(), first_hash);
|
assert_eq!(bc.best_block_hash(), first_hash);
|
||||||
@ -1467,8 +1467,8 @@ mod tests {
|
|||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
bc.insert_block(&batch, &b1, vec![]);
|
bc.insert_block(&mut batch, &b1, vec![]);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
bc.commit();
|
bc.commit();
|
||||||
|
|
||||||
@ -1480,8 +1480,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn insert_block(db: &Arc<Database>, bc: &BlockChain, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
|
fn insert_block(db: &Arc<Database>, bc: &BlockChain, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
let res = bc.insert_block(&batch, bytes, receipts);
|
let res = bc.insert_block(&mut batch, bytes, receipts);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
bc.commit();
|
bc.commit();
|
||||||
res
|
res
|
||||||
@ -1569,16 +1569,16 @@ mod tests {
|
|||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
||||||
let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap();
|
let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap();
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
// create a longer fork
|
// create a longer fork
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
let canon_block = canon_chain.generate(&mut finalizer).unwrap();
|
let canon_block = canon_chain.generate(&mut finalizer).unwrap();
|
||||||
bc.insert_block(&batch, &canon_block, vec![]);
|
bc.insert_block(&mut batch, &canon_block, vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(bc.best_block_number(), 5);
|
assert_eq!(bc.best_block_number(), 5);
|
||||||
bc.insert_block(&batch, &uncle, vec![]);
|
bc.insert_block(&mut batch, &uncle, vec![]);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
bc.commit();
|
bc.commit();
|
||||||
}
|
}
|
||||||
@ -1604,10 +1604,10 @@ mod tests {
|
|||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch =db.transaction();
|
||||||
bc.insert_block(&batch, &first, vec![]);
|
bc.insert_block(&mut batch, &first, vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
bc.insert_block(&batch, &second, vec![]);
|
bc.insert_block(&mut batch, &second, vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
|
|
||||||
|
@ -172,8 +172,8 @@ impl Client {
|
|||||||
|
|
||||||
let mut state_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
|
let mut state_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
|
||||||
if state_db.is_empty() && try!(spec.ensure_db_good(state_db.as_hashdb_mut())) {
|
if state_db.is_empty() && try!(spec.ensure_db_good(state_db.as_hashdb_mut())) {
|
||||||
let batch = DBTransaction::new(&db);
|
let mut batch = DBTransaction::new(&db);
|
||||||
try!(state_db.commit(&batch, 0, &spec.genesis_header().hash(), None));
|
try!(state_db.commit(&mut batch, 0, &spec.genesis_header().hash(), None));
|
||||||
try!(db.write(batch).map_err(ClientError::Database));
|
try!(db.write(batch).map_err(ClientError::Database));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,14 +431,14 @@ impl Client {
|
|||||||
|
|
||||||
//let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));
|
//let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));
|
||||||
|
|
||||||
let batch = DBTransaction::new(&self.db);
|
let mut batch = DBTransaction::new(&self.db);
|
||||||
// CHECK! I *think* this is fine, even if the state_root is equal to another
|
// CHECK! I *think* this is fine, even if the state_root is equal to another
|
||||||
// already-imported block of the same number.
|
// already-imported block of the same number.
|
||||||
// TODO: Prove it with a test.
|
// TODO: Prove it with a test.
|
||||||
block.drain().commit(&batch, number, hash, ancient).expect("DB commit failed.");
|
block.drain().commit(&mut batch, number, hash, ancient).expect("DB commit failed.");
|
||||||
|
|
||||||
let route = self.chain.insert_block(&batch, block_data, receipts);
|
let route = self.chain.insert_block(&mut batch, block_data, receipts);
|
||||||
self.tracedb.import(&batch, TraceImportRequest {
|
self.tracedb.import(&mut batch, TraceImportRequest {
|
||||||
traces: traces.into(),
|
traces: traces.into(),
|
||||||
block_hash: hash.clone(),
|
block_hash: hash.clone(),
|
||||||
block_number: number,
|
block_number: number,
|
||||||
|
@ -83,10 +83,10 @@ pub trait Key<T> {
|
|||||||
/// Should be used to write value into database.
|
/// Should be used to write value into database.
|
||||||
pub trait Writable {
|
pub trait Writable {
|
||||||
/// Writes the value into the database.
|
/// Writes the value into the database.
|
||||||
fn write<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]>;
|
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]>;
|
||||||
|
|
||||||
/// Writes the value into the database and updates the cache.
|
/// Writes the value into the database and updates the cache.
|
||||||
fn write_with_cache<K, T, R>(&self, col: Option<u32>, cache: &mut Cache<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
|
fn write_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
|
||||||
K: Key<T, Target = R> + Hash + Eq,
|
K: Key<T, Target = R> + Hash + Eq,
|
||||||
T: Encodable,
|
T: Encodable,
|
||||||
R: Deref<Target = [u8]> {
|
R: Deref<Target = [u8]> {
|
||||||
@ -102,7 +102,7 @@ pub trait Writable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the values into the database and updates the cache.
|
/// Writes the values into the database and updates the cache.
|
||||||
fn extend_with_cache<K, T, R>(&self, col: Option<u32>, cache: &mut Cache<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where
|
fn extend_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where
|
||||||
K: Key<T, Target = R> + Hash + Eq,
|
K: Key<T, Target = R> + Hash + Eq,
|
||||||
T: Encodable,
|
T: Encodable,
|
||||||
R: Deref<Target = [u8]> {
|
R: Deref<Target = [u8]> {
|
||||||
@ -169,7 +169,7 @@ pub trait Readable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Writable for DBTransaction {
|
impl Writable for DBTransaction {
|
||||||
fn write<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]> {
|
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]> {
|
||||||
self.put(col, &key.key(), &encode(value));
|
self.put(col, &key.key(), &encode(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,8 +492,8 @@ impl StateRebuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let backing = self.db.backing().clone();
|
let backing = self.db.backing().clone();
|
||||||
let batch = backing.transaction();
|
let mut batch = backing.transaction();
|
||||||
try!(self.db.inject(&batch));
|
try!(self.db.inject(&mut batch));
|
||||||
try!(backing.write(batch).map_err(::util::UtilError::SimpleString));
|
try!(backing.write(batch).map_err(::util::UtilError::SimpleString));
|
||||||
trace!(target: "snapshot", "current state root: {:?}", self.state_root);
|
trace!(target: "snapshot", "current state root: {:?}", self.state_root);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -43,14 +43,16 @@ fn chunk_and_restore(amount: u64) {
|
|||||||
let bc = BlockChain::new(Default::default(), &genesis, old_db.clone());
|
let bc = BlockChain::new(Default::default(), &genesis, old_db.clone());
|
||||||
|
|
||||||
// build the blockchain.
|
// build the blockchain.
|
||||||
|
let mut batch = old_db.transaction();
|
||||||
for _ in 0..amount {
|
for _ in 0..amount {
|
||||||
let block = canon_chain.generate(&mut finalizer).unwrap();
|
let block = canon_chain.generate(&mut finalizer).unwrap();
|
||||||
let batch = old_db.transaction();
|
bc.insert_block(&mut batch, &block, vec![]);
|
||||||
bc.insert_block(&batch, &block, vec![]);
|
|
||||||
bc.commit();
|
bc.commit();
|
||||||
old_db.write(batch).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
old_db.write(batch).unwrap();
|
||||||
|
|
||||||
|
|
||||||
let best_hash = bc.best_block_hash();
|
let best_hash = bc.best_block_hash();
|
||||||
|
|
||||||
// snapshot it.
|
// snapshot it.
|
||||||
|
@ -259,9 +259,9 @@ pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult<BlockCh
|
|||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone());
|
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone());
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
for block_order in 1..block_number {
|
for block_order in 1..block_number {
|
||||||
bc.insert_block(&batch, &create_unverifiable_block(block_order, bc.best_block_hash()), vec![]);
|
bc.insert_block(&mut batch, &create_unverifiable_block(block_order, bc.best_block_hash()), vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
}
|
}
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
@ -278,9 +278,9 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempRes
|
|||||||
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone());
|
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone());
|
||||||
|
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
for block_order in 1..block_number {
|
for block_order in 1..block_number {
|
||||||
bc.insert_block(&batch, &create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None), vec![]);
|
bc.insert_block(&mut batch, &create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None), vec![]);
|
||||||
bc.commit();
|
bc.commit();
|
||||||
}
|
}
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
|
@ -142,7 +142,7 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
|
|||||||
false => [0x0]
|
false => [0x0]
|
||||||
};
|
};
|
||||||
|
|
||||||
let batch = DBTransaction::new(&tracesdb);
|
let mut batch = DBTransaction::new(&tracesdb);
|
||||||
batch.put(db::COL_TRACE, b"enabled", &encoded_tracing);
|
batch.put(db::COL_TRACE, b"enabled", &encoded_tracing);
|
||||||
batch.put(db::COL_TRACE, b"version", TRACE_DB_VER);
|
batch.put(db::COL_TRACE, b"version", TRACE_DB_VER);
|
||||||
tracesdb.write(batch).unwrap();
|
tracesdb.write(batch).unwrap();
|
||||||
@ -261,7 +261,7 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
|
|||||||
|
|
||||||
/// Traces of import request's enacted blocks are expected to be already in database
|
/// Traces of import request's enacted blocks are expected to be already in database
|
||||||
/// or to be the currently inserted trace.
|
/// or to be the currently inserted trace.
|
||||||
fn import(&self, batch: &DBTransaction, request: ImportRequest) {
|
fn import(&self, batch: &mut DBTransaction, request: ImportRequest) {
|
||||||
// valid (canon): retracted 0, enacted 1 => false, true,
|
// valid (canon): retracted 0, enacted 1 => false, true,
|
||||||
// valid (branch): retracted 0, enacted 0 => false, false,
|
// valid (branch): retracted 0, enacted 0 => false, false,
|
||||||
// valid (bbcc): retracted 1, enacted 1 => true, true,
|
// valid (bbcc): retracted 1, enacted 1 => true, true,
|
||||||
@ -611,8 +611,8 @@ mod tests {
|
|||||||
|
|
||||||
// import block 0
|
// import block 0
|
||||||
let request = create_simple_import_request(0, block_0.clone());
|
let request = create_simple_import_request(0, block_0.clone());
|
||||||
let batch = DBTransaction::new(&db);
|
let mut batch = DBTransaction::new(&db);
|
||||||
tracedb.import(&batch, request);
|
tracedb.import(&mut batch, request);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
|
|
||||||
let filter = Filter {
|
let filter = Filter {
|
||||||
@ -627,8 +627,8 @@ mod tests {
|
|||||||
|
|
||||||
// import block 1
|
// import block 1
|
||||||
let request = create_simple_import_request(1, block_1.clone());
|
let request = create_simple_import_request(1, block_1.clone());
|
||||||
let batch = DBTransaction::new(&db);
|
let mut batch = DBTransaction::new(&db);
|
||||||
tracedb.import(&batch, request);
|
tracedb.import(&mut batch, request);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
|
|
||||||
let filter = Filter {
|
let filter = Filter {
|
||||||
@ -686,8 +686,8 @@ mod tests {
|
|||||||
|
|
||||||
// import block 0
|
// import block 0
|
||||||
let request = create_simple_import_request(0, block_0.clone());
|
let request = create_simple_import_request(0, block_0.clone());
|
||||||
let batch = DBTransaction::new(&db);
|
let mut batch = DBTransaction::new(&db);
|
||||||
tracedb.import(&batch, request);
|
tracedb.import(&mut batch, request);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ pub trait Database {
|
|||||||
fn tracing_enabled(&self) -> bool;
|
fn tracing_enabled(&self) -> bool;
|
||||||
|
|
||||||
/// Imports new block traces.
|
/// Imports new block traces.
|
||||||
fn import(&self, batch: &DBTransaction, request: ImportRequest);
|
fn import(&self, batch: &mut DBTransaction, request: ImportRequest);
|
||||||
|
|
||||||
/// Returns localized trace at given position.
|
/// Returns localized trace at given position.
|
||||||
fn trace(&self, block_number: BlockNumber, tx_position: usize, trace_position: Vec<usize>) -> Option<LocalizedTrace>;
|
fn trace(&self, block_number: BlockNumber, tx_position: usize, trace_position: Vec<usize>) -> Option<LocalizedTrace>;
|
||||||
|
@ -156,7 +156,7 @@ impl JournalDB for ArchiveDB {
|
|||||||
self.latest_era.is_none()
|
self.latest_era.is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commit(&mut self, batch: &DBTransaction, now: u64, _id: &H256, _end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
fn commit(&mut self, batch: &mut DBTransaction, now: u64, _id: &H256, _end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
||||||
let mut inserts = 0usize;
|
let mut inserts = 0usize;
|
||||||
let mut deletes = 0usize;
|
let mut deletes = 0usize;
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ impl JournalDB for ArchiveDB {
|
|||||||
Ok((inserts + deletes) as u32)
|
Ok((inserts + deletes) as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject(&mut self, batch: &DBTransaction) -> Result<u32, UtilError> {
|
fn inject(&mut self, batch: &mut DBTransaction) -> Result<u32, UtilError> {
|
||||||
let mut inserts = 0usize;
|
let mut inserts = 0usize;
|
||||||
let mut deletes = 0usize;
|
let mut deletes = 0usize;
|
||||||
|
|
||||||
|
@ -101,13 +101,13 @@ impl EarlyMergeDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The next three are valid only as long as there is an insert operation of `key` in the journal.
|
// The next three are valid only as long as there is an insert operation of `key` in the journal.
|
||||||
fn set_already_in(batch: &DBTransaction, col: Option<u32>, key: &H256) { batch.put(col, &Self::morph_key(key, 0), &[1u8]); }
|
fn set_already_in(batch: &mut DBTransaction, col: Option<u32>, key: &H256) { batch.put(col, &Self::morph_key(key, 0), &[1u8]); }
|
||||||
fn reset_already_in(batch: &DBTransaction, col: Option<u32>, key: &H256) { batch.delete(col, &Self::morph_key(key, 0)); }
|
fn reset_already_in(batch: &mut DBTransaction, col: Option<u32>, key: &H256) { batch.delete(col, &Self::morph_key(key, 0)); }
|
||||||
fn is_already_in(backing: &Database, col: Option<u32>, key: &H256) -> bool {
|
fn is_already_in(backing: &Database, col: Option<u32>, key: &H256) -> bool {
|
||||||
backing.get(col, &Self::morph_key(key, 0)).expect("Low-level database error. Some issue with your hard disk?").is_some()
|
backing.get(col, &Self::morph_key(key, 0)).expect("Low-level database error. Some issue with your hard disk?").is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_keys(inserts: &[(H256, Bytes)], backing: &Database, col: Option<u32>, refs: &mut HashMap<H256, RefInfo>, batch: &DBTransaction, trace: bool) {
|
fn insert_keys(inserts: &[(H256, Bytes)], backing: &Database, col: Option<u32>, refs: &mut HashMap<H256, RefInfo>, batch: &mut DBTransaction, trace: bool) {
|
||||||
for &(ref h, ref d) in inserts {
|
for &(ref h, ref d) in inserts {
|
||||||
if let Some(c) = refs.get_mut(h) {
|
if let Some(c) = refs.get_mut(h) {
|
||||||
// already counting. increment.
|
// already counting. increment.
|
||||||
@ -156,7 +156,7 @@ impl EarlyMergeDB {
|
|||||||
trace!(target: "jdb.fine", "replay_keys: (end) refs={:?}", refs);
|
trace!(target: "jdb.fine", "replay_keys: (end) refs={:?}", refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_keys(deletes: &[H256], refs: &mut HashMap<H256, RefInfo>, batch: &DBTransaction, col: Option<u32>, from: RemoveFrom, trace: bool) {
|
fn remove_keys(deletes: &[H256], refs: &mut HashMap<H256, RefInfo>, batch: &mut DBTransaction, col: Option<u32>, from: RemoveFrom, trace: bool) {
|
||||||
// with a remove on {queue_refs: 1, in_archive: true}, we have two options:
|
// with a remove on {queue_refs: 1, in_archive: true}, we have two options:
|
||||||
// - convert to {queue_refs: 1, in_archive: false} (i.e. remove it from the conceptual archive)
|
// - convert to {queue_refs: 1, in_archive: false} (i.e. remove it from the conceptual archive)
|
||||||
// - convert to {queue_refs: 0, in_archive: true} (i.e. remove it from the conceptual queue)
|
// - convert to {queue_refs: 0, in_archive: true} (i.e. remove it from the conceptual queue)
|
||||||
@ -337,7 +337,7 @@ impl JournalDB for EarlyMergeDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
||||||
fn commit(&mut self, batch: &DBTransaction, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
fn commit(&mut self, batch: &mut DBTransaction, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
||||||
// journal format:
|
// journal format:
|
||||||
// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ]
|
// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ]
|
||||||
// [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ]
|
// [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ]
|
||||||
@ -514,7 +514,7 @@ impl JournalDB for EarlyMergeDB {
|
|||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject(&mut self, batch: &DBTransaction) -> Result<u32, UtilError> {
|
fn inject(&mut self, batch: &mut DBTransaction) -> Result<u32, UtilError> {
|
||||||
let mut ops = 0;
|
let mut ops = 0;
|
||||||
for (key, (value, rc)) in self.overlay.drain() {
|
for (key, (value, rc)) in self.overlay.drain() {
|
||||||
if rc != 0 { ops += 1 }
|
if rc != 0 { ops += 1 }
|
||||||
|
@ -222,7 +222,7 @@ impl JournalDB for OverlayRecentDB {
|
|||||||
.or_else(|| self.backing.get_by_prefix(self.column, &key[0..DB_PREFIX_LEN]).map(|b| b.to_vec()))
|
.or_else(|| self.backing.get_by_prefix(self.column, &key[0..DB_PREFIX_LEN]).map(|b| b.to_vec()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commit(&mut self, batch: &DBTransaction, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
fn commit(&mut self, batch: &mut DBTransaction, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
||||||
// record new commit's details.
|
// record new commit's details.
|
||||||
trace!("commit: #{} ({}), end era: {:?}", now, id, end);
|
trace!("commit: #{} ({}), end era: {:?}", now, id, end);
|
||||||
let mut journal_overlay = self.journal_overlay.write();
|
let mut journal_overlay = self.journal_overlay.write();
|
||||||
@ -314,7 +314,7 @@ impl JournalDB for OverlayRecentDB {
|
|||||||
self.journal_overlay.write().pending_overlay.clear();
|
self.journal_overlay.write().pending_overlay.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject(&mut self, batch: &DBTransaction) -> Result<u32, UtilError> {
|
fn inject(&mut self, batch: &mut DBTransaction) -> Result<u32, UtilError> {
|
||||||
let mut ops = 0;
|
let mut ops = 0;
|
||||||
for (key, (value, rc)) in self.transaction_overlay.drain() {
|
for (key, (value, rc)) in self.transaction_overlay.drain() {
|
||||||
if rc != 0 { ops += 1 }
|
if rc != 0 { ops += 1 }
|
||||||
|
@ -109,7 +109,7 @@ impl JournalDB for RefCountedDB {
|
|||||||
self.backing.get_by_prefix(self.column, &id[0..DB_PREFIX_LEN]).map(|b| b.to_vec())
|
self.backing.get_by_prefix(self.column, &id[0..DB_PREFIX_LEN]).map(|b| b.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commit(&mut self, batch: &DBTransaction, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
fn commit(&mut self, batch: &mut DBTransaction, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
||||||
// journal format:
|
// journal format:
|
||||||
// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ]
|
// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ]
|
||||||
// [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ]
|
// [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ]
|
||||||
@ -182,11 +182,11 @@ impl JournalDB for RefCountedDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = try!(self.forward.commit_to_batch(&batch));
|
let r = try!(self.forward.commit_to_batch(batch));
|
||||||
Ok(r)
|
Ok(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject(&mut self, batch: &DBTransaction) -> Result<u32, UtilError> {
|
fn inject(&mut self, batch: &mut DBTransaction) -> Result<u32, UtilError> {
|
||||||
self.inserts.clear();
|
self.inserts.clear();
|
||||||
for remove in self.removes.drain(..) {
|
for remove in self.removes.drain(..) {
|
||||||
self.forward.remove(&remove);
|
self.forward.remove(&remove);
|
||||||
|
@ -37,7 +37,7 @@ pub trait JournalDB: HashDB {
|
|||||||
|
|
||||||
/// Commit all recent insert operations and canonical historical commits' removals from the
|
/// Commit all recent insert operations and canonical historical commits' removals from the
|
||||||
/// old era to the backing database, reverting any non-canonical historical commit's inserts.
|
/// old era to the backing database, reverting any non-canonical historical commit's inserts.
|
||||||
fn commit(&mut self, batch: &DBTransaction, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError>;
|
fn commit(&mut self, batch: &mut DBTransaction, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError>;
|
||||||
|
|
||||||
/// Commit all queued insert and delete operations without affecting any journalling -- this requires that all insertions
|
/// Commit all queued insert and delete operations without affecting any journalling -- this requires that all insertions
|
||||||
/// and deletions are indeed canonical and will likely lead to an invalid database if that assumption is violated.
|
/// and deletions are indeed canonical and will likely lead to an invalid database if that assumption is violated.
|
||||||
@ -46,7 +46,7 @@ pub trait JournalDB: HashDB {
|
|||||||
/// by any previous `commit` operations. Essentially, this means that `inject` can be used
|
/// by any previous `commit` operations. Essentially, this means that `inject` can be used
|
||||||
/// either to restore a state to a fresh database, or to insert data which may only be journalled
|
/// either to restore a state to a fresh database, or to insert data which may only be journalled
|
||||||
/// from this point onwards.
|
/// from this point onwards.
|
||||||
fn inject(&mut self, batch: &DBTransaction) -> Result<u32, UtilError>;
|
fn inject(&mut self, batch: &mut DBTransaction) -> Result<u32, UtilError>;
|
||||||
|
|
||||||
/// State data query
|
/// State data query
|
||||||
fn state(&self, _id: &H256) -> Option<Bytes>;
|
fn state(&self, _id: &H256) -> Option<Bytes>;
|
||||||
@ -67,8 +67,8 @@ pub trait JournalDB: HashDB {
|
|||||||
/// Commit all changes in a single batch
|
/// Commit all changes in a single batch
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn commit_batch(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
fn commit_batch(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
|
||||||
let batch = self.backing().transaction();
|
let mut batch = self.backing().transaction();
|
||||||
let res = try!(self.commit(&batch, now, id, end));
|
let res = try!(self.commit(&mut batch, now, id, end));
|
||||||
let result = self.backing().write(batch).map(|_| res).map_err(Into::into);
|
let result = self.backing().write(batch).map(|_| res).map_err(Into::into);
|
||||||
self.flush();
|
self.flush();
|
||||||
result
|
result
|
||||||
@ -77,8 +77,8 @@ pub trait JournalDB: HashDB {
|
|||||||
/// Inject all changes in a single batch.
|
/// Inject all changes in a single batch.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn inject_batch(&mut self) -> Result<u32, UtilError> {
|
fn inject_batch(&mut self) -> Result<u32, UtilError> {
|
||||||
let batch = self.backing().transaction();
|
let mut batch = self.backing().transaction();
|
||||||
let res = try!(self.inject(&batch));
|
let res = try!(self.inject(&mut batch));
|
||||||
self.backing().write(batch).map(|_| res).map_err(Into::into)
|
self.backing().write(batch).map(|_| res).map_err(Into::into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ const DB_BACKGROUND_COMPACTIONS: i32 = 2;
|
|||||||
|
|
||||||
/// Write transaction. Batches a sequence of put/delete operations for efficiency.
|
/// Write transaction. Batches a sequence of put/delete operations for efficiency.
|
||||||
pub struct DBTransaction {
|
pub struct DBTransaction {
|
||||||
ops: Mutex<Vec<DBOp>>,
|
ops: Vec<DBOp>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DBOp {
|
enum DBOp {
|
||||||
@ -52,15 +52,15 @@ impl DBTransaction {
|
|||||||
/// Create new transaction.
|
/// Create new transaction.
|
||||||
pub fn new(_db: &Database) -> DBTransaction {
|
pub fn new(_db: &Database) -> DBTransaction {
|
||||||
DBTransaction {
|
DBTransaction {
|
||||||
ops: Mutex::new(Vec::with_capacity(256)),
|
ops: Vec::with_capacity(256),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten upon write.
|
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten upon write.
|
||||||
pub fn put(&self, col: Option<u32>, key: &[u8], value: &[u8]) {
|
pub fn put(&mut self, col: Option<u32>, key: &[u8], value: &[u8]) {
|
||||||
let mut ekey = ElasticArray32::new();
|
let mut ekey = ElasticArray32::new();
|
||||||
ekey.append_slice(key);
|
ekey.append_slice(key);
|
||||||
self.ops.lock().push(DBOp::Insert {
|
self.ops.push(DBOp::Insert {
|
||||||
col: col,
|
col: col,
|
||||||
key: ekey,
|
key: ekey,
|
||||||
value: value.to_vec(),
|
value: value.to_vec(),
|
||||||
@ -68,10 +68,10 @@ impl DBTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten upon write.
|
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten upon write.
|
||||||
pub fn put_vec(&self, col: Option<u32>, key: &[u8], value: Bytes) {
|
pub fn put_vec(&mut self, col: Option<u32>, key: &[u8], value: Bytes) {
|
||||||
let mut ekey = ElasticArray32::new();
|
let mut ekey = ElasticArray32::new();
|
||||||
ekey.append_slice(key);
|
ekey.append_slice(key);
|
||||||
self.ops.lock().push(DBOp::Insert {
|
self.ops.push(DBOp::Insert {
|
||||||
col: col,
|
col: col,
|
||||||
key: ekey,
|
key: ekey,
|
||||||
value: value,
|
value: value,
|
||||||
@ -79,11 +79,11 @@ impl DBTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten upon write.
|
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten upon write.
|
||||||
/// Value will be RLP-compressed on flush
|
/// Value will be RLP-compressed on flush
|
||||||
pub fn put_compressed(&self, col: Option<u32>, key: &[u8], value: Bytes) {
|
pub fn put_compressed(&mut self, col: Option<u32>, key: &[u8], value: Bytes) {
|
||||||
let mut ekey = ElasticArray32::new();
|
let mut ekey = ElasticArray32::new();
|
||||||
ekey.append_slice(key);
|
ekey.append_slice(key);
|
||||||
self.ops.lock().push(DBOp::InsertCompressed {
|
self.ops.push(DBOp::InsertCompressed {
|
||||||
col: col,
|
col: col,
|
||||||
key: ekey,
|
key: ekey,
|
||||||
value: value,
|
value: value,
|
||||||
@ -91,10 +91,10 @@ impl DBTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Delete value by key.
|
/// Delete value by key.
|
||||||
pub fn delete(&self, col: Option<u32>, key: &[u8]) {
|
pub fn delete(&mut self, col: Option<u32>, key: &[u8]) {
|
||||||
let mut ekey = ElasticArray32::new();
|
let mut ekey = ElasticArray32::new();
|
||||||
ekey.append_slice(key);
|
ekey.append_slice(key);
|
||||||
self.ops.lock().push(DBOp::Delete {
|
self.ops.push(DBOp::Delete {
|
||||||
col: col,
|
col: col,
|
||||||
key: ekey,
|
key: ekey,
|
||||||
});
|
});
|
||||||
@ -299,7 +299,7 @@ impl Database {
|
|||||||
/// Commit transaction to database.
|
/// Commit transaction to database.
|
||||||
pub fn write_buffered(&self, tr: DBTransaction) {
|
pub fn write_buffered(&self, tr: DBTransaction) {
|
||||||
let mut overlay = self.overlay.write();
|
let mut overlay = self.overlay.write();
|
||||||
let ops = tr.ops.into_inner();
|
let ops = tr.ops;
|
||||||
for op in ops {
|
for op in ops {
|
||||||
match op {
|
match op {
|
||||||
DBOp::Insert { col, key, value } => {
|
DBOp::Insert { col, key, value } => {
|
||||||
@ -359,7 +359,7 @@ impl Database {
|
|||||||
/// Commit transaction to database.
|
/// Commit transaction to database.
|
||||||
pub fn write(&self, tr: DBTransaction) -> Result<(), String> {
|
pub fn write(&self, tr: DBTransaction) -> Result<(), String> {
|
||||||
let batch = WriteBatch::new();
|
let batch = WriteBatch::new();
|
||||||
let ops = tr.ops.into_inner();
|
let ops = tr.ops;
|
||||||
for op in ops {
|
for op in ops {
|
||||||
match op {
|
match op {
|
||||||
DBOp::Insert { col, key, value } => {
|
DBOp::Insert { col, key, value } => {
|
||||||
@ -425,7 +425,7 @@ mod tests {
|
|||||||
let key2 = H256::from_str("03c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap();
|
let key2 = H256::from_str("03c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap();
|
||||||
let key3 = H256::from_str("01c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap();
|
let key3 = H256::from_str("01c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap();
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
batch.put(None, &key1, b"cat");
|
batch.put(None, &key1, b"cat");
|
||||||
batch.put(None, &key2, b"dog");
|
batch.put(None, &key2, b"dog");
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
@ -439,17 +439,17 @@ mod tests {
|
|||||||
assert_eq!(&*contents[1].0, &*key2);
|
assert_eq!(&*contents[1].0, &*key2);
|
||||||
assert_eq!(&*contents[1].1, b"dog");
|
assert_eq!(&*contents[1].1, b"dog");
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
batch.delete(None, &key1);
|
batch.delete(None, &key1);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
|
|
||||||
assert!(db.get(None, &key1).unwrap().is_none());
|
assert!(db.get(None, &key1).unwrap().is_none());
|
||||||
|
|
||||||
let batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
batch.put(None, &key1, b"cat");
|
batch.put(None, &key1, b"cat");
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
|
|
||||||
let transaction = db.transaction();
|
let mut transaction = db.transaction();
|
||||||
transaction.put(None, &key3, b"elephant");
|
transaction.put(None, &key3, b"elephant");
|
||||||
transaction.delete(None, &key1);
|
transaction.delete(None, &key1);
|
||||||
db.write(transaction).unwrap();
|
db.write(transaction).unwrap();
|
||||||
@ -459,7 +459,7 @@ mod tests {
|
|||||||
assert_eq!(&*db.get_by_prefix(None, &key3).unwrap(), b"elephant");
|
assert_eq!(&*db.get_by_prefix(None, &key3).unwrap(), b"elephant");
|
||||||
assert_eq!(&*db.get_by_prefix(None, &key2).unwrap(), b"dog");
|
assert_eq!(&*db.get_by_prefix(None, &key2).unwrap(), b"dog");
|
||||||
|
|
||||||
let transaction = db.transaction();
|
let mut transaction = db.transaction();
|
||||||
transaction.put(None, &key1, b"horse");
|
transaction.put(None, &key1, b"horse");
|
||||||
transaction.delete(None, &key3);
|
transaction.delete(None, &key3);
|
||||||
db.write_buffered(transaction);
|
db.write_buffered(transaction);
|
||||||
|
@ -72,7 +72,7 @@ impl Batch {
|
|||||||
pub fn commit(&mut self, dest: &mut Database) -> Result<(), Error> {
|
pub fn commit(&mut self, dest: &mut Database) -> Result<(), Error> {
|
||||||
if self.inner.is_empty() { return Ok(()) }
|
if self.inner.is_empty() { return Ok(()) }
|
||||||
|
|
||||||
let transaction = DBTransaction::new(dest);
|
let mut transaction = DBTransaction::new(dest);
|
||||||
|
|
||||||
for keypair in &self.inner {
|
for keypair in &self.inner {
|
||||||
transaction.put(self.column, &keypair.0, &keypair.1);
|
transaction.put(self.column, &keypair.0, &keypair.1);
|
||||||
|
@ -35,7 +35,7 @@ fn db_path(path: &Path) -> PathBuf {
|
|||||||
fn make_db(path: &Path, pairs: BTreeMap<Vec<u8>, Vec<u8>>) {
|
fn make_db(path: &Path, pairs: BTreeMap<Vec<u8>, Vec<u8>>) {
|
||||||
let db = Database::open_default(path.to_str().unwrap()).expect("failed to open temp database");
|
let db = Database::open_default(path.to_str().unwrap()).expect("failed to open temp database");
|
||||||
{
|
{
|
||||||
let transaction = db.transaction();
|
let mut transaction = db.transaction();
|
||||||
for (k, v) in pairs {
|
for (k, v) in pairs {
|
||||||
transaction.put(None, &k, &v);
|
transaction.put(None, &k, &v);
|
||||||
}
|
}
|
||||||
|
@ -58,13 +58,13 @@ impl OverlayDB {
|
|||||||
/// Commit all operations in a single batch.
|
/// Commit all operations in a single batch.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn commit(&mut self) -> Result<u32, UtilError> {
|
pub fn commit(&mut self) -> Result<u32, UtilError> {
|
||||||
let batch = self.backing.transaction();
|
let mut batch = self.backing.transaction();
|
||||||
let res = try!(self.commit_to_batch(&batch));
|
let res = try!(self.commit_to_batch(&mut batch));
|
||||||
self.backing.write(batch).map(|_| res).map_err(|e| e.into())
|
self.backing.write(batch).map(|_| res).map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Commit all operations to given batch.
|
/// Commit all operations to given batch.
|
||||||
pub fn commit_to_batch(&mut self, batch: &DBTransaction) -> Result<u32, UtilError> {
|
pub fn commit_to_batch(&mut self, batch: &mut DBTransaction) -> Result<u32, UtilError> {
|
||||||
let mut ret = 0u32;
|
let mut ret = 0u32;
|
||||||
let mut deletes = 0usize;
|
let mut deletes = 0usize;
|
||||||
for i in self.overlay.drain().into_iter() {
|
for i in self.overlay.drain().into_iter() {
|
||||||
@ -111,7 +111,7 @@ impl OverlayDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Put the refs and value of the given key, possibly deleting it from the db.
|
/// Put the refs and value of the given key, possibly deleting it from the db.
|
||||||
fn put_payload_in_batch(&self, batch: &DBTransaction, key: &H256, payload: (Bytes, u32)) -> bool {
|
fn put_payload_in_batch(&self, batch: &mut DBTransaction, key: &H256, payload: (Bytes, u32)) -> bool {
|
||||||
if payload.1 > 0 {
|
if payload.1 > 0 {
|
||||||
let mut s = RlpStream::new_list(2);
|
let mut s = RlpStream::new_list(2);
|
||||||
s.append(&payload.1);
|
s.append(&payload.1);
|
||||||
@ -195,8 +195,8 @@ impl HashDB for OverlayDB {
|
|||||||
fn overlaydb_revert() {
|
fn overlaydb_revert() {
|
||||||
let mut m = OverlayDB::new_temp();
|
let mut m = OverlayDB::new_temp();
|
||||||
let foo = m.insert(b"foo"); // insert foo.
|
let foo = m.insert(b"foo"); // insert foo.
|
||||||
let batch = m.backing.transaction();
|
let mut batch = m.backing.transaction();
|
||||||
m.commit_to_batch(&batch).unwrap(); // commit - new operations begin here...
|
m.commit_to_batch(&mut batch).unwrap(); // commit - new operations begin here...
|
||||||
m.backing.write(batch).unwrap();
|
m.backing.write(batch).unwrap();
|
||||||
let bar = m.insert(b"bar"); // insert bar.
|
let bar = m.insert(b"bar"); // insert bar.
|
||||||
m.remove(&foo); // remove foo.
|
m.remove(&foo); // remove foo.
|
||||||
@ -300,7 +300,7 @@ fn playpen() {
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
{
|
{
|
||||||
let db = Database::open_default("/tmp/test").unwrap();
|
let db = Database::open_default("/tmp/test").unwrap();
|
||||||
let batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
batch.put(None, b"test", b"test2");
|
batch.put(None, b"test", b"test2");
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
match db.get(None, b"test") {
|
match db.get(None, b"test") {
|
||||||
@ -308,7 +308,7 @@ fn playpen() {
|
|||||||
Ok(None) => println!("No value for that key"),
|
Ok(None) => println!("No value for that key"),
|
||||||
Err(..) => println!("Gah"),
|
Err(..) => println!("Gah"),
|
||||||
}
|
}
|
||||||
let batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
batch.delete(None, b"test");
|
batch.delete(None, b"test");
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user