mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-08 00:06:51 -05:00
Add QgsFeature::approximateMemoryUsage()
This commit is contained in:
parent
7ac4b51885
commit
a04fcce548
@ -547,6 +547,17 @@ before this method can be used.
|
|||||||
:return: -1 if field does not exist or field map is not associated.
|
:return: -1 if field does not exist or field map is not associated.
|
||||||
|
|
||||||
.. seealso:: :py:func:`setFields`
|
.. seealso:: :py:func:`setFields`
|
||||||
|
%End
|
||||||
|
|
||||||
|
int approximateMemoryUsage() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the approximate RAM usage of the feature, in bytes.
|
||||||
|
|
||||||
|
This method takes into account the size of variable elements (strings,
|
||||||
|
geometry, ...), but the value returned should be considered as a lower
|
||||||
|
bound estimation.
|
||||||
|
|
||||||
|
.. versionadded:: 3.16
|
||||||
%End
|
%End
|
||||||
|
|
||||||
operator QVariant() const;
|
operator QVariant() const;
|
||||||
|
|||||||
@ -18,6 +18,8 @@ email : sherman at mrcc.com
|
|||||||
#include "qgsfields.h"
|
#include "qgsfields.h"
|
||||||
#include "qgsgeometry.h"
|
#include "qgsgeometry.h"
|
||||||
#include "qgsrectangle.h"
|
#include "qgsrectangle.h"
|
||||||
|
#include "qgsfield_p.h" // for approximateMemoryUsage()
|
||||||
|
#include "qgsfields_p.h" // for approximateMemoryUsage()
|
||||||
|
|
||||||
#include "qgsmessagelog.h"
|
#include "qgsmessagelog.h"
|
||||||
|
|
||||||
@ -279,6 +281,58 @@ int QgsFeature::fieldNameIndex( const QString &fieldName ) const
|
|||||||
return d->fields.lookupField( fieldName );
|
return d->fields.lookupField( fieldName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t qgsQStringApproximateMemoryUsage( const QString &str )
|
||||||
|
{
|
||||||
|
return sizeof( QString ) + str.size() * sizeof( QChar );
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t qgsQVariantApproximateMemoryUsage( const QVariant &v )
|
||||||
|
{
|
||||||
|
// A QVariant has a private structure that is a union of things whose larger
|
||||||
|
// size if a long long, and a int
|
||||||
|
size_t s = sizeof( QVariant ) + sizeof( long long ) + sizeof( int );
|
||||||
|
if ( v.type() == QVariant::String )
|
||||||
|
{
|
||||||
|
s += qgsQStringApproximateMemoryUsage( v.toString() );
|
||||||
|
}
|
||||||
|
else if ( v.type() == QVariant::StringList )
|
||||||
|
{
|
||||||
|
for ( const QString &str : v.toStringList() )
|
||||||
|
s += qgsQStringApproximateMemoryUsage( str );
|
||||||
|
}
|
||||||
|
else if ( v.type() == QVariant::List )
|
||||||
|
{
|
||||||
|
for ( const QVariant &subV : v.toList() )
|
||||||
|
s += qgsQVariantApproximateMemoryUsage( subV );
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QgsFeature::approximateMemoryUsage() const
|
||||||
|
{
|
||||||
|
size_t s = sizeof( *this ) + sizeof( *d );
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
for ( const QVariant &attr : qgis::as_const( d->attributes ) )
|
||||||
|
{
|
||||||
|
s += qgsQVariantApproximateMemoryUsage( attr );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Geometry
|
||||||
|
s += sizeof( QAtomicInt ) + sizeof( void * ); // ~ sizeof(QgsGeometryPrivate)
|
||||||
|
// For simplicity we consider that the RAM usage is the one of the WKB
|
||||||
|
// representation
|
||||||
|
s += d->geometry.wkbSize();
|
||||||
|
|
||||||
|
// Fields
|
||||||
|
s += sizeof( QgsFieldsPrivate );
|
||||||
|
// TODO potentially: take into account the length of the name, comment, default value, etc...
|
||||||
|
s += d->fields.size() * ( sizeof( QgsField ) + sizeof( QgsFieldPrivate ) );
|
||||||
|
|
||||||
|
return static_cast<int>( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* This class is considered CRITICAL and any change MUST be accompanied with
|
* This class is considered CRITICAL and any change MUST be accompanied with
|
||||||
* full unit tests in testqgsfeature.cpp.
|
* full unit tests in testqgsfeature.cpp.
|
||||||
|
|||||||
@ -536,6 +536,17 @@ class CORE_EXPORT QgsFeature
|
|||||||
*/
|
*/
|
||||||
int fieldNameIndex( const QString &fieldName ) const;
|
int fieldNameIndex( const QString &fieldName ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the approximate RAM usage of the feature, in bytes.
|
||||||
|
*
|
||||||
|
* This method takes into account the size of variable elements (strings,
|
||||||
|
* geometry, ...), but the value returned should be considered as a lower
|
||||||
|
* bound estimation.
|
||||||
|
*
|
||||||
|
* \since QGIS 3.16
|
||||||
|
*/
|
||||||
|
int approximateMemoryUsage() const;
|
||||||
|
|
||||||
//! Allows direct construction of QVariants from features.
|
//! Allows direct construction of QVariants from features.
|
||||||
operator QVariant() const
|
operator QVariant() const
|
||||||
{
|
{
|
||||||
|
|||||||
@ -124,6 +124,7 @@ void TestQgsFeature::attributesTest()
|
|||||||
void TestQgsFeature::constructorTest()
|
void TestQgsFeature::constructorTest()
|
||||||
{
|
{
|
||||||
QgsFeature f;
|
QgsFeature f;
|
||||||
|
QVERIFY( f.approximateMemoryUsage() > 0 );
|
||||||
QVERIFY( FID_IS_NULL( f.id() ) );
|
QVERIFY( FID_IS_NULL( f.id() ) );
|
||||||
QgsFeature f2 { QgsFields() };
|
QgsFeature f2 { QgsFields() };
|
||||||
QVERIFY( FID_IS_NULL( f2.id() ) );
|
QVERIFY( FID_IS_NULL( f2.id() ) );
|
||||||
@ -222,6 +223,7 @@ void TestQgsFeature::attributes()
|
|||||||
feature.setAttributes( mAttrs );
|
feature.setAttributes( mAttrs );
|
||||||
QCOMPARE( feature.attributes(), mAttrs );
|
QCOMPARE( feature.attributes(), mAttrs );
|
||||||
QCOMPARE( feature.attributes(), mAttrs );
|
QCOMPARE( feature.attributes(), mAttrs );
|
||||||
|
QVERIFY( feature.approximateMemoryUsage() > QgsFeature().approximateMemoryUsage() );
|
||||||
|
|
||||||
//test implicit sharing detachment
|
//test implicit sharing detachment
|
||||||
QgsFeature copy( feature );
|
QgsFeature copy( feature );
|
||||||
@ -286,6 +288,7 @@ void TestQgsFeature::geometry()
|
|||||||
//test no double delete of geometry when setting:
|
//test no double delete of geometry when setting:
|
||||||
feature.setGeometry( QgsGeometry( mGeometry2 ) );
|
feature.setGeometry( QgsGeometry( mGeometry2 ) );
|
||||||
QVERIFY( feature.hasGeometry() );
|
QVERIFY( feature.hasGeometry() );
|
||||||
|
QVERIFY( feature.approximateMemoryUsage() > QgsFeature().approximateMemoryUsage() );
|
||||||
feature.setGeometry( QgsGeometry( mGeometry ) );
|
feature.setGeometry( QgsGeometry( mGeometry ) );
|
||||||
QCOMPARE( feature.geometry().asWkb(), mGeometry.asWkb() );
|
QCOMPARE( feature.geometry().asWkb(), mGeometry.asWkb() );
|
||||||
|
|
||||||
@ -355,6 +358,8 @@ void TestQgsFeature::fields()
|
|||||||
QVERIFY( original.fields().isEmpty() );
|
QVERIFY( original.fields().isEmpty() );
|
||||||
original.setFields( mFields );
|
original.setFields( mFields );
|
||||||
QCOMPARE( original.fields(), mFields );
|
QCOMPARE( original.fields(), mFields );
|
||||||
|
QVERIFY( original.approximateMemoryUsage() > QgsFeature().approximateMemoryUsage() );
|
||||||
|
|
||||||
QgsFeature copy( original );
|
QgsFeature copy( original );
|
||||||
QCOMPARE( copy.fields(), original.fields() );
|
QCOMPARE( copy.fields(), original.fields() );
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user