added an extremely simple cell attr cache (yet it catches 80% of acccesses)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5974 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -134,6 +134,7 @@ public:
|
|||||||
// it until the matching DecRef() is called
|
// it until the matching DecRef() is called
|
||||||
void IncRef() { m_nRef++; }
|
void IncRef() { m_nRef++; }
|
||||||
void DecRef() { if ( !--m_nRef ) delete this; }
|
void DecRef() { if ( !--m_nRef ) delete this; }
|
||||||
|
void SafeIncRef() { if ( this ) IncRef(); }
|
||||||
void SafeDecRef() { if ( this ) DecRef(); }
|
void SafeDecRef() { if ( this ) DecRef(); }
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
@@ -1026,6 +1027,27 @@ protected:
|
|||||||
// doesn't have any yet or the existing one if it does
|
// doesn't have any yet or the existing one if it does
|
||||||
//
|
//
|
||||||
// DecRef() must be called on the returned pointer, as usual
|
// DecRef() must be called on the returned pointer, as usual
|
||||||
|
wxGridCellAttr *GetOrCreateCellAttr(int row, int col) const;
|
||||||
|
|
||||||
|
// cell attribute cache (currently we only cache 1, may be will do
|
||||||
|
// more/better later)
|
||||||
|
struct CachedAttr
|
||||||
|
{
|
||||||
|
int row, col;
|
||||||
|
wxGridCellAttr *attr;
|
||||||
|
} m_attrCache;
|
||||||
|
|
||||||
|
// invalidates the attribute cache
|
||||||
|
void ClearAttrCache();
|
||||||
|
|
||||||
|
// adds an attribute to cache
|
||||||
|
void CacheAttr(int row, int col, wxGridCellAttr *attr) const;
|
||||||
|
|
||||||
|
// looks for an attr in cache, returns TRUE if found
|
||||||
|
bool LookupAttr(int row, int col, wxGridCellAttr **attr) const;
|
||||||
|
|
||||||
|
// looks for the attr in cache, if not found asks the table and caches the
|
||||||
|
// result
|
||||||
wxGridCellAttr *GetCellAttr(int row, int col) const;
|
wxGridCellAttr *GetCellAttr(int row, int col) const;
|
||||||
|
|
||||||
wxGridCellCoordsArray m_cellsExposed;
|
wxGridCellCoordsArray m_cellsExposed;
|
||||||
|
@@ -180,7 +180,15 @@ private:
|
|||||||
#define WXGRID_DRAW_LINES 1
|
#define WXGRID_DRAW_LINES 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
// ----------------------------------------------------------------------------
|
||||||
|
// globals
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//#define DEBUG_ATTR_CACHE
|
||||||
|
#ifdef DEBUG_ATTR_CACHE
|
||||||
|
static size_t gs_nAttrCacheHits = 0;
|
||||||
|
static size_t gs_nAttrCacheMisses = 0;
|
||||||
|
#endif // DEBUG_ATTR_CACHE
|
||||||
|
|
||||||
wxGridCellCoords wxGridNoCellCoords( -1, -1 );
|
wxGridCellCoords wxGridNoCellCoords( -1, -1 );
|
||||||
wxRect wxGridNoCellRect( -1, -1, -1, -1 );
|
wxRect wxGridNoCellRect( -1, -1, -1, -1 );
|
||||||
@@ -1249,6 +1257,16 @@ wxGrid::wxGrid( wxWindow *parent,
|
|||||||
|
|
||||||
wxGrid::~wxGrid()
|
wxGrid::~wxGrid()
|
||||||
{
|
{
|
||||||
|
ClearAttrCache();
|
||||||
|
|
||||||
|
#ifdef DEBUG_ATTR_CACHE
|
||||||
|
size_t total = gs_nAttrCacheHits + gs_nAttrCacheMisses;
|
||||||
|
wxPrintf(_T("wxGrid attribute cache statistics: "
|
||||||
|
"total: %u, hits: %u (%u%%)\n"),
|
||||||
|
total, gs_nAttrCacheHits,
|
||||||
|
total ? (gs_nAttrCacheHits*100) / total : 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
delete m_defaultRenderer;
|
delete m_defaultRenderer;
|
||||||
delete m_table;
|
delete m_table;
|
||||||
}
|
}
|
||||||
@@ -1345,6 +1363,9 @@ void wxGrid::Init()
|
|||||||
|
|
||||||
m_labelTextColour = wxColour( _T("BLACK") );
|
m_labelTextColour = wxColour( _T("BLACK") );
|
||||||
|
|
||||||
|
// init attr cache
|
||||||
|
m_attrCache.row = -1;
|
||||||
|
|
||||||
// TODO: something better than this ?
|
// TODO: something better than this ?
|
||||||
//
|
//
|
||||||
m_labelFont = this->GetFont();
|
m_labelFont = this->GetFont();
|
||||||
@@ -4665,11 +4686,9 @@ wxGridCellRenderer *wxGrid::GetCellRenderer(int row, int col)
|
|||||||
// access to cell attributes
|
// access to cell attributes
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// TODO VZ: we must cache the attr to allow only retrieveing it once!
|
|
||||||
|
|
||||||
wxColour wxGrid::GetCellBackgroundColour(int row, int col)
|
wxColour wxGrid::GetCellBackgroundColour(int row, int col)
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = m_table ? m_table->GetAttr(row, col) : NULL;
|
wxGridCellAttr *attr = GetCellAttr(row, col);
|
||||||
|
|
||||||
wxColour colour;
|
wxColour colour;
|
||||||
if ( attr && attr->HasBackgroundColour() )
|
if ( attr && attr->HasBackgroundColour() )
|
||||||
@@ -4684,7 +4703,7 @@ wxColour wxGrid::GetCellBackgroundColour(int row, int col)
|
|||||||
|
|
||||||
wxColour wxGrid::GetCellTextColour( int row, int col )
|
wxColour wxGrid::GetCellTextColour( int row, int col )
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = m_table ? m_table->GetAttr(row, col) : NULL;
|
wxGridCellAttr *attr = GetCellAttr(row, col);
|
||||||
|
|
||||||
wxColour colour;
|
wxColour colour;
|
||||||
if ( attr && attr->HasTextColour() )
|
if ( attr && attr->HasTextColour() )
|
||||||
@@ -4699,7 +4718,7 @@ wxColour wxGrid::GetCellTextColour( int row, int col )
|
|||||||
|
|
||||||
wxFont wxGrid::GetCellFont( int row, int col )
|
wxFont wxGrid::GetCellFont( int row, int col )
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = m_table ? m_table->GetAttr(row, col) : NULL;
|
wxGridCellAttr *attr = GetCellAttr(row, col);
|
||||||
|
|
||||||
wxFont font;
|
wxFont font;
|
||||||
if ( attr && attr->HasFont() )
|
if ( attr && attr->HasFont() )
|
||||||
@@ -4714,7 +4733,7 @@ wxFont wxGrid::GetCellFont( int row, int col )
|
|||||||
|
|
||||||
void wxGrid::GetCellAlignment( int row, int col, int *horiz, int *vert )
|
void wxGrid::GetCellAlignment( int row, int col, int *horiz, int *vert )
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = m_table ? m_table->GetAttr(row, col) : NULL;
|
wxGridCellAttr *attr = GetCellAttr(row, col);
|
||||||
|
|
||||||
if ( attr && attr->HasAlignment() )
|
if ( attr && attr->HasAlignment() )
|
||||||
attr->GetAlignment(horiz, vert);
|
attr->GetAlignment(horiz, vert);
|
||||||
@@ -4746,17 +4765,81 @@ bool wxGrid::CanHaveAttributes()
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxGrid::ClearAttrCache()
|
||||||
|
{
|
||||||
|
if ( m_attrCache.row != -1 )
|
||||||
|
{
|
||||||
|
m_attrCache.attr->SafeDecRef();
|
||||||
|
m_attrCache.row = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxGrid::CacheAttr(int row, int col, wxGridCellAttr *attr) const
|
||||||
|
{
|
||||||
|
wxGrid *self = (wxGrid *)this; // const_cast
|
||||||
|
|
||||||
|
self->ClearAttrCache();
|
||||||
|
self->m_attrCache.row = row;
|
||||||
|
self->m_attrCache.col = col;
|
||||||
|
self->m_attrCache.attr = attr;
|
||||||
|
attr->SafeIncRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxGrid::LookupAttr(int row, int col, wxGridCellAttr **attr) const
|
||||||
|
{
|
||||||
|
if ( row == m_attrCache.row && col == m_attrCache.col )
|
||||||
|
{
|
||||||
|
*attr = m_attrCache.attr;
|
||||||
|
(*attr)->SafeIncRef();
|
||||||
|
|
||||||
|
#ifdef DEBUG_ATTR_CACHE
|
||||||
|
gs_nAttrCacheHits++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_ATTR_CACHE
|
||||||
|
gs_nAttrCacheMisses++;
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wxGridCellAttr *wxGrid::GetCellAttr(int row, int col) const
|
wxGridCellAttr *wxGrid::GetCellAttr(int row, int col) const
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = m_table->GetAttr(row, col);
|
wxGridCellAttr *attr;
|
||||||
if ( !attr )
|
if ( !LookupAttr(row, col, &attr) )
|
||||||
{
|
{
|
||||||
attr = new wxGridCellAttr;
|
attr = m_table ? m_table->GetAttr(row, col) : (wxGridCellAttr *)NULL;
|
||||||
|
CacheAttr(row, col, attr);
|
||||||
|
}
|
||||||
|
|
||||||
// artificially inc the ref count to match DecRef() in caller
|
return attr;
|
||||||
attr->IncRef();
|
}
|
||||||
|
|
||||||
m_table->SetAttr(attr, row, col);
|
wxGridCellAttr *wxGrid::GetOrCreateCellAttr(int row, int col) const
|
||||||
|
{
|
||||||
|
wxGridCellAttr *attr;
|
||||||
|
if ( !LookupAttr(row, col, &attr) || !attr )
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( m_table,
|
||||||
|
_T("we may only be called if CanHaveAttributes() "
|
||||||
|
"returned TRUE and then m_table should be !NULL") );
|
||||||
|
|
||||||
|
attr = m_table->GetAttr(row, col);
|
||||||
|
if ( !attr )
|
||||||
|
{
|
||||||
|
attr = new wxGridCellAttr;
|
||||||
|
|
||||||
|
// artificially inc the ref count to match DecRef() in caller
|
||||||
|
attr->IncRef();
|
||||||
|
|
||||||
|
m_table->SetAttr(attr, row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheAttr(row, col, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return attr;
|
return attr;
|
||||||
@@ -4766,7 +4849,7 @@ void wxGrid::SetCellBackgroundColour( int row, int col, const wxColour& colour )
|
|||||||
{
|
{
|
||||||
if ( CanHaveAttributes() )
|
if ( CanHaveAttributes() )
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = GetCellAttr(row, col);
|
wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
|
||||||
attr->SetBackgroundColour(colour);
|
attr->SetBackgroundColour(colour);
|
||||||
attr->DecRef();
|
attr->DecRef();
|
||||||
}
|
}
|
||||||
@@ -4776,7 +4859,7 @@ void wxGrid::SetCellTextColour( int row, int col, const wxColour& colour )
|
|||||||
{
|
{
|
||||||
if ( CanHaveAttributes() )
|
if ( CanHaveAttributes() )
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = GetCellAttr(row, col);
|
wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
|
||||||
attr->SetTextColour(colour);
|
attr->SetTextColour(colour);
|
||||||
attr->DecRef();
|
attr->DecRef();
|
||||||
}
|
}
|
||||||
@@ -4786,7 +4869,7 @@ void wxGrid::SetCellFont( int row, int col, const wxFont& font )
|
|||||||
{
|
{
|
||||||
if ( CanHaveAttributes() )
|
if ( CanHaveAttributes() )
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = GetCellAttr(row, col);
|
wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
|
||||||
attr->SetFont(font);
|
attr->SetFont(font);
|
||||||
attr->DecRef();
|
attr->DecRef();
|
||||||
}
|
}
|
||||||
@@ -4796,7 +4879,7 @@ void wxGrid::SetCellAlignment( int row, int col, int horiz, int vert )
|
|||||||
{
|
{
|
||||||
if ( CanHaveAttributes() )
|
if ( CanHaveAttributes() )
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = GetCellAttr(row, col);
|
wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
|
||||||
attr->SetAlignment(horiz, vert);
|
attr->SetAlignment(horiz, vert);
|
||||||
attr->DecRef();
|
attr->DecRef();
|
||||||
}
|
}
|
||||||
@@ -4806,7 +4889,7 @@ void wxGrid::SetCellRenderer(int row, int col, wxGridCellRenderer *renderer)
|
|||||||
{
|
{
|
||||||
if ( CanHaveAttributes() )
|
if ( CanHaveAttributes() )
|
||||||
{
|
{
|
||||||
wxGridCellAttr *attr = GetCellAttr(row, col);
|
wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
|
||||||
attr->SetRenderer(renderer);
|
attr->SetRenderer(renderer);
|
||||||
attr->DecRef();
|
attr->DecRef();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user