Store TxOuts directly in UtxoSet rather than in Boxes

This gives a significant speedup during deserialization since we
don't have to allocate for every output.
This commit is contained in:
Andrew Poelstra 2014-07-23 11:27:03 -07:00
parent b5c25ff768
commit 1be45395da
1 changed files with 8 additions and 8 deletions

View File

@ -32,14 +32,14 @@ use util::uint::Uint128;
use util::thinvec::ThinVec;
/// Vector of outputs; None indicates a nonexistent or already spent output
type UtxoNode = ThinVec<Option<Box<TxOut>>>;
type UtxoNode = ThinVec<Option<TxOut>>;
/// The UTXO set
pub struct UtxoSet {
table: HashMap<Uint128, UtxoNode, DumbHasher>,
last_hash: Sha256dHash,
// A circular buffer of deleted utxos, grouped by block
spent_txos: Vec<Vec<Box<TxOut>>>,
spent_txos: Vec<Vec<TxOut>>,
// The last index into the above buffer that was assigned to
spent_idx: u64,
n_utxos: u64
@ -70,7 +70,7 @@ impl UtxoSet {
let mut new_node = ThinVec::with_capacity(tx.output.len() as u32);
for (vout, txo) in tx.output.iter().enumerate() {
// Unsafe since we are not uninitializing the old data in the vector
unsafe { new_node.init(vout as uint, Some(box txo.clone())); }
unsafe { new_node.init(vout as uint, Some(txo.clone())); }
}
// TODO: insert/lookup should return a Result which we pass along
if self.table.insert(txid.as_uint128(), new_node) {
@ -81,7 +81,7 @@ impl UtxoSet {
}
/// Remove a UTXO from the set and return it
fn take_utxo(&mut self, txid: Sha256dHash, vout: u32) -> Option<Box<TxOut>> {
fn take_utxo(&mut self, txid: Sha256dHash, vout: u32) -> Option<TxOut> {
// This whole function has awkward scoping thx to lexical borrow scoping :(
let (ret, should_delete) = {
// Locate the UTXO, failing if not found
@ -111,7 +111,7 @@ impl UtxoSet {
}
/// Get a reference to a UTXO in the set
pub fn get_utxo<'a>(&'a mut self, txid: Sha256dHash, vout: u32) -> Option<&'a Box<TxOut>> {
pub fn get_utxo<'a>(&'a mut self, txid: Sha256dHash, vout: u32) -> Option<&'a TxOut> {
// Locate the UTXO, failing if not found
let node = match self.table.find_mut(&txid.as_uint128()) {
Some(node) => node,
@ -289,7 +289,7 @@ mod tests {
let hash = tx.bitcoin_hash();
for (n, out) in tx.output.iter().enumerate() {
let n = n as u32;
assert_eq!(empty_set.get_utxo(hash, n), Some(&box out.clone()));
assert_eq!(empty_set.get_utxo(hash, n), Some(&out.clone()));
}
}
@ -301,7 +301,7 @@ mod tests {
let hash = tx.bitcoin_hash();
for (n, out) in tx.output.iter().enumerate() {
let n = n as u32;
assert_eq!(empty_set.get_utxo(hash, n), Some(&box out.clone()));
assert_eq!(empty_set.get_utxo(hash, n), Some(&out.clone()));
}
}
@ -323,7 +323,7 @@ mod tests {
assert_eq!(read_set.take_utxo(hash, 100 + n), None);
// Check take of real UTXO
let ret = read_set.take_utxo(hash, n);
assert_eq!(ret, Some(box out.clone()));
assert_eq!(ret, Some(out.clone()));
// Try double-take
assert_eq!(read_set.take_utxo(hash, n), None);
}