From 6e1ffd752da930dc8cd7b9c1a770b002bd89479c Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 30 Jul 2012 23:42:57 -0700 Subject: [PATCH] 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. --- src/TransactionMeta.cpp | 21 ++++++++++++--------- src/TransactionMeta.h | 22 +++++++++++++++++----- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp index 669b678dea..6594dc0392 100644 --- a/src/TransactionMeta.cpp +++ b/src/TransactionMeta.cpp @@ -1,5 +1,7 @@ #include "TransactionMeta.h" +#include + #include #include @@ -115,22 +117,23 @@ TransactionMetaNode::TransactionMetaNode(const uint256& node, SerializerIterator { type = sit.get8(); if (type == TransactionMetaNodeEntry::TMNChangedBalance) - mEntries.insert(boost::shared_ptr(new TMNEBalance(sit))); + mEntries.push_back(new TMNEBalance(sit)); if (type == TransactionMetaNodeEntry::TMNDeleteUnfunded) - mEntries.insert(boost::shared_ptr(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::const_iterator it = mEntries.begin(), end = mEntries.end(); + mEntries.sort(); + for (boost::ptr_vector::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::const_iterator it = mEntries.begin(), end = mEntries.end(); + for (boost::ptr_vector::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::const_iterator it = mNodes.begin(), end = mNodes.end(); + for (std::map::iterator it = mNodes.begin(), end = mNodes.end(); it != end; ++it) it->second.addRaw(s); s.add256(uint256()); diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index 5d680838f3..cc1bd50659 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -2,9 +2,9 @@ #define __TRANSACTIONMETA__ #include -#include #include +#include #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 clone() const + { return std::auto_ptr(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 mEntries; + boost::ptr_vector 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& peekEntries() const { return mEntries; } + const boost::ptr_vector& 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);