Cosmetic changes for path finding.

This commit is contained in:
Arthur Britto
2012-11-20 18:52:42 -08:00
parent 50cdc0c49f
commit 9755563e18
3 changed files with 160 additions and 126 deletions

View File

@@ -36,27 +36,24 @@ Test XRP to USD
Test USD to EUR
*/
// we sort the options by:
// cost of path
// length of path
// width of path
// correct currency at the end
bool sortPathOptions(PathOption::pointer first, PathOption::pointer second)
{
if(first->mTotalCost<second->mTotalCost) return(true);
if(first->mTotalCost>second->mTotalCost) return(false);
if (first->mTotalCost<second->mTotalCost) return(true);
if (first->mTotalCost>second->mTotalCost) return(false);
if(first->mCorrectCurrency && !second->mCorrectCurrency) return(true);
if(!first->mCorrectCurrency && second->mCorrectCurrency) return(false);
if (first->mCorrectCurrency && !second->mCorrectCurrency) return(true);
if (!first->mCorrectCurrency && second->mCorrectCurrency) return(false);
if(first->mPath.getElementCount()<second->mPath.getElementCount()) return(true);
if(first->mPath.getElementCount()>second->mPath.getElementCount()) return(false);
if (first->mPath.getElementCount()<second->mPath.getElementCount()) return(true);
if (first->mPath.getElementCount()>second->mPath.getElementCount()) return(false);
if(first->mMinWidth<second->mMinWidth) return true;
if (first->mMinWidth<second->mMinWidth) return true;
return false;
}
@@ -76,98 +73,115 @@ PathOption::PathOption(PathOption::pointer other)
}
Pathfinder::Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount) :
Pathfinder::Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount) :
mSrcAccountID(srcAccountID.getAccountID()), mDstAccountID(dstAccountID.getAccountID()), mDstAmount(dstAmount), mSrcCurrencyID(srcCurrencyID), mOrderBook(theApp->getMasterLedger().getCurrentLedger())
{
mLedger=theApp->getMasterLedger().getCurrentLedger();
}
// Returns a single path, if possible.
// --> maxSearchSteps: unused
// --> maxPay: unused
bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet)
{
if(mLedger) {
std::queue<STPath> pqueue;
STPathElement ele(mSrcAccountID,
mSrcCurrencyID,
uint160());
STPath path;
path.addElement(ele);
pqueue.push(path);
while(pqueue.size()) {
if (mLedger) {
std::queue<STPath> pqueue;
STPathElement ele(mSrcAccountID,
mSrcCurrencyID,
uint160());
STPath path;
STPath path = pqueue.front();
pqueue.pop();
// get the first path from the queue
path.addElement(ele); // Add the source.
ele = path.mPath.back();
// get the last node from the path
pqueue.push(path);
if (ele.mAccountID == mDstAccountID) {
path.mPath.erase(path.mPath.begin());
path.mPath.erase(path.mPath.begin() + path.mPath.size()-1);
if (path.mPath.size() == 0) {
continue;
}
retPathSet.addPath(path);
return true;
}
// found the destination
while (pqueue.size()) {
STPath path = pqueue.front();
if (!ele.mCurrencyID) {
BOOST_FOREACH(OrderBook::pointer book,mOrderBook.getXRPInBooks())
{
//if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
{
pqueue.pop(); // Pop the first path from the queue.
STPath new_path(path);
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
new_path.mPath.push_back(new_ele);
new_path.mCurrencyID = book->getCurrencyOut();
new_path.mCurrentAccount = book->getCurrencyOut();
ele = path.mPath.back(); // Get the last node from the path.
pqueue.push(new_path);
// Determine if path is solved.
if (ele.mAccountID == mDstAccountID) {
// Found a path to the destination.
}
}
if (2 == path.mPath.size()) {
// Empty path is default. Drop it.
continue;
}
} else {
RippleLines rippleLines(ele.mAccountID);
BOOST_FOREACH(RippleState::pointer line,rippleLines.getLines())
{
if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
{
STPath new_path(path);
STPathElement new_ele(line->getAccountIDPeer().getAccountID(),
ele.mCurrencyID,
uint160());
new_path.mPath.push_back(new_ele);
pqueue.push(new_path);
}
} // BOOST_FOREACHE
// Remove implied first and last nodes.
path.mPath.erase(path.mPath.begin());
path.mPath.erase(path.mPath.begin() + path.mPath.size()-1);
// every offer that wants the source currency
std::vector<OrderBook::pointer> books;
mOrderBook.getBooks(path.mCurrentAccount, path.mCurrencyID, books);
// Return the path.
retPathSet.addPath(path);
BOOST_FOREACH(OrderBook::pointer book,books)
{
STPath new_path(path);
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
return true;
}
new_path.mPath.push_back(new_ele);
new_path.mCurrentAccount=book->getIssuerOut();
new_path.mCurrencyID=book->getCurrencyOut();
if (!ele.mCurrencyID) {
// Last element is for XRP continue with qualifying books.
pqueue.push(new_path);
BOOST_FOREACH(OrderBook::pointer book, mOrderBook.getXRPInBooks())
{
//if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
{
STPath new_path(path);
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
}
new_path.mPath.push_back(new_ele);
new_path.mCurrencyID = book->getCurrencyOut();
new_path.mCurrentAccount = book->getCurrencyOut();
} // else
// enumerate all adjacent nodes, construct a new path and push it into the queue
} // While
} // if there is a ledger
pqueue.push(new_path);
}
}
return false;
} else {
// Last element is for non-XRP continue by adding ripple lines and order books.
// Create new paths for each outbound account not already in the path.
RippleLines rippleLines(ele.mAccountID);
BOOST_FOREACH(RippleState::pointer line, rippleLines.getLines())
{
if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
{
STPath new_path(path);
STPathElement new_ele(line->getAccountIDPeer().getAccountID(),
ele.mCurrencyID,
uint160());
new_path.mPath.push_back(new_ele);
pqueue.push(new_path);
}
}
// Every book that wants the source currency.
std::vector<OrderBook::pointer> books;
mOrderBook.getBooks(path.mCurrentAccount, path.mCurrencyID, books);
BOOST_FOREACH(OrderBook::pointer book,books)
{
STPath new_path(path);
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
new_path.mPath.push_back(new_ele);
new_path.mCurrentAccount=book->getIssuerOut();
new_path.mCurrencyID=book->getCurrencyOut();
pqueue.push(new_path);
}
}
// enumerate all adjacent nodes, construct a new path and push it into the queue
} // While
} // if there is a ledger
return false;
}
bool Pathfinder::checkComplete(STPathSet& retPathSet)
@@ -196,9 +210,9 @@ bool Pathfinder::checkComplete(STPathSet& retPathSet)
void Pathfinder::addOptions(PathOption::pointer tail)
{
if(!tail->mCurrencyID)
if (!tail->mCurrencyID)
{ // source XRP
BOOST_FOREACH(OrderBook::pointer book,mOrderBook.getXRPInBooks())
BOOST_FOREACH(OrderBook::pointer book, mOrderBook.getXRPInBooks())
{
PathOption::pointer pathOption(new PathOption(tail));
@@ -209,13 +223,14 @@ void Pathfinder::addOptions(PathOption::pointer tail)
pathOption->mCurrencyID=book->getCurrencyOut();
addPathOption(pathOption);
}
}else
}
else
{ // ripple
RippleLines rippleLines(tail->mCurrentAccount);
BOOST_FOREACH(RippleState::pointer line,rippleLines.getLines())
{
// TODO: make sure we can move in the correct direction
STAmount balance=line->getBalance();
STAmount balance=line->getBalance();
if(balance.getCurrency()==tail->mCurrencyID)
{ // we have a ripple line from the tail to somewhere else
PathOption::pointer pathOption(new PathOption(tail));