work on ldb iteration.
This commit is contained in:
parent
d7641c173c
commit
4341e487c0
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue