Cleanup generics (where not needed) (#1429)

BlockChain does not need to be generic
This commit is contained in:
Antioch Peverell 2018-08-27 22:22:48 +01:00 committed by Ignotus Peverell
parent dd164e153d
commit a6bd81fdb3
16 changed files with 78 additions and 113 deletions

View file

@ -694,14 +694,11 @@ impl Handler for HeaderHandler {
} }
// Get basic information about the transaction pool. // Get basic information about the transaction pool.
struct PoolInfoHandler<T> { struct PoolInfoHandler {
tx_pool: Weak<RwLock<pool::TransactionPool<T>>>, tx_pool: Weak<RwLock<pool::TransactionPool>>,
} }
impl<T> Handler for PoolInfoHandler<T> impl Handler for PoolInfoHandler {
where
T: pool::BlockChain + Send + Sync,
{
fn get(&self, _req: Request<Body>) -> ResponseFuture { fn get(&self, _req: Request<Body>) -> ResponseFuture {
let pool_arc = w(&self.tx_pool); let pool_arc = w(&self.tx_pool);
let pool = pool_arc.read().unwrap(); let pool = pool_arc.read().unwrap();
@ -719,14 +716,11 @@ struct TxWrapper {
} }
// Push new transaction to our local transaction pool. // Push new transaction to our local transaction pool.
struct PoolPushHandler<T> { struct PoolPushHandler {
tx_pool: Weak<RwLock<pool::TransactionPool<T>>>, tx_pool: Weak<RwLock<pool::TransactionPool>>,
} }
impl<T> PoolPushHandler<T> impl PoolPushHandler {
where
T: pool::BlockChain + Send + Sync + 'static,
{
fn update_pool(&self, req: Request<Body>) -> Box<Future<Item = (), Error = Error> + Send> { fn update_pool(&self, req: Request<Body>) -> Box<Future<Item = (), Error = Error> + Send> {
let params = match req.uri().query() { let params = match req.uri().query() {
Some(query_string) => form_urlencoded::parse(query_string.as_bytes()) Some(query_string) => form_urlencoded::parse(query_string.as_bytes())
@ -779,10 +773,7 @@ where
} }
} }
impl<T> Handler for PoolPushHandler<T> impl Handler for PoolPushHandler {
where
T: pool::BlockChain + Send + Sync + 'static,
{
fn post(&self, req: Request<Body>) -> ResponseFuture { fn post(&self, req: Request<Body>) -> ResponseFuture {
Box::new( Box::new(
self.update_pool(req) self.update_pool(req)
@ -861,14 +852,12 @@ thread_local!( static ROUTER: RefCell<Option<Router>> = RefCell::new(None) );
/// weak references. Note that this likely means a crash if the handlers are /// weak references. Note that this likely means a crash if the handlers are
/// used after a server shutdown (which should normally never happen, /// used after a server shutdown (which should normally never happen,
/// except during tests). /// except during tests).
pub fn start_rest_apis<T>( pub fn start_rest_apis(
addr: String, addr: String,
chain: Weak<chain::Chain>, chain: Weak<chain::Chain>,
tx_pool: Weak<RwLock<pool::TransactionPool<T>>>, tx_pool: Weak<RwLock<pool::TransactionPool>>,
peers: Weak<p2p::Peers>, peers: Weak<p2p::Peers>,
) where ) {
T: pool::BlockChain + Send + Sync + 'static,
{
let _ = thread::Builder::new() let _ = thread::Builder::new()
.name("apis".to_string()) .name("apis".to_string())
.spawn(move || { .spawn(move || {
@ -912,14 +901,11 @@ where
) )
} }
pub fn build_router<T>( pub fn build_router(
chain: Weak<chain::Chain>, chain: Weak<chain::Chain>,
tx_pool: Weak<RwLock<pool::TransactionPool<T>>>, tx_pool: Weak<RwLock<pool::TransactionPool>>,
peers: Weak<p2p::Peers>, peers: Weak<p2p::Peers>,
) -> Result<Router, RouterError> ) -> Result<Router, RouterError> {
where
T: pool::BlockChain + Send + Sync + 'static,
{
let route_list = vec![ let route_list = vec![
"get blocks".to_string(), "get blocks".to_string(),
"get chain".to_string(), "get chain".to_string(),

View file

@ -550,10 +550,12 @@ impl Chain {
/// If we're willing to accept that new state, the data stream will be /// If we're willing to accept that new state, the data stream will be
/// read as a zip file, unzipped and the resulting state files should be /// read as a zip file, unzipped and the resulting state files should be
/// rewound to the provided indexes. /// rewound to the provided indexes.
pub fn txhashset_write<T>(&self, h: Hash, txhashset_data: File, status: &T) -> Result<(), Error> pub fn txhashset_write(
where &self,
T: TxHashsetWriteStatus, h: Hash,
{ txhashset_data: File,
status: &TxHashsetWriteStatus,
) -> Result<(), Error> {
status.on_setup(); status.on_setup();
let head = self.head().unwrap(); let head = self.head().unwrap();
let header_head = self.get_header_head().unwrap(); let header_head = self.get_header_head().unwrap();

View file

@ -866,15 +866,12 @@ impl<'a> Extension<'a> {
} }
/// Validate the txhashset state against the provided block header. /// Validate the txhashset state against the provided block header.
pub fn validate<T>( pub fn validate(
&mut self, &mut self,
header: &BlockHeader, header: &BlockHeader,
skip_rproofs: bool, skip_rproofs: bool,
status: &T, status: &TxHashsetWriteStatus,
) -> Result<((Commitment, Commitment)), Error> ) -> Result<((Commitment, Commitment)), Error> {
where
T: TxHashsetWriteStatus,
{
self.validate_mmrs()?; self.validate_mmrs()?;
self.validate_roots(header)?; self.validate_roots(header)?;
@ -952,10 +949,7 @@ impl<'a> Extension<'a> {
) )
} }
fn verify_kernel_signatures<T>(&self, status: &T) -> Result<(), Error> fn verify_kernel_signatures(&self, status: &TxHashsetWriteStatus) -> Result<(), Error> {
where
T: TxHashsetWriteStatus,
{
let now = Instant::now(); let now = Instant::now();
let mut kern_count = 0; let mut kern_count = 0;
@ -983,10 +977,7 @@ impl<'a> Extension<'a> {
Ok(()) Ok(())
} }
fn verify_rangeproofs<T>(&self, status: &T) -> Result<(), Error> fn verify_rangeproofs(&self, status: &TxHashsetWriteStatus) -> Result<(), Error> {
where
T: TxHashsetWriteStatus,
{
let now = Instant::now(); let now = Instant::now();
let mut commits: Vec<Commitment> = vec![]; let mut commits: Vec<Commitment> = vec![];

View file

@ -33,19 +33,16 @@ const MAX_MINEABLE_WEIGHT: usize =
// longest chain of dependent transactions that can be included in a block // longest chain of dependent transactions that can be included in a block
const MAX_TX_CHAIN: usize = 20; const MAX_TX_CHAIN: usize = 20;
pub struct Pool<T> { pub struct Pool {
/// Entries in the pool (tx + info + timer) in simple insertion order. /// Entries in the pool (tx + info + timer) in simple insertion order.
pub entries: Vec<PoolEntry>, pub entries: Vec<PoolEntry>,
/// The blockchain /// The blockchain
pub blockchain: Arc<T>, pub blockchain: Arc<BlockChain>,
pub name: String, pub name: String,
} }
impl<T> Pool<T> impl Pool {
where pub fn new(chain: Arc<BlockChain>, name: String) -> Pool {
T: BlockChain,
{
pub fn new(chain: Arc<T>, name: String) -> Pool<T> {
Pool { Pool {
entries: vec![], entries: vec![],
blockchain: chain.clone(), blockchain: chain.clone(),

View file

@ -26,27 +26,26 @@ use pool::Pool;
use types::{BlockChain, PoolAdapter, PoolConfig, PoolEntry, PoolEntryState, PoolError, TxSource}; use types::{BlockChain, PoolAdapter, PoolConfig, PoolEntry, PoolEntryState, PoolError, TxSource};
/// Transaction pool implementation. /// Transaction pool implementation.
pub struct TransactionPool<T> { pub struct TransactionPool {
/// Pool Config /// Pool Config
pub config: PoolConfig, pub config: PoolConfig,
/// Our transaction pool. /// Our transaction pool.
pub txpool: Pool<T>, pub txpool: Pool,
/// Our Dandelion "stempool". /// Our Dandelion "stempool".
pub stempool: Pool<T>, pub stempool: Pool,
/// The blockchain /// The blockchain
pub blockchain: Arc<T>, pub blockchain: Arc<BlockChain>,
/// The pool adapter /// The pool adapter
pub adapter: Arc<PoolAdapter>, pub adapter: Arc<PoolAdapter>,
} }
impl<T> TransactionPool<T> impl TransactionPool {
where
T: BlockChain,
{
/// Create a new transaction pool /// Create a new transaction pool
pub fn new(config: PoolConfig, chain: Arc<T>, adapter: Arc<PoolAdapter>) -> TransactionPool<T> { pub fn new(
config: PoolConfig,
chain: Arc<BlockChain>,
adapter: Arc<PoolAdapter>,
) -> TransactionPool {
TransactionPool { TransactionPool {
config: config, config: config,
txpool: Pool::new(chain.clone(), format!("txpool")), txpool: Pool::new(chain.clone(), format!("txpool")),

View file

@ -187,7 +187,7 @@ impl From<transaction::Error> for PoolError {
} }
/// Interface that the pool requires from a blockchain implementation. /// Interface that the pool requires from a blockchain implementation.
pub trait BlockChain { pub trait BlockChain: Sync + Send {
/// Validate a vec of txs against known chain state at specific block /// Validate a vec of txs against known chain state at specific block
/// after applying the pre_tx to the chain state. /// after applying the pre_tx to the chain state.
fn validate_raw_txs( fn validate_raw_txs(

View file

@ -34,15 +34,13 @@ use keychain::{ExtKeychain, Keychain};
use pool::types::{BlockChain, NoopAdapter, PoolConfig, PoolError}; use pool::types::{BlockChain, NoopAdapter, PoolConfig, PoolError};
use pool::TransactionPool; use pool::TransactionPool;
pub fn test_setup( pub fn test_setup(chain: CoinbaseMaturityErrorChainAdapter) -> TransactionPool {
chain: &Arc<CoinbaseMaturityErrorChainAdapter>,
) -> TransactionPool<CoinbaseMaturityErrorChainAdapter> {
TransactionPool::new( TransactionPool::new(
PoolConfig { PoolConfig {
accept_fee_base: 0, accept_fee_base: 0,
max_pool_size: 50, max_pool_size: 50,
}, },
chain.clone(), Arc::new(chain.clone()),
Arc::new(NoopAdapter {}), Arc::new(NoopAdapter {}),
) )
} }
@ -89,7 +87,7 @@ fn test_coinbase_maturity() {
// Mocking this up with an adapter that will raise an error for coinbase // Mocking this up with an adapter that will raise an error for coinbase
// maturity. // maturity.
let chain = CoinbaseMaturityErrorChainAdapter::new(); let chain = CoinbaseMaturityErrorChainAdapter::new();
let pool = RwLock::new(test_setup(&Arc::new(chain.clone()))); let pool = RwLock::new(test_setup(chain));
{ {
let mut write_pool = pool.write().unwrap(); let mut write_pool = pool.write().unwrap();

View file

@ -105,7 +105,7 @@ impl BlockChain for ChainAdapter {
} }
} }
pub fn test_setup(chain: &Arc<ChainAdapter>) -> TransactionPool<ChainAdapter> { pub fn test_setup(chain: &Arc<ChainAdapter>) -> TransactionPool {
TransactionPool::new( TransactionPool::new(
PoolConfig { PoolConfig {
accept_fee_base: 0, accept_fee_base: 0,

View file

@ -53,7 +53,7 @@ pub struct NetToChainAdapter {
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
archive_mode: bool, archive_mode: bool,
chain: Weak<chain::Chain>, chain: Weak<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: Arc<RwLock<pool::TransactionPool>>,
peers: OneTime<Weak<p2p::Peers>>, peers: OneTime<Weak<p2p::Peers>>,
config: ServerConfig, config: ServerConfig,
} }
@ -164,7 +164,8 @@ impl p2p::ChainAdapter for NetToChainAdapter {
} }
}; };
let chain = self.chain let chain = self
.chain
.upgrade() .upgrade()
.expect("failed to upgrade weak ref to chain"); .expect("failed to upgrade weak ref to chain");
@ -372,7 +373,7 @@ impl NetToChainAdapter {
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
archive_mode: bool, archive_mode: bool,
chain_ref: Weak<chain::Chain>, chain_ref: Weak<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: Arc<RwLock<pool::TransactionPool>>,
config: ServerConfig, config: ServerConfig,
) -> NetToChainAdapter { ) -> NetToChainAdapter {
NetToChainAdapter { NetToChainAdapter {
@ -437,7 +438,8 @@ impl NetToChainAdapter {
// we have a fast sync'd node and are sent a block older than our horizon, // we have a fast sync'd node and are sent a block older than our horizon,
// only sync can do something with that // only sync can do something with that
if b.header.height if b.header.height
< head.height < head
.height
.saturating_sub(global::cut_through_horizon() as u64) .saturating_sub(global::cut_through_horizon() as u64)
{ {
return true; return true;
@ -602,7 +604,7 @@ impl NetToChainAdapter {
/// the network to broadcast the block /// the network to broadcast the block
pub struct ChainToPoolAndNetAdapter { pub struct ChainToPoolAndNetAdapter {
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: Arc<RwLock<pool::TransactionPool>>,
peers: OneTime<Weak<p2p::Peers>>, peers: OneTime<Weak<p2p::Peers>>,
} }
@ -665,7 +667,7 @@ impl ChainToPoolAndNetAdapter {
/// Construct a ChainToPoolAndNetAdapter instance. /// Construct a ChainToPoolAndNetAdapter instance.
pub fn new( pub fn new(
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: Arc<RwLock<pool::TransactionPool>>,
) -> ChainToPoolAndNetAdapter { ) -> ChainToPoolAndNetAdapter {
ChainToPoolAndNetAdapter { ChainToPoolAndNetAdapter {
sync_state, sync_state,

View file

@ -21,7 +21,7 @@ use std::time::Duration;
use core::core::hash::Hashed; use core::core::hash::Hashed;
use core::core::transaction; use core::core::transaction;
use pool::{BlockChain, DandelionConfig, PoolEntryState, PoolError, TransactionPool, TxSource}; use pool::{DandelionConfig, PoolEntryState, PoolError, TransactionPool, TxSource};
use util::LOGGER; use util::LOGGER;
/// A process to monitor transactions in the stempool. /// A process to monitor transactions in the stempool.
@ -32,13 +32,11 @@ use util::LOGGER;
/// stempool and test if the timer is expired for each transaction. In that case /// stempool and test if the timer is expired for each transaction. In that case
/// the transaction will be sent in fluff phase (to multiple peers) instead of /// the transaction will be sent in fluff phase (to multiple peers) instead of
/// sending only to the peer relay. /// sending only to the peer relay.
pub fn monitor_transactions<T>( pub fn monitor_transactions(
dandelion_config: DandelionConfig, dandelion_config: DandelionConfig,
tx_pool: Arc<RwLock<TransactionPool<T>>>, tx_pool: Arc<RwLock<TransactionPool>>,
stop: Arc<AtomicBool>, stop: Arc<AtomicBool>,
) where ) {
T: BlockChain + Send + Sync + 'static,
{
debug!(LOGGER, "Started Dandelion transaction monitor."); debug!(LOGGER, "Started Dandelion transaction monitor.");
let _ = thread::Builder::new() let _ = thread::Builder::new()
@ -84,10 +82,7 @@ pub fn monitor_transactions<T>(
}); });
} }
fn process_stem_phase<T>(tx_pool: Arc<RwLock<TransactionPool<T>>>) -> Result<(), PoolError> fn process_stem_phase(tx_pool: Arc<RwLock<TransactionPool>>) -> Result<(), PoolError> {
where
T: BlockChain + Send + Sync + 'static,
{
let mut tx_pool = tx_pool.write().unwrap(); let mut tx_pool = tx_pool.write().unwrap();
let header = tx_pool.blockchain.chain_head()?; let header = tx_pool.blockchain.chain_head()?;
@ -127,10 +122,7 @@ where
Ok(()) Ok(())
} }
fn process_fluff_phase<T>(tx_pool: Arc<RwLock<TransactionPool<T>>>) -> Result<(), PoolError> fn process_fluff_phase(tx_pool: Arc<RwLock<TransactionPool>>) -> Result<(), PoolError> {
where
T: BlockChain + Send + Sync + 'static,
{
let mut tx_pool = tx_pool.write().unwrap(); let mut tx_pool = tx_pool.write().unwrap();
let header = tx_pool.blockchain.chain_head()?; let header = tx_pool.blockchain.chain_head()?;
@ -162,13 +154,10 @@ where
Ok(()) Ok(())
} }
fn process_fresh_entries<T>( fn process_fresh_entries(
dandelion_config: DandelionConfig, dandelion_config: DandelionConfig,
tx_pool: Arc<RwLock<TransactionPool<T>>>, tx_pool: Arc<RwLock<TransactionPool>>,
) -> Result<(), PoolError> ) -> Result<(), PoolError> {
where
T: BlockChain + Send + Sync + 'static,
{
let mut tx_pool = tx_pool.write().unwrap(); let mut tx_pool = tx_pool.write().unwrap();
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
@ -199,13 +188,10 @@ where
Ok(()) Ok(())
} }
fn process_expired_entries<T>( fn process_expired_entries(
dandelion_config: DandelionConfig, dandelion_config: DandelionConfig,
tx_pool: Arc<RwLock<TransactionPool<T>>>, tx_pool: Arc<RwLock<TransactionPool>>,
) -> Result<(), PoolError> ) -> Result<(), PoolError> {
where
T: BlockChain + Send + Sync + 'static,
{
let now = Utc::now().timestamp(); let now = Utc::now().timestamp();
let embargo_sec = dandelion_config.embargo_secs.unwrap() + rand::thread_rng().gen_range(0, 31); let embargo_sec = dandelion_config.embargo_secs.unwrap() + rand::thread_rng().gen_range(0, 31);
let cutoff = now - embargo_sec as i64; let cutoff = now - embargo_sec as i64;

View file

@ -48,7 +48,7 @@ pub struct Server {
/// data store access /// data store access
pub chain: Arc<chain::Chain>, pub chain: Arc<chain::Chain>,
/// in-memory transaction pool /// in-memory transaction pool
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: Arc<RwLock<pool::TransactionPool>>,
/// Whether we're currently syncing /// Whether we're currently syncing
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
/// To be passed around to collect stats and info /// To be passed around to collect stats and info
@ -421,7 +421,8 @@ impl Server {
} }
}; };
let peer_stats = self.p2p let peer_stats = self
.p2p
.peers .peers
.connected_peers() .connected_peers()
.into_iter() .into_iter()

View file

@ -23,7 +23,6 @@ use std::thread;
use std::time::Duration; use std::time::Duration;
use chain; use chain;
use common::adapters::PoolToChainAdapter;
use common::types::Error; use common::types::Error;
use core::ser::{self, AsFixedBytes}; use core::ser::{self, AsFixedBytes};
use core::{consensus, core}; use core::{consensus, core};
@ -76,7 +75,7 @@ impl ser::Writer for HeaderPrePowWriter {
// Warning: This call does not return until/unless a new block can be built // Warning: This call does not return until/unless a new block can be built
pub fn get_block( pub fn get_block(
chain: &Arc<chain::Chain>, chain: &Arc<chain::Chain>,
tx_pool: &Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: &Arc<RwLock<pool::TransactionPool>>,
key_id: Option<Identifier>, key_id: Option<Identifier>,
wallet_listener_url: Option<String>, wallet_listener_url: Option<String>,
) -> (core::Block, BlockFees) { ) -> (core::Block, BlockFees) {
@ -118,7 +117,7 @@ pub fn get_block(
/// transactions from the pool. /// transactions from the pool.
fn build_block( fn build_block(
chain: &Arc<chain::Chain>, chain: &Arc<chain::Chain>,
tx_pool: &Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: &Arc<RwLock<pool::TransactionPool>>,
key_id: Option<Identifier>, key_id: Option<Identifier>,
wallet_listener_url: Option<String>, wallet_listener_url: Option<String>,
) -> Result<(core::Block, BlockFees), Error> { ) -> Result<(core::Block, BlockFees), Error> {

View file

@ -26,7 +26,6 @@ use std::time::{Duration, SystemTime};
use std::{cmp, thread}; use std::{cmp, thread};
use chain; use chain;
use common::adapters::PoolToChainAdapter;
use common::stats::{StratumStats, WorkerStats}; use common::stats::{StratumStats, WorkerStats};
use common::types::{StratumServerConfig, SyncState}; use common::types::{StratumServerConfig, SyncState};
use core::core::Block; use core::core::Block;
@ -229,7 +228,7 @@ pub struct StratumServer {
id: String, id: String,
config: StratumServerConfig, config: StratumServerConfig,
chain: Arc<chain::Chain>, chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: Arc<RwLock<pool::TransactionPool>>,
current_block_versions: Vec<Block>, current_block_versions: Vec<Block>,
current_difficulty: u64, current_difficulty: u64,
minimum_share_difficulty: u64, minimum_share_difficulty: u64,
@ -243,7 +242,7 @@ impl StratumServer {
pub fn new( pub fn new(
config: StratumServerConfig, config: StratumServerConfig,
chain_ref: Arc<chain::Chain>, chain_ref: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: Arc<RwLock<pool::TransactionPool>>,
) -> StratumServer { ) -> StratumServer {
StratumServer { StratumServer {
id: String::from("StratumServer"), id: String::from("StratumServer"),

View file

@ -22,7 +22,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use chain; use chain;
use common::adapters::PoolToChainAdapter;
use common::types::StratumServerConfig; use common::types::StratumServerConfig;
use core::core::hash::{Hash, Hashed}; use core::core::hash::{Hash, Hashed};
use core::core::{Block, BlockHeader, Proof}; use core::core::{Block, BlockHeader, Proof};
@ -35,7 +34,7 @@ use util::LOGGER;
pub struct Miner { pub struct Miner {
config: StratumServerConfig, config: StratumServerConfig,
chain: Arc<chain::Chain>, chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: Arc<RwLock<pool::TransactionPool>>,
stop: Arc<AtomicBool>, stop: Arc<AtomicBool>,
// Just to hold the port we're on, so this miner can be identified // Just to hold the port we're on, so this miner can be identified
@ -49,7 +48,7 @@ impl Miner {
pub fn new( pub fn new(
config: StratumServerConfig, config: StratumServerConfig,
chain_ref: Arc<chain::Chain>, chain_ref: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>, tx_pool: Arc<RwLock<pool::TransactionPool>>,
stop: Arc<AtomicBool>, stop: Arc<AtomicBool>,
) -> Miner { ) -> Miner {
Miner { Miner {

View file

@ -35,6 +35,9 @@ pub struct LeafSet {
bitmap_bak: Bitmap, bitmap_bak: Bitmap,
} }
unsafe impl Send for LeafSet {}
unsafe impl Sync for LeafSet {}
impl LeafSet { impl LeafSet {
/// Open the remove log file. /// Open the remove log file.
/// The content of the file will be read in memory for fast checking. /// The content of the file will be read in memory for fast checking.

View file

@ -48,6 +48,9 @@ pub struct PruneList {
bitmap: Bitmap, bitmap: Bitmap,
} }
unsafe impl Send for PruneList {}
unsafe impl Sync for PruneList {}
impl PruneList { impl PruneList {
/// Instantiate a new empty prune list /// Instantiate a new empty prune list
pub fn new() -> PruneList { pub fn new() -> PruneList {