Working on streaming metadata.

This commit is contained in:
Andrzej Kapolka 2014-03-14 18:22:56 -07:00
parent ee084d1afd
commit 35f57cb998
3 changed files with 37 additions and 29 deletions

View file

@ -90,11 +90,12 @@ QList<const QMetaObject*> Bitstream::getMetaObjectSubClasses(const QMetaObject*
return getMetaObjectSubClasses().values(metaObject); return getMetaObjectSubClasses().values(metaObject);
} }
Bitstream::Bitstream(QDataStream& underlying, QObject* parent) : Bitstream::Bitstream(QDataStream& underlying, MetadataType metadataType, QObject* parent) :
QObject(parent), QObject(parent),
_underlying(underlying), _underlying(underlying),
_byte(0), _byte(0),
_position(0), _position(0),
_metadataType(metadataType),
_metaObjectStreamer(*this), _metaObjectStreamer(*this),
_typeStreamerStreamer(*this), _typeStreamerStreamer(*this),
_attributeStreamer(*this), _attributeStreamer(*this),

View file

@ -55,26 +55,26 @@ private:
/// Provides a means to stream repeated values efficiently. The value is first streamed along with a unique ID. When /// Provides a means to stream repeated values efficiently. The value is first streamed along with a unique ID. When
/// subsequently streamed, only the ID is sent. /// subsequently streamed, only the ID is sent.
template<class T, class P = T> class RepeatedValueStreamer { template<class K, class P = K, class V = K> class RepeatedValueStreamer {
public: public:
RepeatedValueStreamer(Bitstream& stream) : _stream(stream), _idStreamer(stream), RepeatedValueStreamer(Bitstream& stream) : _stream(stream), _idStreamer(stream),
_lastPersistentID(0), _lastTransientOffset(0) { } _lastPersistentID(0), _lastTransientOffset(0) { }
QHash<T, int> getAndResetTransientOffsets(); QHash<K, int> getAndResetTransientOffsets();
void persistTransientOffsets(const QHash<T, int>& transientOffsets); void persistTransientOffsets(const QHash<K, int>& transientOffsets);
QHash<int, T> getAndResetTransientValues(); QHash<int, V> getAndResetTransientValues();
void persistTransientValues(const QHash<int, T>& transientValues); void persistTransientValues(const QHash<int, V>& transientValues);
int takePersistentID(P value) { return _persistentIDs.take(value); } int takePersistentID(P value) { return _persistentIDs.take(value); }
T takePersistentValue(int id) { T value = _persistentValues.take(id); _persistentIDs.remove(value); return value; } V takePersistentValue(int id) { V value = _persistentValues.take(id); _valueIDs.remove(value); return value; }
RepeatedValueStreamer& operator<<(T value); RepeatedValueStreamer& operator<<(K value);
RepeatedValueStreamer& operator>>(T& value); RepeatedValueStreamer& operator>>(V& value);
private: private:
@ -83,23 +83,24 @@ private:
int _lastPersistentID; int _lastPersistentID;
int _lastTransientOffset; int _lastTransientOffset;
QHash<P, int> _persistentIDs; QHash<P, int> _persistentIDs;
QHash<T, int> _transientOffsets; QHash<K, int> _transientOffsets;
QHash<int, T> _persistentValues; QHash<int, V> _persistentValues;
QHash<int, T> _transientValues; QHash<int, V> _transientValues;
QHash<V, int> _valueIDs;
}; };
template<class T, class P> inline QHash<T, int> RepeatedValueStreamer<T, P>::getAndResetTransientOffsets() { template<class K, class P, class V> inline QHash<K, int> RepeatedValueStreamer<K, P, V>::getAndResetTransientOffsets() {
QHash<T, int> transientOffsets; QHash<K, int> transientOffsets;
_transientOffsets.swap(transientOffsets); _transientOffsets.swap(transientOffsets);
_lastTransientOffset = 0; _lastTransientOffset = 0;
_idStreamer.setBitsFromValue(_lastPersistentID); _idStreamer.setBitsFromValue(_lastPersistentID);
return transientOffsets; return transientOffsets;
} }
template<class T, class P> inline void RepeatedValueStreamer<T, P>::persistTransientOffsets( template<class K, class P, class V> inline void RepeatedValueStreamer<K, P, V>::persistTransientOffsets(
const QHash<T, int>& transientOffsets) { const QHash<K, int>& transientOffsets) {
int oldLastPersistentID = _lastPersistentID; int oldLastPersistentID = _lastPersistentID;
for (typename QHash<T, int>::const_iterator it = transientOffsets.constBegin(); it != transientOffsets.constEnd(); it++) { for (typename QHash<K, int>::const_iterator it = transientOffsets.constBegin(); it != transientOffsets.constEnd(); it++) {
int& id = _persistentIDs[it.key()]; int& id = _persistentIDs[it.key()];
if (id == 0) { if (id == 0) {
id = oldLastPersistentID + it.value(); id = oldLastPersistentID + it.value();
@ -109,18 +110,18 @@ template<class T, class P> inline void RepeatedValueStreamer<T, P>::persistTrans
_idStreamer.setBitsFromValue(_lastPersistentID); _idStreamer.setBitsFromValue(_lastPersistentID);
} }
template<class T, class P> inline QHash<int, T> RepeatedValueStreamer<T, P>::getAndResetTransientValues() { template<class K, class P, class V> inline QHash<int, V> RepeatedValueStreamer<K, P, V>::getAndResetTransientValues() {
QHash<int, T> transientValues; QHash<int, V> transientValues;
_transientValues.swap(transientValues); _transientValues.swap(transientValues);
_idStreamer.setBitsFromValue(_lastPersistentID); _idStreamer.setBitsFromValue(_lastPersistentID);
return transientValues; return transientValues;
} }
template<class T, class P> inline void RepeatedValueStreamer<T, P>::persistTransientValues( template<class K, class P, class V> inline void RepeatedValueStreamer<K, P, V>::persistTransientValues(
const QHash<int, T>& transientValues) { const QHash<int, V>& transientValues) {
int oldLastPersistentID = _lastPersistentID; int oldLastPersistentID = _lastPersistentID;
for (typename QHash<int, T>::const_iterator it = transientValues.constBegin(); it != transientValues.constEnd(); it++) { for (typename QHash<int, V>::const_iterator it = transientValues.constBegin(); it != transientValues.constEnd(); it++) {
int& id = _persistentIDs[it.value()]; int& id = _valueIDs[it.value()];
if (id == 0) { if (id == 0) {
id = oldLastPersistentID + it.key(); id = oldLastPersistentID + it.key();
_lastPersistentID = qMax(_lastPersistentID, id); _lastPersistentID = qMax(_lastPersistentID, id);
@ -130,7 +131,8 @@ template<class T, class P> inline void RepeatedValueStreamer<T, P>::persistTrans
_idStreamer.setBitsFromValue(_lastPersistentID); _idStreamer.setBitsFromValue(_lastPersistentID);
} }
template<class T, class P> inline RepeatedValueStreamer<T, P>& RepeatedValueStreamer<T, P>::operator<<(T value) { template<class K, class P, class V> inline RepeatedValueStreamer<K, P, V>&
RepeatedValueStreamer<K, P, V>::operator<<(K value) {
int id = _persistentIDs.value(value); int id = _persistentIDs.value(value);
if (id == 0) { if (id == 0) {
int& offset = _transientOffsets[value]; int& offset = _transientOffsets[value];
@ -147,7 +149,8 @@ template<class T, class P> inline RepeatedValueStreamer<T, P>& RepeatedValueStre
return *this; return *this;
} }
template<class T, class P> inline RepeatedValueStreamer<T, P>& RepeatedValueStreamer<T, P>::operator>>(T& value) { template<class K, class P, class V> inline RepeatedValueStreamer<K, P, V>&
RepeatedValueStreamer<K, P, V>::operator>>(V& value) {
int id; int id;
_idStreamer >> id; _idStreamer >> id;
if (id <= _lastPersistentID) { if (id <= _lastPersistentID) {
@ -155,7 +158,7 @@ template<class T, class P> inline RepeatedValueStreamer<T, P>& RepeatedValueStre
} else { } else {
int offset = id - _lastPersistentID; int offset = id - _lastPersistentID;
typename QHash<int, T>::iterator it = _transientValues.find(offset); typename QHash<int, V>::iterator it = _transientValues.find(offset);
if (it == _transientValues.end()) { if (it == _transientValues.end()) {
_stream > value; _stream > value;
_transientValues.insert(offset, value); _transientValues.insert(offset, value);
@ -205,8 +208,10 @@ public:
/// Returns the list of registered subclasses for the supplied meta-object. /// Returns the list of registered subclasses for the supplied meta-object.
static QList<const QMetaObject*> getMetaObjectSubClasses(const QMetaObject* metaObject); static QList<const QMetaObject*> getMetaObjectSubClasses(const QMetaObject* metaObject);
enum MetadataType { NO_METADATA, HASH_METADATA, FULL_METADATA };
/// Creates a new bitstream. Note: the stream may be used for reading or writing, but not both. /// Creates a new bitstream. Note: the stream may be used for reading or writing, but not both.
Bitstream(QDataStream& underlying, QObject* parent = NULL); Bitstream(QDataStream& underlying, MetadataType metadataType = NO_METADATA, QObject* parent = NULL);
/// Writes a set of bits to the underlying stream. /// Writes a set of bits to the underlying stream.
/// \param bits the number of bits to write /// \param bits the number of bits to write
@ -339,7 +344,9 @@ private:
quint8 _byte; quint8 _byte;
int _position; int _position;
RepeatedValueStreamer<const QMetaObject*> _metaObjectStreamer; MetadataType _metadataType;
RepeatedValueStreamer<const QMetaObject*, const QMetaObject*, const QMetaObject*> _metaObjectStreamer;
RepeatedValueStreamer<const TypeStreamer*> _typeStreamerStreamer; RepeatedValueStreamer<const TypeStreamer*> _typeStreamerStreamer;
RepeatedValueStreamer<AttributePointer> _attributeStreamer; RepeatedValueStreamer<AttributePointer> _attributeStreamer;
RepeatedValueStreamer<QScriptString> _scriptStringStreamer; RepeatedValueStreamer<QScriptString> _scriptStringStreamer;

View file

@ -143,7 +143,7 @@ private:
}; };
SetSpannerEditVisitor::SetSpannerEditVisitor(Spanner* spanner) : SetSpannerEditVisitor::SetSpannerEditVisitor(Spanner* spanner) :
MetavoxelVisitor(QVector<AttributePointer>(), spanner->getAttributes()), MetavoxelVisitor(spanner->getAttributes(), spanner->getAttributes()),
_spanner(spanner) { _spanner(spanner) {
} }