return *this;
Clear();
- ReSize (theOther.Extent()-1);
- Iterator anIter(theOther);
- for (; anIter.More(); anIter.Next())
- Bind (anIter.Key(), anIter.Value());
+ Standard_Integer anExt = theOther.Extent();
+ if (anExt)
+ {
+ ReSize (anExt-1);
+ Iterator anIter(theOther);
+ for (; anIter.More(); anIter.Next())
+ Bind (anIter.Key(), anIter.Value());
+ }
return *this;
}
return *this;
Clear();
- ReSize (theOther.Extent()-1);
- Iterator anIter(theOther);
- for (; anIter.More(); anIter.Next())
+ Standard_Integer anExt = theOther.Extent();
+ if (anExt)
{
- TheKey1Type aKey1 = anIter.Key1();
- TheKey2Type aKey2 = anIter.Key2();
- Standard_Integer iK1 = Hasher1::HashCode (aKey1, NbBuckets());
- Standard_Integer iK2 = Hasher2::HashCode (aKey2, NbBuckets());
- DoubleMapNode * pNode = new (this->myAllocator) DoubleMapNode (aKey1, aKey2,
- myData1[iK1],
- myData2[iK2]);
- myData1[iK1] = pNode;
- myData2[iK2] = pNode;
- Increment();
+ ReSize (anExt-1);
+ Iterator anIter(theOther);
+ for (; anIter.More(); anIter.Next())
+ {
+ TheKey1Type aKey1 = anIter.Key1();
+ TheKey2Type aKey2 = anIter.Key2();
+ Standard_Integer iK1 = Hasher1::HashCode (aKey1, NbBuckets());
+ Standard_Integer iK2 = Hasher2::HashCode (aKey2, NbBuckets());
+ DoubleMapNode * pNode = new (this->myAllocator) DoubleMapNode (aKey1, aKey2,
+ myData1[iK1],
+ myData2[iK2]);
+ myData1[iK1] = pNode;
+ myData2[iK2] = pNode;
+ Increment();
+ }
}
return *this;
}
return *this;
Clear();
- ReSize (theOther.Extent()-1);
- for (Standard_Integer anIndexIter = 1; anIndexIter <= theOther.Extent(); ++anIndexIter)
+ Standard_Integer anExt = theOther.Extent();
+ if (anExt)
{
- const TheKeyType& aKey1 = theOther.FindKey (anIndexIter);
- const TheItemType& anItem = theOther.FindFromIndex(anIndexIter);
- const Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
- IndexedDataMapNode* pNode = new (this->myAllocator) IndexedDataMapNode (aKey1, anIndexIter, anItem, myData1[iK1]);
- myData1[iK1] = pNode;
- myData2[anIndexIter - 1] = pNode;
- Increment();
+ ReSize (anExt-1); //mySize is same after resize
+ for (Standard_Integer anIndexIter = 1; anIndexIter <= anExt; ++anIndexIter)
+ {
+ const TheKeyType& aKey1 = theOther.FindKey (anIndexIter);
+ const TheItemType& anItem = theOther.FindFromIndex(anIndexIter);
+ const Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
+ IndexedDataMapNode* pNode = new (this->myAllocator) IndexedDataMapNode (aKey1, anIndexIter, anItem, myData1[iK1]);
+ myData1[iK1] = pNode;
+ myData2[anIndexIter - 1] = pNode;
+ Increment();
+ }
}
return *this;
}
return *this;
Clear();
- ReSize (theOther.Extent()-1);
- const Standard_Integer iLength = theOther.Extent();
- for (Standard_Integer anIndexIter = 1; anIndexIter <= iLength; ++anIndexIter)
+ Standard_Integer anExt = theOther.Extent();
+ if (anExt)
{
- const TheKeyType& aKey1 = theOther.FindKey (anIndexIter);
- const Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
- IndexedMapNode* pNode = new (this->myAllocator) IndexedMapNode (aKey1, anIndexIter, myData1[iK1]);
- myData1[iK1] = pNode;
- myData2[anIndexIter - 1] = pNode;
- Increment();
+ ReSize (anExt-1); //mySize is same after resize
+ for (Standard_Integer anIndexIter = 1; anIndexIter <= anExt; ++anIndexIter)
+ {
+ const TheKeyType& aKey1 = theOther.FindKey (anIndexIter);
+ const Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
+ IndexedMapNode* pNode = new (this->myAllocator) IndexedMapNode (aKey1, anIndexIter, myData1[iK1]);
+ myData1[iK1] = pNode;
+ myData2[anIndexIter - 1] = pNode;
+ Increment();
+ }
}
return *this;
}
return *this;
Clear();
- ReSize (theOther.Extent()-1);
- Iterator anIter(theOther);
- for (; anIter.More(); anIter.Next())
- Add (anIter.Key());
+ int anExt = theOther.Extent();
+ if (anExt)
+ {
+ ReSize (anExt-1);
+ Iterator anIter(theOther);
+ for (; anIter.More(); anIter.Next())
+ Add (anIter.Key());
+ }
return *this;
}
return 0;
}
+#include <NCollection_DoubleMap.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_IndexedDataMap.hxx>
+#include <OSD_MemInfo.hxx>
+
+// check that copying of empty maps does not allocate extra memory
+template<typename T> void AllocDummyArr (Draw_Interpretor& theDI, int theN1, int theN2)
+{
+ NCollection_Array1<T> aMapArr1(0, theN1), aMapArr2(0, theN2);
+
+ OSD_MemInfo aMemTool;
+ Standard_Size aMem0 = aMemTool.Value (OSD_MemInfo::MemHeapUsage);
+
+ for (int i = 1; i < theN1; i++)
+ aMapArr1(i) = aMapArr1(i-1);
+ for (int i = 1; i < theN2; i++)
+ aMapArr2(i) = aMapArr2(0);
+
+ aMemTool.Update();
+ Standard_Size aMem1 = aMemTool.Value (OSD_MemInfo::MemHeapUsage);
+
+ theDI << "Heap usage before copy = " << (int)aMem0 << ", after = " << (int)aMem1 << "\n";
+
+ if (aMem1 > aMem0)
+ theDI << "Error: memory increased by " << (int)(aMem1 - aMem0) << " bytes\n";
+};
+
+static Standard_Integer OCC29064 (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
+{
+ if (theArgc < 2)
+ {
+ cout << "Error: give argument indicating type of map (map, doublemap, datamap, indexedmap, indexeddatamap)" << endl;
+ return 1;
+ }
+
+ const int nbm1 = 10000, nbm2 = 10000;
+ if (strcasecmp (theArgv[1], "map") == 0)
+ AllocDummyArr<NCollection_Map<int> > (theDI, nbm1, nbm2);
+ else if (strcasecmp (theArgv[1], "doublemap") == 0)
+ AllocDummyArr<NCollection_DoubleMap<int, int> > (theDI, nbm1, nbm2);
+ else if (strcasecmp (theArgv[1], "datamap") == 0)
+ AllocDummyArr<NCollection_DataMap<int, int> > (theDI, nbm1, nbm2);
+ else if (strcasecmp (theArgv[1], "indexedmap") == 0)
+ AllocDummyArr<NCollection_IndexedMap<int> > (theDI, nbm1, nbm2);
+ else if (strcasecmp (theArgv[1], "indexeddatamap") == 0)
+ AllocDummyArr<NCollection_IndexedDataMap<int, int> > (theDI, nbm1, nbm2);
+ else
+ {
+ cout << "Error: unrecognized argument " << theArgv[1] << endl;
+ return 1;
+ }
+ return 0;
+}
+
#include <BRepOffsetAPI_MakePipeShell.hxx>
#include <GC_MakeArcOfCircle.hxx>
#include <BRepAdaptor_CompCurve.hxx>
__FILE__, OCC29430, group);
theCommands.Add("OCC29531", "OCC29531 <step file name>", __FILE__, OCC29531, group);
+ theCommands.Add ("OCC29064", "OCC29064: test memory usage by copying empty maps", __FILE__, OCC29064, group);
return;
}
--- /dev/null
+puts "========"
+puts " 0029064: Copying of empty NCollection map takes excessive memory"
+puts "========"
+puts ""
+
+pload QAcommands
+
+OCC29064 map
+OCC29064 doublemap
+OCC29064 datamap
+OCC29064 indexedmap
+OCC29064 indexeddatamap