Feature (contd.): Variable Fields - AbstractProtocol now caches fieldFrameBitOffset unless the subclass says not to

This commit is contained in:
Srivats P. 2015-05-27 22:41:31 +05:30
parent 4f2abcb789
commit 60c47c34a1
4 changed files with 35 additions and 7 deletions

View File

@ -79,6 +79,7 @@ AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent)
_frameVariableCount = -1; _frameVariableCount = -1;
protoSize = -1; protoSize = -1;
_hasPayload = true; _hasPayload = true;
_cacheFlags |= FieldFrameBitOffsetCache;
} }
/*! /*!
@ -363,11 +364,24 @@ int AbstractProtocol::fieldFrameBitOffset(int index, int streamIndex) const
if ((index < 0) || (index >= frameFieldCount())) if ((index < 0) || (index >= frameFieldCount()))
return -1; return -1;
// TODO: we should cache the return value // Lookup Cache; if not available calculate and cache (if enabled)
for (int i = 0; i < index; i++)
ofs += fieldData(i, FieldBitSize, streamIndex).toInt();
qDebug("======> index: %d, ofs: %d", index, ofs); if (_fieldFrameBitOffset.contains(index)) {
ofs = _fieldFrameBitOffset.value(index);
goto _exit;
}
for (int i = 0; i < index; i++) {
if (_cacheFlags.testFlag(FieldFrameBitOffsetCache)
&& !_fieldFrameBitOffset.contains(i))
_fieldFrameBitOffset.insert(i, ofs);
ofs += fieldData(i, FieldBitSize, streamIndex).toInt();
}
if (_cacheFlags.testFlag(FieldFrameBitOffsetCache))
_fieldFrameBitOffset.insert(index, ofs);
_exit:
qDebug("======> ffbo index: %d, ofs: %d", index, ofs);
return ofs; return ofs;
} }

View File

@ -20,11 +20,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _ABSTRACT_PROTOCOL_H #ifndef _ABSTRACT_PROTOCOL_H
#define _ABSTRACT_PROTOCOL_H #define _ABSTRACT_PROTOCOL_H
#include <QByteArray>
#include <QFlags>
#include <QHash>
#include <QLinkedList>
#include <QString> #include <QString>
#include <QVariant> #include <QVariant>
#include <QByteArray>
#include <QLinkedList>
#include <QFlags>
#include <qendian.h> #include <qendian.h>
//#include "../rpc/pbhelper.h" //#include "../rpc/pbhelper.h"
@ -50,6 +51,7 @@ private:
mutable int _frameVariableCount; mutable int _frameVariableCount;
mutable int protoSize; mutable int protoSize;
mutable QString protoAbbr; mutable QString protoAbbr;
mutable QHash<int, int> _fieldFrameBitOffset;
OstProto::Protocol _data; OstProto::Protocol _data;
protected: protected:
@ -61,6 +63,13 @@ protected:
//! Is protocol typically followed by payload or another protocol //! Is protocol typically followed by payload or another protocol
bool _hasPayload; bool _hasPayload;
//! Caching Control Flags
enum CacheFlag {
FieldFrameBitOffsetCache = 0x1
};
Q_DECLARE_FLAGS(CacheFlags, CacheFlag);
CacheFlags _cacheFlags;
public: public:
//! Properties of a field, can be OR'd //! Properties of a field, can be OR'd
enum FieldFlag { enum FieldFlag {
@ -170,6 +179,7 @@ private:
void varyProtocolFrameValue(QByteArray &buf, int frameIndex, void varyProtocolFrameValue(QByteArray &buf, int frameIndex,
const OstProto::VariableField &varField) const; const OstProto::VariableField &varField) const;
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractProtocol::CacheFlags);
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractProtocol::FieldFlags); Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractProtocol::FieldFlags);
#endif #endif

View File

@ -25,6 +25,8 @@ QHash<int, int> GmpProtocol::frameFieldCountMap;
GmpProtocol::GmpProtocol(StreamBase *stream, AbstractProtocol *parent) GmpProtocol::GmpProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream, parent) : AbstractProtocol(stream, parent)
{ {
// field count may change based on msgType - so don't cache field offsets
_cacheFlags &= ~FieldFrameBitOffsetCache;
} }
GmpProtocol::~GmpProtocol() GmpProtocol::~GmpProtocol()

View File

@ -27,6 +27,8 @@ IcmpProtocol::IcmpProtocol(StreamBase *stream, AbstractProtocol *parent)
IcmpProtocol::~IcmpProtocol() IcmpProtocol::~IcmpProtocol()
{ {
// field count may change based on msgType - so don't cache field offsets
_cacheFlags &= ~FieldFrameBitOffsetCache;
} }
AbstractProtocol* IcmpProtocol::createInstance(StreamBase *stream, AbstractProtocol* IcmpProtocol::createInstance(StreamBase *stream,