[Libreoffice] [PATCH] removing mpNotes field from ScBaseCell
Noel Grandin
noelgrandin at gmail.com
Sat Dec 17 08:34:38 PST 2011
Hi
So I've been working on this patch to move mpNotes from ScBaseCell to
ScTable, and I got it mostly working.
But I was struggling with leaks and getting the lifecycle of the notes
to exactly match the lifecycle of the ScBaseCell object.
So then I had a weird idea - how about if I tied the lifecycles
together implicitly?
So I came up with this patch.
It compiles, and passes a make check.
I'll do a memcheck run on Monday when I can get access to my other
machine with tons of memory.
Regards, Noel Grandin
-------------- next part --------------
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
old mode 100644
new mode 100755
index fa1b719..1755591
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -122,11 +122,11 @@ public:
inline void SetScriptType( sal_uInt8 nNew ) { nScriptType = nNew; }
/** Returns true, if the cell contains a note. */
- inline bool HasNote() const { return mpNote != 0; }
+ bool HasNote() const;
/** Returns the pointer to a cell note object (read-only). */
- inline const ScPostIt* GetNote() const { return mpNote; }
+ const ScPostIt* GetNote() const;
/** Returns the pointer to a cell note object. */
- inline ScPostIt* GetNote() { return mpNote; }
+ ScPostIt* GetNote();
/** Takes ownership of the passed cell note object. */
void TakeNote( ScPostIt* pNote );
/** Returns and forgets the own cell note object. Caller takes ownership! */
@@ -169,7 +169,6 @@ private:
ScBaseCell& operator=( const ScBaseCell& );
private:
- ScPostIt* mpNote; /// The cell note. Cell takes ownership!
SvtBroadcaster* mpBroadcaster; /// Broadcaster for changed values. Cell takes ownership!
protected:
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
old mode 100644
new mode 100755
index 6cc8209..04aae8c
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -82,10 +82,16 @@ IMPL_FIXEDMEMPOOL_NEWDEL( ScStringCell, nMemPoolStringCell, nMemPoolStringCell
IMPL_FIXEDMEMPOOL_NEWDEL( ScNoteCell, nMemPoolNoteCell, nMemPoolNoteCell )
#endif
+/**
+ * The notes map. Because only a handful of notes typically exist in an application, but there can be millions
+ * of cells, we don't want to store this on the cell itself
+ */
+typedef ::std::map<const ScBaseCell*, ScPostIt*> ScNotesMap;
+static ScNotesMap notesMap;
+
// ============================================================================
ScBaseCell::ScBaseCell( CellType eNewType ) :
- mpNote( 0 ),
mpBroadcaster( 0 ),
nTextWidth( TEXTWIDTH_DIRTY ),
eCellType( sal::static_int_cast<sal_uInt8>(eNewType) ),
@@ -94,7 +100,6 @@ ScBaseCell::ScBaseCell( CellType eNewType ) :
}
ScBaseCell::ScBaseCell( const ScBaseCell& rCell ) :
- mpNote( 0 ),
mpBroadcaster( 0 ),
nTextWidth( rCell.nTextWidth ),
eCellType( rCell.eCellType ),
@@ -104,7 +109,12 @@ ScBaseCell::ScBaseCell( const ScBaseCell& rCell ) :
ScBaseCell::~ScBaseCell()
{
- delete mpNote;
+ ScNotesMap::iterator it = notesMap.find(this);
+ if (it != notesMap.end()) {
+ ScPostIt *pNote = it->second;
+ notesMap.erase(this);
+ delete pNote;
+ }
delete mpBroadcaster;
OSL_ENSURE( eCellType == CELLTYPE_DESTROYED, "BaseCell Destructor" );
}
@@ -244,12 +254,14 @@ ScBaseCell* ScBaseCell::CloneWithoutNote( ScDocument& rDestDoc, const ScAddress&
ScBaseCell* ScBaseCell::CloneWithNote( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
{
ScBaseCell* pNewCell = lclCloneCell( *this, rDestDoc, rDestPos, nCloneFlags );
- if( mpNote )
+ ScNotesMap::iterator it = notesMap.find(this);
+ if (it != notesMap.end())
{
if( !pNewCell )
pNewCell = new ScNoteCell;
bool bCloneCaption = (nCloneFlags & SC_CLONECELL_NOCAPTION) == 0;
- pNewCell->TakeNote( mpNote->Clone( rOwnPos, rDestDoc, rDestPos, bCloneCaption ) );
+ ScPostIt* pNote = it->second;
+ pNewCell->TakeNote( pNote->Clone( rOwnPos, rDestDoc, rDestPos, bCloneCaption ) );
}
return pNewCell;
}
@@ -282,27 +294,63 @@ void ScBaseCell::Delete()
bool ScBaseCell::IsBlank( bool bIgnoreNotes ) const
{
- return (eCellType == CELLTYPE_NOTE) && (bIgnoreNotes || !mpNote);
+ return (eCellType == CELLTYPE_NOTE) && (bIgnoreNotes || notesMap.find(this) == notesMap.end());
+}
+
+/** Returns true, if the cell contains a note. */
+bool ScBaseCell::HasNote() const
+{
+ return notesMap.find(this) != notesMap.end();
+}
+
+/** Returns the pointer to a cell note object. */
+ScPostIt* ScBaseCell::GetNote()
+{
+ ScNotesMap::iterator it = notesMap.find(this);
+ return it == notesMap.end() ? 0 : it->second;
+}
+
+/** Returns the pointer to a cell note object (read-only). */
+const ScPostIt* ScBaseCell::GetNote() const
+{
+ ScNotesMap::iterator it = notesMap.find(this);
+ return it == notesMap.end() ? 0 : it->second;
}
void ScBaseCell::TakeNote( ScPostIt* pNote )
{
- delete mpNote;
- mpNote = pNote;
+ ScNotesMap::iterator it = notesMap.find(this);
+ if (it != notesMap.end())
+ {
+ delete it->second;
+ }
+ notesMap[this] = pNote;
}
ScPostIt* ScBaseCell::ReleaseNote()
{
- ScPostIt* pNote = mpNote;
- mpNote = 0;
- return pNote;
+ ScNotesMap::iterator it = notesMap.find(this);
+ if (it != notesMap.end())
+ {
+ ScPostIt* pNote = it->second;
+ notesMap.erase(it);
+ return pNote;
+ }
+ else
+ return 0;
}
void ScBaseCell::DeleteNote()
{
- DELETEZ( mpNote );
+ ScNotesMap::iterator it = notesMap.find(this);
+ if (it != notesMap.end())
+ {
+ ScPostIt* pNote = it->second;
+ notesMap.erase(it);
+ delete pNote;
+ }
}
-
+
void ScBaseCell::TakeBroadcaster( SvtBroadcaster* pBroadcaster )
{
delete mpBroadcaster;
More information about the LibreOffice
mailing list