changeset 3277:8fe9e4fc1152 draft

Optimize JSON-RPC getblockhash - If the height is in the first half, start at the genesis block and go up, rather than at the top - Cache the last lookup and use it as a reference point if it's close to the next request, to make linear lookups always fast
author Luke Dashjr <luke-jr+git@utopios.org>
date Thu, 19 Jul 2012 20:06:20 +0000
parents e9e7e33d391f
children 1e0555e98f55
files src/bitcoinrpc.cpp src/main.cpp src/main.h
diffstat 3 files changed, 21 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -2023,10 +2023,7 @@
     if (nHeight < 0 || nHeight > nBestHeight)
         throw runtime_error("Block number out of range.");
 
-    CBlock block;
-    CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
-    while (pblockindex->nHeight > nHeight)
-        pblockindex = pblockindex->pprev;
+    CBlockIndex* pblockindex = FindBlockByHeight(nHeight);
     return pblockindex->phashBlock->GetHex();
 }
 
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -802,6 +802,24 @@
 // CBlock and CBlockIndex
 //
 
+static CBlockIndex* pblockindexFBBHLast;
+CBlockIndex* FindBlockByHeight(int nHeight)
+{
+    CBlockIndex *pblockindex;
+    if (nHeight < nBestHeight / 2)
+        pblockindex = pindexGenesisBlock;
+    else
+        pblockindex = pindexBest;
+    if (pblockindexFBBHLast && abs(nHeight - pblockindex->nHeight) > abs(nHeight - pblockindexFBBHLast->nHeight))
+        pblockindex = pblockindexFBBHLast;
+    while (pblockindex->nHeight > nHeight)
+        pblockindex = pblockindex->pprev;
+    while (pblockindex->nHeight < nHeight)
+        pblockindex = pblockindex->pnext;
+    pblockindexFBBHLast = pblockindex;
+    return pblockindex;
+}
+
 bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions)
 {
     if (!fReadTransactions)
@@ -1615,6 +1633,7 @@
     // New best block
     hashBestChain = hash;
     pindexBest = pindexNew;
+    pblockindexFBBHLast = NULL;
     nBestHeight = pindexBest->nHeight;
     bnBestChainWork = pindexNew->bnChainWork;
     nTimeBestReceived = GetTime();
--- a/src/main.h
+++ b/src/main.h
@@ -88,6 +88,7 @@
 FILE* AppendBlockFile(unsigned int& nFileRet);
 bool LoadBlockIndex(bool fAllowNew=true);
 void PrintBlockTree();
+CBlockIndex* FindBlockByHeight(int nHeight);
 bool ProcessMessages(CNode* pfrom);
 bool SendMessages(CNode* pto, bool fSendTrickle);
 bool LoadExternalBlockFile(FILE* fileIn);