mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-25 13:35:54 +00:00
Large speed up of getField* functions on non-free objects such as transactions and ledger nodes.
This commit is contained in:
@@ -96,6 +96,7 @@ public:
|
||||
bool isKnown() const { return fieldType != STI_UNKNOWN; }
|
||||
bool isBinary() const { return fieldValue < 256; }
|
||||
bool isDiscardable() const { return fieldValue > 256; }
|
||||
int getCode() const { return fieldCode; }
|
||||
|
||||
bool isSigningField() const { return signingField; }
|
||||
void notSigningField() { signingField = false; }
|
||||
|
||||
@@ -11,7 +11,7 @@ std::map<std::string, LedgerEntryFormat*> LedgerEntryFormat::byName;
|
||||
|
||||
#define DECLARE_LEF(name, type) lef = new LedgerEntryFormat(#name, type); (*lef) LEF_BASE
|
||||
|
||||
static bool LEFInit()
|
||||
void LEFInit()
|
||||
{
|
||||
LedgerEntryFormat* lef;
|
||||
|
||||
@@ -111,12 +111,8 @@ static bool LEFInit()
|
||||
<< SOElement(sfReserveBase, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveIncrement, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LEFInitComplete = LEFInit();
|
||||
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat(LedgerEntryType t)
|
||||
{
|
||||
std::map<int, LedgerEntryFormat*>::iterator it = byType.find(static_cast<int>(t));
|
||||
|
||||
@@ -58,7 +58,7 @@ class LedgerEntryFormat
|
||||
public:
|
||||
std::string t_name;
|
||||
LedgerEntryType t_type;
|
||||
std::vector<SOElement::ref> elements;
|
||||
SOTemplate elements;
|
||||
|
||||
static std::map<int, LedgerEntryFormat*> byType;
|
||||
static std::map<std::string, LedgerEntryFormat*> byName;
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
}
|
||||
LedgerEntryFormat& operator<<(const SOElement& el)
|
||||
{
|
||||
elements.push_back(new SOElement(el));
|
||||
elements.push_back(el);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,14 +130,26 @@ std::auto_ptr<SerializedType> STObject::makeDeserializedObject(SerializedTypeID
|
||||
}
|
||||
}
|
||||
|
||||
void STObject::set(const std::vector<SOElement::ref>& type)
|
||||
void SOTemplate::push_back(const SOElement &r)
|
||||
{
|
||||
assert(mMap.find(r.e_field.getCode()) == mMap.end());
|
||||
mMap[r.e_field.getCode()] = mTypes.size();
|
||||
mTypes.push_back(new SOElement(r));
|
||||
}
|
||||
|
||||
int SOTemplate::getIndex(SField::ref f) const
|
||||
{
|
||||
std::map<int, int>::const_iterator it = mMap.find(f.getCode());
|
||||
return (it == mMap.end()) ? -1 : it->second;
|
||||
}
|
||||
|
||||
void STObject::set(const SOTemplate& type)
|
||||
{
|
||||
mData.clear();
|
||||
mType.clear();
|
||||
mType = &type;
|
||||
|
||||
BOOST_FOREACH(SOElement::ref elem, type)
|
||||
BOOST_FOREACH(const SOElement* elem, type.peek())
|
||||
{
|
||||
mType.push_back(elem);
|
||||
if (elem->flags != SOE_REQUIRED)
|
||||
giveObject(makeNonPresentObject(elem->e_field));
|
||||
else
|
||||
@@ -145,15 +157,14 @@ void STObject::set(const std::vector<SOElement::ref>& type)
|
||||
}
|
||||
}
|
||||
|
||||
bool STObject::setType(const std::vector<SOElement::ref> &type)
|
||||
bool STObject::setType(const SOTemplate &type)
|
||||
{
|
||||
boost::ptr_vector<SerializedType> newData(type.size());
|
||||
boost::ptr_vector<SerializedType> newData(type.peek().size());
|
||||
bool valid = true;
|
||||
|
||||
mType.clear();
|
||||
mType.reserve(type.size());
|
||||
mType = &type;
|
||||
|
||||
BOOST_FOREACH(SOElement::ref elem, type)
|
||||
BOOST_FOREACH(const SOElement* elem, type.peek())
|
||||
{
|
||||
bool match = false;
|
||||
for (boost::ptr_vector<SerializedType>::iterator it = mData.begin(); it != mData.end(); ++it)
|
||||
@@ -180,8 +191,6 @@ bool STObject::setType(const std::vector<SOElement::ref> &type)
|
||||
}
|
||||
newData.push_back(makeNonPresentObject(elem->e_field));
|
||||
}
|
||||
|
||||
mType.push_back(elem);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const SerializedType& t, mData)
|
||||
@@ -201,7 +210,7 @@ bool STObject::setType(const std::vector<SOElement::ref> &type)
|
||||
bool STObject::isValidForType()
|
||||
{
|
||||
boost::ptr_vector<SerializedType>::iterator it = mData.begin();
|
||||
BOOST_FOREACH(SOElement::ref elem, mType)
|
||||
BOOST_FOREACH(const SOElement* elem, mType->peek())
|
||||
{
|
||||
if (it == mData.end())
|
||||
return false;
|
||||
@@ -215,14 +224,9 @@ bool STObject::isValidForType()
|
||||
|
||||
bool STObject::isFieldAllowed(SField::ref field)
|
||||
{
|
||||
if (isFree())
|
||||
if (mType == NULL)
|
||||
return true;
|
||||
BOOST_FOREACH(SOElement::ref elem, mType)
|
||||
{ // are any required elemnents missing
|
||||
if (elem->e_field == field)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return mType->getIndex(field) != -1;
|
||||
}
|
||||
|
||||
bool STObject::set(SerializerIterator& sit, int depth)
|
||||
@@ -361,6 +365,9 @@ uint256 STObject::getSigningHash(uint32 prefix) const
|
||||
|
||||
int STObject::getFieldIndex(SField::ref field) const
|
||||
{
|
||||
if (mType != NULL)
|
||||
return mType->getIndex(field);
|
||||
|
||||
int i = 0;
|
||||
BOOST_FOREACH(const SerializedType& elem, mData)
|
||||
{
|
||||
@@ -1243,11 +1250,11 @@ BOOST_AUTO_TEST_CASE( FieldManipulation_test )
|
||||
SField sfTestU32(STI_UINT32, 255, "TestU32");
|
||||
SField sfTestObject(STI_OBJECT, 255, "TestObject");
|
||||
|
||||
std::vector<SOElement::ref> elements;
|
||||
elements.push_back(new SOElement(sfFlags, SOE_REQUIRED));
|
||||
elements.push_back(new SOElement(sfTestVL, SOE_REQUIRED));
|
||||
elements.push_back(new SOElement(sfTestH256, SOE_OPTIONAL));
|
||||
elements.push_back(new SOElement(sfTestU32, SOE_REQUIRED));
|
||||
SOTemplate elements;
|
||||
elements.push_back(SOElement(sfFlags, SOE_REQUIRED));
|
||||
elements.push_back(SOElement(sfTestVL, SOE_REQUIRED));
|
||||
elements.push_back(SOElement(sfTestH256, SOE_OPTIONAL));
|
||||
elements.push_back(SOElement(sfTestU32, SOE_REQUIRED));
|
||||
|
||||
STObject object1(elements, sfTestObject);
|
||||
STObject object2(object1);
|
||||
|
||||
@@ -18,32 +18,44 @@ DEFINE_INSTANCE(SerializedArray);
|
||||
class SOElement
|
||||
{ // An element in the description of a serialized object
|
||||
public:
|
||||
typedef SOElement const * ref; // used to point to one element
|
||||
SField::ref e_field;
|
||||
const SOE_Flags flags;
|
||||
|
||||
SField::ref e_field;
|
||||
const SOE_Flags flags;
|
||||
SOElement(SField::ref fi, SOE_Flags fl) : e_field(fi), flags(fl) { ; }
|
||||
};
|
||||
|
||||
SOElement(SField::ref fi, SOE_Flags fl) : e_field(fi), flags(fl) { ; }
|
||||
class SOTemplate
|
||||
{
|
||||
protected:
|
||||
std::vector<const SOElement*> mTypes;
|
||||
std::map<int, int> mMap; // field code -> index
|
||||
|
||||
public:
|
||||
SOTemplate() { ; }
|
||||
const std::vector<const SOElement*>& peek() const { return mTypes; }
|
||||
void push_back(const SOElement& r);
|
||||
int getIndex(SField::ref) const;
|
||||
};
|
||||
|
||||
class STObject : public SerializedType, private IS_INSTANCE(SerializedObject)
|
||||
{
|
||||
protected:
|
||||
boost::ptr_vector<SerializedType> mData;
|
||||
std::vector<SOElement::ref> mType;
|
||||
const SOTemplate* mType;
|
||||
|
||||
STObject* duplicate() const { return new STObject(*this); }
|
||||
STObject(SField::ref name, boost::ptr_vector<SerializedType>& data) : SerializedType(name) { mData.swap(data); }
|
||||
STObject(SField::ref name, boost::ptr_vector<SerializedType>& data) : SerializedType(name), mType(NULL)
|
||||
{ mData.swap(data); }
|
||||
|
||||
public:
|
||||
STObject() { ; }
|
||||
STObject() : mType(NULL) { ; }
|
||||
|
||||
STObject(SField::ref name) : SerializedType(name) { ; }
|
||||
STObject(SField::ref name) : SerializedType(name), mType(NULL) { ; }
|
||||
|
||||
STObject(const std::vector<SOElement::ref>& type, SField::ref name) : SerializedType(name)
|
||||
STObject(const SOTemplate& type, SField::ref name) : SerializedType(name)
|
||||
{ set(type); }
|
||||
|
||||
STObject(const std::vector<SOElement::ref>& type, SerializerIterator& sit, SField::ref name) : SerializedType(name)
|
||||
STObject(const SOTemplate& type, SerializerIterator& sit, SField::ref name) : SerializedType(name)
|
||||
{ set(sit); setType(type); }
|
||||
|
||||
std::auto_ptr<STObject> oClone() const { return std::auto_ptr<STObject>(new STObject(*this)); }
|
||||
@@ -54,12 +66,12 @@ public:
|
||||
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name);
|
||||
|
||||
bool setType(const std::vector<SOElement::ref>& type);
|
||||
bool setType(const SOTemplate& type);
|
||||
bool isValidForType();
|
||||
bool isFieldAllowed(SField::ref);
|
||||
bool isFree() const { return mType.empty(); }
|
||||
bool isFree() const { return mType == NULL; }
|
||||
|
||||
void set(const std::vector<SOElement::ref>&);
|
||||
void set(const SOTemplate&);
|
||||
bool set(SerializerIterator& u, int depth = 0);
|
||||
|
||||
virtual SerializedTypeID getSType() const { return STI_OBJECT; }
|
||||
|
||||
@@ -6,25 +6,22 @@
|
||||
|
||||
DECLARE_INSTANCE(SerializedValidation);
|
||||
|
||||
std::vector<SOElement::ref> sValidationFormat;
|
||||
SOTemplate sValidationFormat;
|
||||
|
||||
static bool SVFInit()
|
||||
void SVFInit()
|
||||
{
|
||||
sValidationFormat.push_back(new SOElement(sfFlags, SOE_REQUIRED));
|
||||
sValidationFormat.push_back(new SOElement(sfLedgerHash, SOE_REQUIRED));
|
||||
sValidationFormat.push_back(new SOElement(sfLedgerSequence, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(new SOElement(sfCloseTime, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(new SOElement(sfLoadFee, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(new SOElement(sfBaseFee, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(new SOElement(sfFeatures, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(new SOElement(sfSigningTime, SOE_REQUIRED));
|
||||
sValidationFormat.push_back(new SOElement(sfSigningPubKey, SOE_REQUIRED));
|
||||
sValidationFormat.push_back(new SOElement(sfSignature, SOE_OPTIONAL));
|
||||
return true;
|
||||
sValidationFormat.push_back(SOElement(sfFlags, SOE_REQUIRED));
|
||||
sValidationFormat.push_back(SOElement(sfLedgerHash, SOE_REQUIRED));
|
||||
sValidationFormat.push_back(SOElement(sfLedgerSequence, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(SOElement(sfCloseTime, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(SOElement(sfLoadFee, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(SOElement(sfBaseFee, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(SOElement(sfFeatures, SOE_OPTIONAL));
|
||||
sValidationFormat.push_back(SOElement(sfSigningTime, SOE_REQUIRED));
|
||||
sValidationFormat.push_back(SOElement(sfSigningPubKey, SOE_REQUIRED));
|
||||
sValidationFormat.push_back(SOElement(sfSignature, SOE_OPTIONAL));
|
||||
};
|
||||
|
||||
bool SVFinitComplete = SVFInit();
|
||||
|
||||
const uint32 SerializedValidation::sFullFlag = 0x1;
|
||||
|
||||
SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSignature)
|
||||
|
||||
@@ -16,7 +16,7 @@ std::map<std::string, TransactionFormat*> TransactionFormat::byName;
|
||||
|
||||
#define DECLARE_TF(name, type) tf = new TransactionFormat(#name, type); (*tf) TF_BASE
|
||||
|
||||
static bool TFInit()
|
||||
void TFInit()
|
||||
{
|
||||
TransactionFormat* tf;
|
||||
|
||||
@@ -84,12 +84,8 @@ static bool TFInit()
|
||||
<< SOElement(sfReserveBase, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveIncrement, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TFInitComplete = TFInit();
|
||||
|
||||
TransactionFormat* TransactionFormat::getTxnFormat(TransactionType t)
|
||||
{
|
||||
std::map<int, TransactionFormat*>::iterator it = byType.find(static_cast<int>(t));
|
||||
|
||||
@@ -31,7 +31,7 @@ class TransactionFormat
|
||||
public:
|
||||
std::string t_name;
|
||||
TransactionType t_type;
|
||||
std::vector<SOElement::ref> elements;
|
||||
SOTemplate elements;
|
||||
|
||||
static std::map<int, TransactionFormat*> byType;
|
||||
static std::map<std::string, TransactionFormat*> byName;
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
}
|
||||
TransactionFormat& operator<<(const SOElement& el)
|
||||
{
|
||||
elements.push_back(new SOElement(el));
|
||||
elements.push_back(el);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
namespace po = boost::program_options;
|
||||
|
||||
extern bool AddSystemEntropy();
|
||||
extern void TFInit();
|
||||
extern void LEFInit();
|
||||
extern void SVFInit();
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::unit_test;
|
||||
|
||||
@@ -188,6 +192,10 @@ int main(int argc, char* argv[])
|
||||
|
||||
InstanceType::multiThread();
|
||||
|
||||
TFInit();
|
||||
LEFInit();
|
||||
SVFInit();
|
||||
|
||||
if (vm.count("unittest"))
|
||||
{
|
||||
unit_test_main(init_unit_test, argc, argv);
|
||||
|
||||
Reference in New Issue
Block a user