Well, that was painful. Can't use vectors because they slice. Can't use sets

because their contents are immutable. Can't use maps because there's no type
that corresponds to the sort order. Can't use a vector of pointers because
they won't snapshot/copy correctly. No real choice but to use
boost::ptr_vector and create the necessary helper functions for it to work.
This commit is contained in:
JoelKatz
2012-07-30 23:42:57 -07:00
parent a01909fa4b
commit 6e1ffd752d
2 changed files with 29 additions and 14 deletions

View File

@@ -1,5 +1,7 @@
#include "TransactionMeta.h"
#include <algorithm>
#include <boost/make_shared.hpp>
#include <boost/bind.hpp>
@@ -115,22 +117,23 @@ TransactionMetaNode::TransactionMetaNode(const uint256& node, SerializerIterator
{
type = sit.get8();
if (type == TransactionMetaNodeEntry::TMNChangedBalance)
mEntries.insert(boost::shared_ptr<TransactionMetaNodeEntry>(new TMNEBalance(sit)));
mEntries.push_back(new TMNEBalance(sit));
if (type == TransactionMetaNodeEntry::TMNDeleteUnfunded)
mEntries.insert(boost::shared_ptr<TransactionMetaNodeEntry>(new TMNEUnfunded()));
mEntries.push_back(new TMNEUnfunded());
else if (type != TransactionMetaNodeEntry::TMNEndOfMetadata)
throw std::runtime_error("Unparseable metadata");
} while (type != TransactionMetaNodeEntry::TMNEndOfMetadata);
}
void TransactionMetaNode::addRaw(Serializer& s) const
void TransactionMetaNode::addRaw(Serializer& s)
{
s.add256(mNode);
s.add256(mPreviousTransaction);
s.add32(mPreviousLedger);
for (std::set<TransactionMetaNodeEntry::pointer>::const_iterator it = mEntries.begin(), end = mEntries.end();
mEntries.sort();
for (boost::ptr_vector<TransactionMetaNodeEntry>::const_iterator it = mEntries.begin(), end = mEntries.end();
it != end; ++it)
(*it)->addRaw(s);
it->addRaw(s);
s.add8(TransactionMetaNodeEntry::TMNEndOfMetadata);
}
@@ -150,9 +153,9 @@ Json::Value TransactionMetaNode::getJson(int v) const
ret["previous_ledger"] = mPreviousLedger;
Json::Value e = Json::arrayValue;
for (std::set<TransactionMetaNodeEntry::pointer>::const_iterator it = mEntries.begin(), end = mEntries.end();
for (boost::ptr_vector<TransactionMetaNodeEntry>::const_iterator it = mEntries.begin(), end = mEntries.end();
it != end; ++it)
e.append((*it)->getJson(v));
e.append(it->getJson(v));
ret["entries"] = e;
return ret;
@@ -174,10 +177,10 @@ TransactionMetaSet::TransactionMetaSet(uint32 ledger, const std::vector<unsigned
} while(1);
}
void TransactionMetaSet::addRaw(Serializer& s) const
void TransactionMetaSet::addRaw(Serializer& s)
{
s.add256(mTransactionID);
for (std::map<uint256, TransactionMetaNode>::const_iterator it = mNodes.begin(), end = mNodes.end();
for (std::map<uint256, TransactionMetaNode>::iterator it = mNodes.begin(), end = mNodes.end();
it != end; ++it)
it->second.addRaw(s);
s.add256(uint256());

View File

@@ -2,9 +2,9 @@
#define __TRANSACTIONMETA__
#include <vector>
#include <set>
#include <boost/shared_ptr.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include "../json/value.h"
@@ -35,6 +35,12 @@ public:
bool operator<=(const TransactionMetaNodeEntry&) const;
bool operator>(const TransactionMetaNodeEntry&) const;
bool operator>=(const TransactionMetaNodeEntry&) const;
std::auto_ptr<TransactionMetaNodeEntry> clone() const
{ return std::auto_ptr<TransactionMetaNodeEntry>(clone()); }
protected:
virtual TransactionMetaNodeEntry* clone(void) = 0;
};
class TMNEBalance : public TransactionMetaNodeEntry
@@ -67,6 +73,7 @@ public:
virtual Json::Value getJson(int) const;
virtual int compare(const TransactionMetaNodeEntry&) const;
virtual TransactionMetaNodeEntry* clone(void) { return new TMNEBalance(*this); }
};
class TMNEUnfunded : public TransactionMetaNodeEntry
@@ -80,8 +87,12 @@ public:
virtual void addRaw(Serializer&) const;
virtual Json::Value getJson(int) const;
virtual int compare(const TransactionMetaNodeEntry&) const;
virtual TransactionMetaNodeEntry* clone(void) { return new TMNEUnfunded(*this); }
};
inline TransactionMetaNodeEntry* new_clone(const TransactionMetaNodeEntry& s) { return s.clone().release(); }
inline void delete_clone(const TransactionMetaNodeEntry* s) { boost::checked_delete(s); }
class TransactionMetaNode
{ // a node that has been affected by a transaction
public:
@@ -91,7 +102,7 @@ protected:
uint256 mNode;
uint256 mPreviousTransaction;
uint32 mPreviousLedger;
std::set<TransactionMetaNodeEntry::pointer> mEntries;
boost::ptr_vector<TransactionMetaNodeEntry> mEntries;
public:
TransactionMetaNode(const uint256 &node) : mNode(node) { ; }
@@ -99,7 +110,7 @@ public:
const uint256& getNode() const { return mNode; }
const uint256& getPreviousTransaction() const { return mPreviousTransaction; }
uint32 getPreviousLedger() const { return mPreviousLedger; }
const std::set<TransactionMetaNodeEntry::pointer>& peekEntries() const { return mEntries; }
const boost::ptr_vector<TransactionMetaNodeEntry>& peekEntries() const { return mEntries; }
bool operator<(const TransactionMetaNode& n) const { return mNode < n.mNode; }
bool operator<=(const TransactionMetaNode& n) const { return mNode <= n.mNode; }
@@ -109,10 +120,11 @@ public:
void thread(const uint256& prevTx, uint32 prevLgr);
TransactionMetaNode(const uint256&node, SerializerIterator&);
void addRaw(Serializer&) const;
void addRaw(Serializer&);
Json::Value getJson(int) const;
};
class TransactionMetaSet
{
protected:
@@ -135,7 +147,7 @@ public:
const TransactionMetaNode& peekAffectedNode(const uint256&) const;
Json::Value getJson(int) const;
void addRaw(Serializer&) const;
void addRaw(Serializer&);
void threadNode(const uint256& node, const uint256& previousTransaction, uint32 previousLedger);
bool signedBy(const uint256& node, const STAmount& fee);