]> git.saurik.com Git - wxWidgets.git/commitdiff
added an extremely simple cell attr cache (yet it catches 80% of acccesses)
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 11 Feb 2000 20:38:04 +0000 (20:38 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 11 Feb 2000 20:38:04 +0000 (20:38 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5974 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/grid.h
src/generic/grid.cpp

index 8bd6959381ec9698c08629374495405104db4c0c..a6fc79412b6afc3dacb3e043acc7ddc25dc7f4d5 100644 (file)
@@ -134,6 +134,7 @@ public:
     // it until the matching DecRef() is called
     void IncRef() { m_nRef++; }
     void DecRef() { if ( !--m_nRef ) delete this; }
+    void SafeIncRef() { if ( this ) IncRef(); }
     void SafeDecRef() { if ( this ) DecRef(); }
 
     // setters
@@ -1026,6 +1027,27 @@ protected:
     // doesn't have any yet or the existing one if it does
     //
     // 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;
 
     wxGridCellCoordsArray  m_cellsExposed;
index 8f8fcddd873c53aded2744c8958f8acec83cba3a..157ec1f569875cc54aaf2253850e7b93dc5a3d75 100644 (file)
@@ -180,7 +180,15 @@ private:
 #define WXGRID_DRAW_LINES 1
 #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 );
 wxRect           wxGridNoCellRect( -1, -1, -1, -1 );
@@ -1249,6 +1257,16 @@ wxGrid::wxGrid( wxWindow *parent,
 
 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_table;
 }
@@ -1345,6 +1363,9 @@ void wxGrid::Init()
 
     m_labelTextColour = wxColour( _T("BLACK") );
 
+    // init attr cache
+    m_attrCache.row = -1;
+
     // TODO: something better than this ?
     //
     m_labelFont = this->GetFont();
@@ -4665,11 +4686,9 @@ wxGridCellRenderer *wxGrid::GetCellRenderer(int row, int col)
 // access to cell attributes
 // ----------------------------------------------------------------------------
 
-// TODO VZ: we must cache the attr to allow only retrieveing it once!
-
 wxColour wxGrid::GetCellBackgroundColour(int row, int col)
 {
-    wxGridCellAttr *attr = m_table ? m_table->GetAttr(row, col) : NULL;
+    wxGridCellAttr *attr = GetCellAttr(row, col);
 
     wxColour colour;
     if ( attr && attr->HasBackgroundColour() )
@@ -4684,7 +4703,7 @@ wxColour wxGrid::GetCellBackgroundColour(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;
     if ( attr && attr->HasTextColour() )
@@ -4699,7 +4718,7 @@ wxColour wxGrid::GetCellTextColour( 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;
     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 )
 {
-    wxGridCellAttr *attr = m_table ? m_table->GetAttr(row, col) : NULL;
+    wxGridCellAttr *attr = GetCellAttr(row, col);
 
     if ( attr && attr->HasAlignment() )
         attr->GetAlignment(horiz, vert);
@@ -4746,17 +4765,81 @@ bool wxGrid::CanHaveAttributes()
     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 *attr = m_table->GetAttr(row, col);
-    if ( !attr )
+    wxGridCellAttr *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
-        attr->IncRef();
+    return attr;
+}
+
+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);
+        }
 
-        m_table->SetAttr(attr, row, col);
+        CacheAttr(row, col, attr);
     }
 
     return attr;
@@ -4766,7 +4849,7 @@ void wxGrid::SetCellBackgroundColour( int row, int col, const wxColour& colour )
 {
     if ( CanHaveAttributes() )
     {
-        wxGridCellAttr *attr = GetCellAttr(row, col);
+        wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
         attr->SetBackgroundColour(colour);
         attr->DecRef();
     }
@@ -4776,7 +4859,7 @@ void wxGrid::SetCellTextColour( int row, int col, const wxColour& colour )
 {
     if ( CanHaveAttributes() )
     {
-        wxGridCellAttr *attr = GetCellAttr(row, col);
+        wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
         attr->SetTextColour(colour);
         attr->DecRef();
     }
@@ -4786,7 +4869,7 @@ void wxGrid::SetCellFont( int row, int col, const wxFont& font )
 {
     if ( CanHaveAttributes() )
     {
-        wxGridCellAttr *attr = GetCellAttr(row, col);
+        wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
         attr->SetFont(font);
         attr->DecRef();
     }
@@ -4796,7 +4879,7 @@ void wxGrid::SetCellAlignment( int row, int col, int horiz, int vert )
 {
     if ( CanHaveAttributes() )
     {
-        wxGridCellAttr *attr = GetCellAttr(row, col);
+        wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
         attr->SetAlignment(horiz, vert);
         attr->DecRef();
     }
@@ -4806,7 +4889,7 @@ void wxGrid::SetCellRenderer(int row, int col, wxGridCellRenderer *renderer)
 {
     if ( CanHaveAttributes() )
     {
-        wxGridCellAttr *attr = GetCellAttr(row, col);
+        wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
         attr->SetRenderer(renderer);
         attr->DecRef();
     }