Update index once (instead at each status RPC)

This commit is contained in:
Roman Zeyde 2018-05-22 10:17:02 +03:00
parent e5da12a5e8
commit 4747e380ec
No known key found for this signature in database
GPG Key ID: 87CAE5FA46917CBB
3 changed files with 24 additions and 18 deletions

View File

@ -83,16 +83,15 @@ fn run_server(config: &Config) {
let query = query::Query::new(&store, &daemon, &index); let query = query::Query::new(&store, &daemon, &index);
crossbeam::scope(|scope| { crossbeam::scope(|scope| {
let poll_delay = Duration::from_secs(1); let poll_delay = Duration::from_secs(5);
scope.spawn(|| rpc::serve(config.rpc_addr(), &query)); scope.spawn(|| rpc::serve(config.rpc_addr(), &query));
loop { loop {
thread::sleep(poll_delay); thread::sleep(poll_delay);
query.update_mempool().unwrap(); query.update_mempool().unwrap();
if tip == daemon.getbestblockhash().unwrap() { if tip != daemon.getbestblockhash().unwrap() {
continue;
}
tip = index.update(&store, &daemon); tip = index.update(&store, &daemon);
} }
}
}); });
} }

View File

@ -21,11 +21,15 @@ struct MempoolStore {
} }
impl MempoolStore { impl MempoolStore {
pub fn new() -> MempoolStore { fn new() -> MempoolStore {
MempoolStore { MempoolStore {
map: RwLock::new(BTreeMap::new()), map: RwLock::new(BTreeMap::new()),
} }
} }
fn clear(&self) {
self.map.write().unwrap().clear()
}
} }
impl Store for MempoolStore { impl Store for MempoolStore {
@ -69,12 +73,14 @@ impl Stats {
pub struct Tracker { pub struct Tracker {
stats: HashMap<Sha256dHash, Stats>, stats: HashMap<Sha256dHash, Stats>,
index: MempoolStore,
} }
impl Tracker { impl Tracker {
pub fn new() -> Tracker { pub fn new() -> Tracker {
Tracker { Tracker {
stats: HashMap::new(), stats: HashMap::new(),
index: MempoolStore::new(),
} }
} }
@ -128,6 +134,14 @@ impl Tracker {
for txid in old_txids.difference(&new_txids) { for txid in old_txids.difference(&new_txids) {
self.remove(txid); self.remove(txid);
} }
let mut rows = Vec::new();
for stats in self.stats.values() {
index_transaction(&stats.tx, 0, &mut rows)
}
self.index.clear();
self.index.persist(rows);
debug!( debug!(
"mempool update took {:.1} ms ({} txns)", "mempool update took {:.1} ms ({} txns)",
t.elapsed().in_seconds() * 1e3, t.elapsed().in_seconds() * 1e3,
@ -144,14 +158,8 @@ impl Tracker {
self.stats.remove(txid); self.stats.remove(txid);
} }
pub fn build_index(&self) -> Box<Store> { pub fn index(&self) -> &Store {
let mut rows = Vec::new(); &self.index
for stats in self.stats.values() {
index_transaction(&stats.tx, 0, &mut rows)
}
let store = MempoolStore::new();
store.persist(rows);
Box::new(store)
} }
} }

View File

@ -213,17 +213,16 @@ impl<'a> Query<'a> {
fn mempool_status(&self, script_hash: &[u8], confirmed_status: &Status) -> Status { fn mempool_status(&self, script_hash: &[u8], confirmed_status: &Status) -> Status {
let mut funding = vec![]; let mut funding = vec![];
let mut spending = vec![]; let mut spending = vec![];
// TODO: build index once per Tracker::update() let tracker = self.tracker.read().unwrap();
let mempool_store = self.tracker.read().unwrap().build_index();
for t in self.load_txns( for t in self.load_txns(
&*mempool_store, tracker.index(),
txids_by_script_hash(&*mempool_store, script_hash), txids_by_script_hash(tracker.index(), script_hash),
) { ) {
funding.extend(self.find_funding_outputs(&t, script_hash)); funding.extend(self.find_funding_outputs(&t, script_hash));
} }
// // TODO: dedup outputs (somehow) both confirmed and in mempool (e.g. reorg?) // // TODO: dedup outputs (somehow) both confirmed and in mempool (e.g. reorg?)
for funding_output in funding.iter().chain(confirmed_status.funding.iter()) { for funding_output in funding.iter().chain(confirmed_status.funding.iter()) {
if let Some(spent) = self.find_spending_input(&*mempool_store, &funding_output) { if let Some(spent) = self.find_spending_input(tracker.index(), &funding_output) {
spending.push(spent); spending.push(spent);
} }
} }