mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-02-02 09:54:29 +00:00
implement index of partial usernames so search-as-you-type can work as expected with listusernamespartial
This commit is contained in:
parent
f4d6c2be28
commit
fb0802449c
@ -1175,6 +1175,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
||||
CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
|
||||
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
|
||||
vPos.reserve(block.vtx.size()-1);
|
||||
std::vector<std::string> vUsernames;
|
||||
vUsernames.reserve(block.vtx.size()-1);
|
||||
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
||||
{
|
||||
const CTransaction &tx = block.vtx[i];
|
||||
@ -1184,6 +1186,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
||||
blockundo.vtxundo.push_back(txundo);
|
||||
uint256 txid = SerializeHash(make_pair(tx.GetUsername(),-1));
|
||||
vPos.push_back(std::make_pair(txid, pos));
|
||||
vUsernames.push_back(tx.GetUsername());
|
||||
|
||||
CDiskTxPos oldPos;
|
||||
if( pblocktree->ReadTxIndex(txid, oldPos) && pos != oldPos ) {
|
||||
@ -1228,6 +1231,11 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
||||
if (!pblocktree->WriteTxIndex(vPos))
|
||||
return state.Abort(_("Failed to write transaction index"));
|
||||
|
||||
for (size_t i=0; i<vUsernames.size(); i++) {
|
||||
if (!pblocktree->AddNameToPartialNameTree(vUsernames.at(i)))
|
||||
return state.Abort(_("Failed to write partial name index"));
|
||||
}
|
||||
|
||||
// add this block to the view's block chain
|
||||
assert(view.SetBestBlock(pindex));
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "main.h"
|
||||
#include "init.h"
|
||||
#include "bitcoinrpc.h"
|
||||
#include "txdb.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
using namespace std;
|
||||
@ -1695,27 +1696,7 @@ Value listusernamespartial(const Array& params, bool fHelp)
|
||||
}
|
||||
}
|
||||
|
||||
// now the rest, the entire block chain
|
||||
for(CBlockIndex* pindex = pindexBest; pindex && retStrings.size() < count; pindex = pindex->pprev ) {
|
||||
CBlock block;
|
||||
if( !ReadBlockFromDisk(block, pindex) )
|
||||
continue;
|
||||
|
||||
BOOST_FOREACH(const CTransaction&tx, block.vtx) {
|
||||
if( !tx.IsSpamMessage() ) {
|
||||
string txUsername = tx.userName.ExtractSmallString();
|
||||
if( (exact_match && userStartsWith.size() != txUsername.size()) ||
|
||||
userStartsWith.size() > txUsername.size() ) {
|
||||
continue;
|
||||
}
|
||||
int toCompare = userStartsWith.size();
|
||||
if( memcmp( txUsername.data(), userStartsWith.data(), toCompare ) == 0 )
|
||||
retStrings.insert( txUsername );
|
||||
if( retStrings.size() >= count )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pblocktree->GetNamesFromPartial(userStartsWith, retStrings, count);
|
||||
|
||||
Array ret;
|
||||
BOOST_FOREACH(string username, retStrings) {
|
||||
|
45
src/txdb.cpp
45
src/txdb.cpp
@ -189,6 +189,51 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBlockTreeDB::WritePartialNameTree(const std::string &partialName, const std::string &nextChars) {
|
||||
return Write(std::make_pair('n', partialName), nextChars);
|
||||
}
|
||||
|
||||
|
||||
bool CBlockTreeDB::ReadPartialNameTree(const std::string &partialName, std::string &nextChars) {
|
||||
return Read(std::make_pair('n', partialName), nextChars);
|
||||
}
|
||||
|
||||
bool CBlockTreeDB::AddCharToPartialNameTree(const std::string &partialName, char ch) {
|
||||
std::string nextChars;
|
||||
if (ReadPartialNameTree(partialName, nextChars)) {
|
||||
if (nextChars.find(ch) == string::npos) {
|
||||
nextChars.push_back(ch);
|
||||
return WritePartialNameTree(partialName, nextChars);
|
||||
}
|
||||
} else {
|
||||
return WritePartialNameTree(partialName, std::string(1,ch));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBlockTreeDB::AddNameToPartialNameTree(const std::string &name) {
|
||||
std::string partial;
|
||||
for (size_t i=0; i<name.size()-1; i++) {
|
||||
partial.push_back(name.at(i));
|
||||
if (!AddCharToPartialNameTree( partial, name.at(i+1) ))
|
||||
return false;
|
||||
}
|
||||
return AddCharToPartialNameTree( name, '.' ); // mark end of name
|
||||
}
|
||||
|
||||
void CBlockTreeDB::GetNamesFromPartial(const std::string &partial, std::set< std::string > &names, size_t count) {
|
||||
std::string nextChars;
|
||||
if (ReadPartialNameTree(partial, nextChars)) {
|
||||
for(size_t i=0; i<nextChars.size() && names.size()<count; i++) {
|
||||
if (nextChars.at(i) == '.') {
|
||||
names.insert(partial);
|
||||
} else {
|
||||
GetNamesFromPartial(partial+nextChars.substr(i,1), names, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CBlockTreeDB::LoadBlockIndexGuts()
|
||||
{
|
||||
leveldb::Iterator *pcursor = NewIterator();
|
||||
|
@ -51,6 +51,11 @@ public:
|
||||
bool WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> > &list);
|
||||
bool WriteFlag(const std::string &name, bool fValue);
|
||||
bool ReadFlag(const std::string &name, bool &fValue);
|
||||
bool WritePartialNameTree(const std::string &partialName, const std::string &nextChars);
|
||||
bool ReadPartialNameTree(const std::string &partialName, std::string &nextChars);
|
||||
bool AddCharToPartialNameTree(const std::string &partialName, char ch);
|
||||
bool AddNameToPartialNameTree(const std::string &name);
|
||||
void GetNamesFromPartial(const std::string &partial, std::set< std::string > &names, size_t count);
|
||||
bool LoadBlockIndexGuts();
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user