work on ldb iteration.

This commit is contained in:
Christopher Jeffrey 2014-11-19 12:26:57 -08:00
parent d7641c173c
commit 4341e487c0
1 changed files with 207 additions and 115 deletions

View File

@ -231,7 +231,10 @@ using namespace v8;
// Need this because account names can be an empty string. // Need this because account names can be an empty string.
#define EMPTY ("\\x01") #define EMPTY ("\\x01")
#define USE_LEVELDB_ADDR #define USE_LDB_ADDR
#define USE_LDB_FILES
#define USE_LDB_BLOCK
/** /**
* Node.js Exposed Function Templates * Node.js Exposed Function Templates
@ -604,7 +607,7 @@ struct async_rescan_data {
* Read Raw DB * Read Raw DB
*/ */
#ifdef USE_LEVELDB_ADDR #ifdef USE_LDB_ADDR
static ctx_list * static ctx_list *
read_addr(const std::string addr); read_addr(const std::string addr);
#endif #endif
@ -2033,7 +2036,7 @@ async_get_addrtx(uv_work_t *req) {
return; return;
} }
#ifndef USE_LEVELDB_ADDR #ifndef USE_LDB_ADDR
CScript expected = GetScriptForDestination(address.Get()); CScript expected = GetScriptForDestination(address.Get());
int64_t i = 0; int64_t i = 0;
@ -5875,7 +5878,7 @@ jstx_to_ctx(const Local<Object> jstx, CTransaction& ctx_) {
ctx.nLockTime = (unsigned int)jstx->Get(NanNew<String>("locktime"))->Uint32Value(); ctx.nLockTime = (unsigned int)jstx->Get(NanNew<String>("locktime"))->Uint32Value();
} }
#ifdef USE_LEVELDB_ADDR #ifdef USE_LDB_ADDR
static leveldb::Options static leveldb::Options
GetOptions(size_t nCacheSize) { GetOptions(size_t nCacheSize) {
leveldb::Options options; leveldb::Options options;
@ -5894,28 +5897,24 @@ GetOptions(size_t nCacheSize) {
// http://leveldb.googlecode.com/svn/tags/1.17/doc/index.html // http://leveldb.googlecode.com/svn/tags/1.17/doc/index.html
#if 0
class TwoPartComparator : public leveldb::Comparator { class TwoPartComparator : public leveldb::Comparator {
public: public:
// Three-way comparison function:
// if a < end: negative result
// if a > end: positive result
// else: zero result
int Compare(const leveldb::Slice& key, const leveldb::Slice& end) const { int Compare(const leveldb::Slice& key, const leveldb::Slice& end) const {
return -1; std::string key_ = key.ToString();
//std::string key_ = key.ToString(); const char *k = key_.c_str();
#ifdef USE_LDB_BLOCK
//const char *k = key_.c_str(); if (k[0] == 'b') return -1;
#else
//if (k[0] == 't') return -1; if (k[0] == 't') return -1;
#endif
//return 1; return 1;
} }
// Ignore the following methods for now:
const char* Name() const { return "TwoPartComparator"; } const char* Name() const { return "TwoPartComparator"; }
void FindShortestSeparator(std::string*, const leveldb::Slice&) const { } void FindShortestSeparator(std::string*, const leveldb::Slice&) const { }
void FindShortSuccessor(std::string*) const { } void FindShortSuccessor(std::string*) const { }
}; };
#endif
static ctx_list * static ctx_list *
read_addr(const std::string addr) { read_addr(const std::string addr) {
@ -5954,84 +5953,12 @@ read_addr(const std::string addr) {
options = GetOptions(nCacheSize); options = GetOptions(nCacheSize);
options.create_if_missing = true; options.create_if_missing = true;
#if 0
TwoPartComparator cmp; TwoPartComparator cmp;
options.comparator = &cmp; options.comparator = &cmp;
#endif
CScript expectedScriptSig = GetScriptForDestination(CBitcoinAddress(addr).Get());
const boost::filesystem::path path = GetDataDir() / "blocks" / "index";
if (fMemory) {
penv = leveldb::NewMemEnv(leveldb::Env::Default());
options.env = penv;
}
leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
if (!status.ok()) {
return head;
}
leveldb::Iterator* it = pdb->NewIterator(options);
for (it->SeekToFirst(); it->Valid(); it->Next()) {
std::string strValue = it->value().ToString();
CTransaction ctx;
if (it->key().ToString().c_str()[0] != 't') {
continue;
}
try {
CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
ssValue >> ctx;
} catch (const std::exception&) {
// return NULL;
continue;
}
for (unsigned int vo = 0; vo < ctx.vout.size(); vo++) {
const CTxOut& txout = ctx.vout[vo];
const CScript& scriptPubKey = txout.scriptPubKey;
int nRequired;
txnouttype type;
vector<CTxDestination> addresses;
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
continue;
}
BOOST_FOREACH(const CTxDestination& address, addresses) {
if (CBitcoinAddress(address).ToString() != addr) {
continue;
}
if (cur == NULL) {
head->ctx = ctx;
uint256 hash(((CMerkleTx)ctx).hashBlock.GetHex());
head->blockhash = hash;
head->next = NULL;
cur = head;
} else {
ctx_list *item = new ctx_list();
item->ctx = ctx;
uint256 hash(((CMerkleTx)ctx).hashBlock.GetHex());
item->blockhash = hash;
item->next = NULL;
cur->next = item;
cur = item;
}
goto found;
}
}
found:
continue;
}
assert(it->status().ok());
delete it;
#if 0
#ifdef USE_LDB_FILES #ifdef USE_LDB_FILES
unsigned int nFile = 0; unsigned int nFile = 0;
@ -6039,9 +5966,10 @@ found:
for (; nFile < tryFiles; nFile++) { for (; nFile < tryFiles; nFile++) {
const boost::filesystem::path path = GetDataDir() / "blocks" / strprintf("%s%05u.dat", "blk", nFile); const boost::filesystem::path path = GetDataDir() / "blocks" / strprintf("%s%05u.dat", "blk", nFile);
#else #else
{ do {
const boost::filesystem::path path = GetDataDir() / "blocks" / "index"; const boost::filesystem::path path = GetDataDir() / "blocks" / "index";
#endif #endif
if (fMemory) { if (fMemory) {
penv = leveldb::NewMemEnv(leveldb::Env::Default()); penv = leveldb::NewMemEnv(leveldb::Env::Default());
options.env = penv; options.env = penv;
@ -6050,33 +5978,62 @@ found:
leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb); leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
if (!status.ok()) { if (!status.ok()) {
return head; break;
} }
leveldb::Slice start = "t"; //leveldb::Iterator* it = pdb->NewIterator(leveldb::ReadOptions());
leveldb::Slice end = "t\xFF"; leveldb::Iterator* it = pdb->NewIterator(iteroptions);
//leveldb::Options options; for (it->SeekToFirst(); it->Valid(); it->Next()) {
#ifdef USE_LDB_BLOCK
// if (it->key().ToString().c_str()[0] != 'b') continue;
CBlock cblock;
#else
// if (it->key().ToString().c_str()[0] != 't') continue;
CTransaction ctx;
#endif
leveldb::Iterator* it = pdb->NewIterator(leveldb::ReadOptions()); std::string strValue = it->value().ToString();
for (it->Seek(start); it->Valid(); it->Next()) { try {
leveldb::Slice key = it->key(); CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
leveldb::Slice value = it->value(); #ifdef USE_LDB_BLOCK
ssValue >> cblock;
#else
ssValue >> ctx;
#endif
} catch (const std::exception&) {
// delete it;
// return NULL;
continue;
}
if (options.comparator->Compare(key, end) > 0) { #ifdef USE_LDB_BLOCK
break; BOOST_FOREACH(const CTransaction& ctx, cblock.vtx) {
} else { #endif
std::string strValue = value.ToString(); // vin
CTransaction ctx; BOOST_FOREACH(const CTxIn& txin, ctx.vin) {
if (txin.scriptSig.ToString() != expectedScriptSig.ToString()) {
try { continue;
CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); }
ssValue >> ctx; if (cur == NULL) {
} catch (const std::exception&) { head->ctx = ctx;
// return NULL; uint256 hash(((CMerkleTx)ctx).hashBlock.GetHex());
continue; head->blockhash = hash;
head->next = NULL;
cur = head;
} else {
ctx_list *item = new ctx_list();
item->ctx = ctx;
uint256 hash(((CMerkleTx)ctx).hashBlock.GetHex());
item->blockhash = hash;
item->next = NULL;
cur->next = item;
cur = item;
}
goto found;
} }
// vout
for (unsigned int vo = 0; vo < ctx.vout.size(); vo++) { for (unsigned int vo = 0; vo < ctx.vout.size(); vo++) {
const CTxOut& txout = ctx.vout[vo]; const CTxOut& txout = ctx.vout[vo];
const CScript& scriptPubKey = txout.scriptPubKey; const CScript& scriptPubKey = txout.scriptPubKey;
@ -6108,6 +6065,141 @@ found:
goto found; goto found;
} }
} }
#ifdef USE_LDB_BLOCK
}
#endif
found:
continue;
}
assert(it->status().ok());
delete it;
#ifdef USE_LDB_FILES
}
#else
} while (0);
#endif
#if 0
#ifdef USE_LDB_FILES
unsigned int nFile = 0;
unsigned int tryFiles = 0xffffffff;
for (; nFile < tryFiles; nFile++) {
const boost::filesystem::path path = GetDataDir() / "blocks" / strprintf("%s%05u.dat", "blk", nFile);
#else
do {
const boost::filesystem::path path = GetDataDir() / "blocks" / "index";
#endif
if (fMemory) {
penv = leveldb::NewMemEnv(leveldb::Env::Default());
options.env = penv;
}
leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
if (!status.ok()) {
break;
}
leveldb::Slice start = "t";
leveldb::Slice end = "t\xFF";
//leveldb::Options options;
leveldb::Iterator* it = pdb->NewIterator(leveldb::ReadOptions());
for (it->Seek(start); it->Valid(); it->Next()) {
leveldb::Slice key = it->key();
leveldb::Slice value = it->value();
if (options.comparator->Compare(key, end) > 0) {
break;
} else {
#ifdef USE_LDB_BLOCK
CBlock cblock;
#else
CTransaction ctx;
#endif
std::string strValue = value.ToString();
try {
CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
#ifdef USE_LDB_BLOCK
ssValue >> cblock;
#else
ssValue >> ctx;
#endif
} catch (const std::exception&) {
// delete it;
// return NULL;
continue;
}
#ifdef USE_LDB_BLOCK
BOOST_FOREACH(const CTransaction& ctx, cblock.vtx) {
#endif
// vin
BOOST_FOREACH(const CTxIn& txin, ctx.vin) {
if (txin.scriptSig.ToString() != expectedScriptSig.ToString()) {
continue;
}
if (cur == NULL) {
head->ctx = ctx;
uint256 hash(((CMerkleTx)ctx).hashBlock.GetHex());
head->blockhash = hash;
head->next = NULL;
cur = head;
} else {
ctx_list *item = new ctx_list();
item->ctx = ctx;
uint256 hash(((CMerkleTx)ctx).hashBlock.GetHex());
item->blockhash = hash;
item->next = NULL;
cur->next = item;
cur = item;
}
goto found;
}
// vout
for (unsigned int vo = 0; vo < ctx.vout.size(); vo++) {
const CTxOut& txout = ctx.vout[vo];
const CScript& scriptPubKey = txout.scriptPubKey;
int nRequired;
txnouttype type;
vector<CTxDestination> addresses;
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
continue;
}
BOOST_FOREACH(const CTxDestination& address, addresses) {
if (CBitcoinAddress(address).ToString() != addr) {
continue;
}
if (cur == NULL) {
head->ctx = ctx;
uint256 hash(((CMerkleTx)ctx).hashBlock.GetHex());
head->blockhash = hash;
head->next = NULL;
cur = head;
} else {
ctx_list *item = new ctx_list();
item->ctx = ctx;
uint256 hash(((CMerkleTx)ctx).hashBlock.GetHex());
item->blockhash = hash;
item->next = NULL;
cur->next = item;
cur = item;
}
goto found;
}
}
#ifdef USE_LDB_BLOCK
}
#endif
found: found:
continue; continue;
@ -6118,7 +6210,7 @@ found:
#ifdef USE_LDB_FILES #ifdef USE_LDB_FILES
} }
#else #else
} } while (0);
#endif #endif
#endif #endif