[mapguide-commits] r4386 - trunk/MgDev/Common/CoordinateSystem
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Mon Dec 7 19:27:39 EST 2009
Author: NormOlsen
Date: 2009-12-07 19:27:39 -0500 (Mon, 07 Dec 2009)
New Revision: 4386
Modified:
trunk/MgDev/Common/CoordinateSystem/CoordSysGrids.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysOneGrid.cpp
Log:
RFC 76 -- Testing has shown that some tuning on the memory use calculation was in order. This submission deals with that issue. Prior to submitting, it was verified using the help of _heapwalker that the calculated memory use is within 10% of reality. Several obstacles to making a computation more accurate than this: 1> MgCoordinate objects with multiple references are counted multiple times, and 2> MgCollection often allocates a capacity for which a substantial portion is not used. There are proably others that we have not discovered yet.
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysGrids.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysGrids.cpp 2009-12-08 00:11:08 UTC (rev 4385)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysGrids.cpp 2009-12-08 00:27:39 UTC (rev 4386)
@@ -30,6 +30,16 @@
using namespace CSLibrary;
+#if !defined (_DEBUG)
+ // Include heap overhead estinated at 12 bytes in release mode.
+ static const INT32 kMgHeapOverhead = 12;
+ static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#else
+ // Include heap overhead estinated at 48 bytes in release mode.
+ static const INT32 kMgHeapOverhead = 36;
+ static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#endif
+
//=============================================================================
// CCoordinateSystemGridSpecification -- Assembly which contains all grid
// parameter values.
@@ -662,10 +672,9 @@
}
INT32 CCoordinateSystemGridLine::GetMemoryUsage ()
{
- static const INT32 sizeOfMgCoordinateXY = 24;
INT32 lineIndex;
INT32 lineCount;
- INT32 memoryUse = sizeof (CCoordinateSystemGridLine);
+ INT32 memoryUse = sizeof (CCoordinateSystemGridLine) + kMgHeapOverhead;
lineCount = m_LineSegments->GetCount ();
for (lineIndex = 0;lineIndex < lineCount;lineIndex += 1)
@@ -673,10 +682,11 @@
Ptr<MgLineString> lineStringPtr = m_LineSegments->GetItem (lineIndex);
if (lineStringPtr != 0)
{
+ memoryUse += sizeof (MgLineString) + kMgHeapOverhead;
Ptr<MgCoordinateIterator> pointItr = lineStringPtr->GetCoordinates ();
while (pointItr->MoveNext ())
{
- memoryUse += sizeOfMgCoordinateXY;
+ memoryUse += kMgSizeOfCoordinateXY;
}
}
}
@@ -807,17 +817,21 @@
INT32 CCoordinateSystemGridRegion::GetMemoryUsage ()
{
INT32 memoryUse;
- static const INT32 sizeOfMgCoordinateXY = 24;
- memoryUse = sizeof (CCoordinateSystemGridRegion);
+ memoryUse = sizeof (CCoordinateSystemGridRegion) + kMgHeapOverhead;
memoryUse += sizeof (STRING);
memoryUse += m_RegionLabel.capacity () * sizeof (wchar_t);
- memoryUse += sizeOfMgCoordinateXY;
+ memoryUse += kMgSizeOfCoordinateXY;
memoryUse += PolygonMemoryUse (m_RegionBoundary.p);
memoryUse += LineStringCollectionMemoryUse (m_SouthLine.p);
memoryUse += LineStringCollectionMemoryUse (m_EastLine.p);
memoryUse += LineStringCollectionMemoryUse (m_NorthLine.p);
memoryUse += LineStringCollectionMemoryUse (m_WestLine.p);
+
+ // Testing has shown the above calculation to be about 20% low.
+ // This is assumed to be because collections have a capacity and a useage,
+ // and while we measure usage above, we can't measure capacity.
+ memoryUse += memoryUse / 5;
return memoryUse;
}
void CCoordinateSystemGridRegion::SetRegionBoundary (MgPolygon* boundary)
@@ -846,43 +860,42 @@
}
INT32 CCoordinateSystemGridRegion::PolygonMemoryUse (MgPolygon* polygon)
{
- // WHile MgPolygon objects support holes, there are no holes in a Region
+ // While MgPolygon objects support holes, there are no holes in a Region
// (so far anyway); so we only evaluate the exterior ring.
- static const INT32 sizeOfMgCoordinateXY = 24;
- INT32 memoryUse (0);
+ INT32 memoryUse;
+ memoryUse = sizeof (MgPolygon) + kMgHeapOverhead;
if (polygon != 0)
{
Ptr<MgCoordinateIterator> pointItr = polygon->GetCoordinates ();
while (pointItr->MoveNext ())
{
- memoryUse += sizeOfMgCoordinateXY;
+ memoryUse += kMgSizeOfCoordinateXY;
}
}
return memoryUse;
}
INT32 CCoordinateSystemGridRegion::LineStringCollectionMemoryUse (MgLineStringCollection* lineCollection)
{
- static const INT32 sizeOfMgCoordinateXY = 24;
INT32 memoryUse (0);
INT32 lineCount;
INT32 lineIndex;
if (lineCollection != 0)
{
- memoryUse += sizeof (MgLineStringCollection);
+ memoryUse += sizeof (MgLineStringCollection) + kMgHeapOverhead;
lineCount = lineCollection->GetCount ();
for (lineIndex = 0;lineIndex < lineCount;lineIndex += 1)
{
Ptr<MgLineString> lineStringPtr = lineCollection->GetItem (lineIndex);
if (lineStringPtr != 0)
{
- memoryUse += sizeof (MgLineString);
+ memoryUse += sizeof (MgLineString) + kMgHeapOverhead;
Ptr<MgCoordinateIterator> pointItr = lineStringPtr->GetCoordinates ();
while (pointItr->MoveNext ())
{
- memoryUse += sizeOfMgCoordinateXY;
+ memoryUse += kMgSizeOfCoordinateXY;
}
}
}
@@ -954,9 +967,8 @@
}
INT32 CCoordinateSystemGridTick::GetMemoryUsage ()
{
- static const INT32 MgSizeOfCoordinateXY = 24;
- INT32 memoryUse = sizeof (CCoordinateSystemGridTick);
- memoryUse += 2 * MgSizeOfCoordinateXY;
+ INT32 memoryUse = sizeof (CCoordinateSystemGridTick) + kMgHeapOverhead;
+ memoryUse += (kMgSizeOfCoordinateXY + kMgSizeOfCoordinateXY);
return memoryUse;
}
void CCoordinateSystemGridTick::Dispose ()
@@ -972,10 +984,11 @@
CCoordinateSystemGridLineCollection::CCoordinateSystemGridLineCollection (INT32 gridLineExceptionLevel)
:
MgCoordinateSystemGridLineCollection (),
- m_MemoryUse (0),
+ m_MemoryUse (),
m_GridLineExceptionLevel (gridLineExceptionLevel),
m_GridLineCollection ()
{
+ m_MemoryUse = sizeof (MgCoordinateSystemGridLineCollection) + sizeof (MgDisposableCollection);
m_GridLineCollection = new MgDisposableCollection();
}
CCoordinateSystemGridLineCollection::~CCoordinateSystemGridLineCollection(void)
@@ -1030,10 +1043,16 @@
// The MgDisposableCollection object checks the index argument, and throws if appropriate.
// The MgDisposableCollection object performs the "SAFE_RELEASE" operation.
- Ptr<MgCoordinateSystemGridLine> gridLinePtr = this->GetItem (index);
- if (gridLinePtr != 0)
+ if (index >= 0 && index < GetCount ())
{
- memoryUse = gridLinePtr->GetMemoryUsage ();
+ // We don't want an invalid index exception thrown from this GetItem,
+ // we leave that to the RemoveAt function. Also, this releases the
+ // pointer we get before the exception is thrown.
+ Ptr<MgCoordinateSystemGridLine> gridLinePtr = GetItem (index);
+ if (gridLinePtr != 0)
+ {
+ memoryUse = gridLinePtr->GetMemoryUsage ();
+ }
}
m_GridLineCollection->RemoveAt (index);
m_MemoryUse -= memoryUse;
@@ -1042,13 +1061,29 @@
{
// The MgDisposableCollection object performs the "SAFE_RELEASE" operation.
m_GridLineCollection->Clear ();
- m_MemoryUse = 0;
+ m_MemoryUse = sizeof (MgCoordinateSystemGridLineCollection) + sizeof (MgDisposableCollection);
}
void CCoordinateSystemGridLineCollection::SetItem (INT32 index,MgCoordinateSystemGridLine* value)
{
- // The MgDisposableCollection object checks the index argument, and throws if appropriate.
- // The MgDisposableCollection object performs the "SAFE_RELEASE" & "SAFE_ADDREF" operations.
- m_GridLineCollection->SetItem (index,value);
+ INT32 memoryUse (0);
+
+ memoryUse = value->GetMemoryUsage ();
+ if (index >= 0 && index < GetCount ())
+ {
+ Ptr<MgCoordinateSystemGridLine> oldGridLine = GetItem (index);
+ if (oldGridLine != 0)
+ {
+ memoryUse -= oldGridLine->GetMemoryUsage ();
+ }
+ }
+ if ((m_MemoryUse + memoryUse) < m_GridLineExceptionLevel)
+ {
+ m_GridLineCollection->SetItem (index,value);
+ }
+ else
+ {
+ throw new MgGridDensityException(L"CCoordinateSystemGridLineCollection.SetItem", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
}
void CCoordinateSystemGridLineCollection::Add (MgCoordinateSystemGridLine* value)
{
@@ -1108,10 +1143,11 @@
CCoordinateSystemGridRegionCollection::CCoordinateSystemGridRegionCollection (INT32 gridRegionExceptionLevel)
:
MgCoordinateSystemGridRegionCollection (),
- m_MemoryUse (0),
+ m_MemoryUse (),
m_GridRegionExceptionLevel (gridRegionExceptionLevel),
m_GridRegionCollection ()
{
+ m_MemoryUse = sizeof (CCoordinateSystemGridRegionCollection) + sizeof (MgDisposableCollection);
m_GridRegionCollection = new MgDisposableCollection();
}
CCoordinateSystemGridRegionCollection::~CCoordinateSystemGridRegionCollection (void)
@@ -1132,26 +1168,44 @@
}
void CCoordinateSystemGridRegionCollection::RemoveAt (INT32 index)
{
+ INT32 memoryUse (0);
+
// The MgDisposableCollection object checks the index argument, and throws if appropriate.
// The MgDisposableCollection object performs the "SAFE_RELEASE" operation.
+
+ if (index >= 0 && index < GetCount ())
+ {
+ // We don't want an invalid index exception thrown from this GetItem,
+ // we leave that to the RemoveAt function. Also, this releases the
+ // pointer we get before the exception is thrown.
+ Ptr<MgCoordinateSystemGridRegion> gridRegionPtr = GetItem (index);
+ if (gridRegionPtr != 0)
+ {
+ memoryUse = gridRegionPtr->GetMemoryUsage ();
+ }
+ }
m_GridRegionCollection->RemoveAt (index);
+ m_MemoryUse -= memoryUse;
}
void CCoordinateSystemGridRegionCollection::Clear()
{
m_GridRegionCollection->Clear ();
- m_MemoryUse = 0;
+ m_MemoryUse = sizeof (CCoordinateSystemGridRegionCollection) + sizeof (MgDisposableCollection);
}
void CCoordinateSystemGridRegionCollection::SetItem (INT32 index, MgCoordinateSystemGridRegion* value)
{
INT32 memoryUse;
- Ptr<MgCoordinateSystemGridRegion> currentPtr = static_cast<MgCoordinateSystemGridRegion*>(m_GridRegionCollection->GetItem (index));
- if (currentPtr != 0)
+ memoryUse = value->GetMemoryUsage ();
+ if (index >= 0 && index < GetCount ())
{
- m_MemoryUse -= currentPtr->GetMemoryUsage ();
+ Ptr<MgCoordinateSystemGridRegion> currentPtr = GetItem (index);
+ if (currentPtr != 0)
+ {
+ memoryUse -= currentPtr->GetMemoryUsage ();
+ }
}
- memoryUse = value->GetMemoryUsage ();
- if ((memoryUse + m_MemoryUse) < m_GridRegionExceptionLevel)
+ if ((m_MemoryUse + memoryUse) < m_GridRegionExceptionLevel)
{
m_GridRegionCollection->SetItem (index,value);
m_MemoryUse += memoryUse;
@@ -1220,10 +1274,11 @@
CCoordinateSystemGridTickCollection::CCoordinateSystemGridTickCollection (INT32 gridTickExceptionLevel)
:
MgCoordinateSystemGridTickCollection (),
- m_MemoryUse (0),
+ m_MemoryUse (),
m_GridTickExceptionLevel (gridTickExceptionLevel),
m_GridTickCollection ()
{
+ m_MemoryUse = sizeof (CCoordinateSystemGridTickCollection) + sizeof (MgDisposableCollection);
m_GridTickCollection = new MgDisposableCollection();
}
CCoordinateSystemGridTickCollection::~CCoordinateSystemGridTickCollection (void)
@@ -1242,16 +1297,53 @@
}
void CCoordinateSystemGridTickCollection::RemoveAt (INT32 index)
{
+ INT32 memoryUse (0);
+
+ // The MgDisposableCollection object checks the index argument, and throws if appropriate.
+ // The MgDisposableCollection object performs the "SAFE_RELEASE" operation.
+
+ if (index >= 0 && index < GetCount ())
+ {
+ // We don't want an invalid index exception thrown from this GetItem,
+ // we leave that to the RemoveAt function. Also, this releases the
+ // pointer we get before the exception is thrown.
+ Ptr<MgCoordinateSystemGridTick> gridTickPtr = GetItem (index);
+ if (gridTickPtr != 0)
+ {
+ memoryUse = gridTickPtr->GetMemoryUsage ();
+ }
+ }
m_GridTickCollection->RemoveAt (index);
+ m_MemoryUse -= memoryUse;
}
void CCoordinateSystemGridTickCollection::Clear()
{
m_GridTickCollection->Clear ();
- m_MemoryUse = 0;
+ m_MemoryUse = sizeof (CCoordinateSystemGridTickCollection) + sizeof (MgDisposableCollection);
}
void CCoordinateSystemGridTickCollection::SetItem (INT32 index, MgCoordinateSystemGridTick* value)
{
- m_GridTickCollection->SetItem (index,value);
+ INT32 memoryUse;
+
+ memoryUse = value->GetMemoryUsage ();
+ if (index >= 0 && index < GetCount ())
+ {
+ Ptr<MgCoordinateSystemGridTick> currentPtr = GetItem (index);
+ if (currentPtr != 0)
+ {
+ memoryUse -= currentPtr->GetMemoryUsage ();
+ }
+ }
+ if ((m_MemoryUse + memoryUse) < m_GridTickExceptionLevel)
+ {
+ m_GridTickCollection->SetItem (index,value);
+ m_MemoryUse += memoryUse;
+ }
+ else
+ {
+ throw new MgGridDensityException(L"CCoordinateSystemGridTickCollection.SetItem", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
}
void CCoordinateSystemGridTickCollection::Add (MgCoordinateSystemGridTick* value)
{
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.cpp 2009-12-08 00:11:08 UTC (rev 4385)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysMgrsZone.cpp 2009-12-08 00:27:39 UTC (rev 4386)
@@ -29,6 +29,16 @@
using namespace CSLibrary;
+#if !defined (_DEBUG)
+ // Include heap overhead estinated at 12 bytes in release mode.
+ static const INT32 kMgHeapOverhead = 12;
+ static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#else
+ // Include heap overhead estinated at 48 bytes in release mode.
+ static const INT32 kMgHeapOverhead = 36;
+ static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + kMgHeapOverhead;
+#endif
+
CCoordinateSystemMgrsZone::CCoordinateSystemMgrsZone (MgCoordinateSystemGridBoundary* frameBoundary,
INT32 utmZoneNbr,
bool useFrameDatum,
@@ -232,11 +242,27 @@
INT32 regionCount;
INT32 memoryGuess (0);
-
-
// Estimate the size of a major region object. Eventually, should include
- // MaxPoints and curve precision from the specification object.
- regionSize = (GridFrameCrsAreTheSame ()) ? 512 : 50000;
+ // MaxPoints and CurvePrecision from the specification object. For now, we
+ // make some guesses based on the coordinate systems involved.
+ if (GridFrameCrsAreTheSame ())
+ {
+ // Here, for now, we assume that there are 4 lines at two points a piece, plus
+ // a polygon with 5 points. In this case, several of these points are the
+ // same actual object in memory; so we reduce the point count by (an arbirtrary
+ // value) 3.
+ regionSize = sizeof (CCoordinateSystemGridRegion) + sizeof (MgPolygon) +
+ sizeof (MgLineString) * 4 +
+ kMgSizeOfCoordinateXY * 10;
+ }
+ else
+ {
+ // Here, for now, we assume that there are 4 lines at 511 points a piece, plus
+ // a polygon with (4 * 511) points; 4088 points altogether.
+ regionSize = sizeof (CCoordinateSystemGridRegion) + sizeof (MgPolygon) +
+ sizeof (MgLineString) * 4 +
+ kMgSizeOfCoordinateXY * 4088;
+ }
MG_TRY ()
if (specification->GetUnitType () == MgCoordinateSystemUnitType::Angular)
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysOneGrid.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysOneGrid.cpp 2009-12-08 00:11:08 UTC (rev 4385)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysOneGrid.cpp 2009-12-08 00:27:39 UTC (rev 4386)
@@ -28,6 +28,14 @@
using namespace CSLibrary;
+#if !defined (_DEBUG)
+ // Include heap overhead estinated at 12 bytes in release mode.
+ static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + 12;
+#else
+ // Include heap overhead estinated at 48 bytes in release mode.
+ static const INT32 kMgSizeOfCoordinateXY = sizeof (MgCoordinateXY) + 48;
+#endif
+
//=============================================================================
// CCoordinateSystemOneGrid
const INT32 CCoordinateSystemOneGrid::MaxCurvePoints = 511;
@@ -418,7 +426,85 @@
INT32 CCoordinateSystemOneGrid::ApproxGridLineMemoryUsage (MgCoordinateSystemGridSpecification* specification)
{
- return 50000;
+ INT32 memoryUse (5000000);
+ INT32 lineSize;
+ INT32 lineCount;
+ INT32 gridCrsUnitCode;
+
+ double delta;
+ double increment;
+ double precision;
+ double eastMin, eastMax;
+ double northMin, northMax;
+
+ // We'll compute the number of grid lines which can be expected given the
+ // provided specification. For now, we just make a guess at the size of
+ // each line based on the coordinate systems involved.
+ if (m_GridFrameCrsSame)
+ {
+ lineSize = sizeof (CCoordinateSystemGridLine) + sizeof (MgLineStringCollection) +
+ sizeof (MgLineString) +
+ kMgSizeOfCoordinateXY * 2;
+ }
+ else
+ {
+ lineSize = sizeof (CCoordinateSystemGridLine) + sizeof (MgLineStringCollection) +
+ sizeof (MgLineString) * 2 +
+ kMgSizeOfCoordinateXY * 511;
+ }
+
+ // TODO --> The folowing 40 or so lines of code are a cut and paste from
+ // the line generator code above. This should be placed in a separate function
+ // to eliminate duplicate code. For now, we jkust want to see how well all
+ // of this memory management stuff works.
+ MG_TRY ()
+ gridCrsUnitCode = m_GridCRS->GetUnitCode ();
+ CCoordinateSystemGridSpecification* mySpecPtr = dynamic_cast<CCoordinateSystemGridSpecification*>(specification);
+ precision = mySpecPtr->GetCurvePrecision (m_GridCRS);
+ // The following does not generate a boundary if it has already been
+ // generated.
+ GenerateGridBoundary (precision);
+
+ // Compute the range of the grid line generation.
+ m_GridBoundary->GetBoundaryExtents (eastMin,eastMax,northMin,northMax);
+
+ // Expand the range to include all grid values at the extents.
+ increment = mySpecPtr->GetEastingIncrement(gridCrsUnitCode);
+ delta = fabs(fmod (eastMin,increment));
+ eastMin -= (eastMin >= 0.0) ? delta : (increment - delta);
+ delta = fabs(fmod (eastMax,increment));
+ eastMax += (eastMax >= 0.0) ? (increment - delta) : delta;
+
+ increment = mySpecPtr->GetNorthingIncrement(gridCrsUnitCode);
+ delta = fabs(fmod (northMin,increment));
+ northMin -= (northMin >= 0.0) ? delta : (increment - delta);
+ delta = fabs(fmod (northMax,increment));
+ northMax += (northMax >= 0.0) ? (increment - delta) : delta;
+
+ // Adjust for the base. Again, we always enlarge, never shrink.
+ if (mySpecPtr->GetEastingBase () > 0.0)
+ {
+ increment = mySpecPtr->GetEastingIncrement (gridCrsUnitCode);
+ delta = fmod (mySpecPtr->GetEastingBase(gridCrsUnitCode),increment);
+ eastMin += delta - increment;
+ eastMax += delta + increment;
+ }
+ if (mySpecPtr->GetNorthingBase () > 0.0)
+ {
+ increment = mySpecPtr->GetNorthingIncrement (gridCrsUnitCode);
+ delta = fmod (mySpecPtr->GetNorthingBase(gridCrsUnitCode),increment);
+ northMin += delta - increment;
+ northMax += delta + increment;
+ }
+
+ // Compute the number of grid line objects we will need to create.
+ increment = mySpecPtr->GetEastingIncrement(gridCrsUnitCode);
+ lineCount = static_cast<INT32>(fabs (eastMax - eastMin) / increment);
+ increment = mySpecPtr->GetNorthingIncrement(gridCrsUnitCode);
+ lineCount += static_cast<INT32>(fabs (northMax - northMin) / increment);
+ memoryUse = lineCount * lineSize;
+ MG_CATCH_AND_RELEASE()
+ return memoryUse;
}
INT32 CCoordinateSystemOneGrid::ApproxGridTickMemoryUsage (MgCoordinateSystemGridSpecification* specification)
{
More information about the mapguide-commits
mailing list