[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: SHOWSTOPPER PATCH: Fix for khtml image cache.
From:       Waldo Bastian <bastian () kde ! org>
Date:       2000-10-15 18:17:40
[Download RAW message or body]

On Sunday 15 October 2000 04:32, you wrote:
> On Sunday 15 October 2000 11:31, you wrote:
> > The following patch makes the flush part of the khtml image cache
> > functional. This prevents an ever growing accummulation of image pixmaps
> > on the X server.
>
> I couldn't find any attachment...?
>
> Bye,
> 		Maarten

*mumble*
-- 
KDE/Linux, you make the choice.

["loader.diff" (text/english)]

? loader.diff
Index: loader.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/misc/loader.cpp,v
retrieving revision 1.49
diff -u -r1.49 loader.cpp
--- loader.cpp	2000/09/17 03:46:23	1.49
+++ loader.cpp	2000/10/15 07:25:11
@@ -24,15 +24,12 @@
 */
 
 //#undef CACHE_DEBUG
-//#define CACHE_DEBUG
+#define CACHE_DEBUG
 
 #include "loader.h"
 
 // up to which size is a picture for sure cacheable
 #define MAXCACHEABLE 40*1024
-// max. size of a single picture in percent of the total cache size
-// to be cacheable
-#define MAXPERCENT 10
 // default cache size
 #define DEFCACHESIZE 512*1024
 // maximum number of files the loader will try to load in parallel
@@ -59,12 +56,12 @@
 
 void CachedObject::computeStatus()
 {
-    if( m_size > MAXCACHEABLE || m_size > Cache::size()/MAXPERCENT )
+    if( m_size > MAXCACHEABLE )
     {
         m_status = Uncacheable;
-        m_size = 0;
+        Cache::flush(true); // Force flush.
     }
-   else
+    else
         m_status = Cached;
 }
 
@@ -115,6 +112,8 @@
 void CachedCSSStyleSheet::data( QBuffer &buffer, bool eof )
 {
     if(!eof) return;
+    m_size = buffer.buffer().size();
+
     buffer.close();
     buffer.open( IO_ReadOnly );
     QTextStream t( &buffer );
@@ -188,6 +187,7 @@
 
     m_script = DOMString(data);
     loading = false;
+    m_size = buffer.buffer().size();
 
     checkNotify();
 }
@@ -651,8 +651,6 @@
         imgSource->setEOF(eof);
     }
 
-    m_size = _buffer.size();
-
     if(eof)
     {
         // QMovie currently doesn't support all kinds of image formats
@@ -665,7 +663,6 @@
 #endif
             p = new QPixmap( _buffer.buffer() );
             // set size of image.
-            m_size = p->width() * p->height() * p->depth() / 8;
 #ifdef CACHE_DEBUG
             kdDebug(6060) << "CachedImage::data(): image is null: " << p->isNull() \
<< endl;  #endif
@@ -677,13 +674,16 @@
 
         computeStatus();
     }
+
+    QSize s = pixmap_size();
+    m_size = s.width() * s.height() * 2;
 }
 
 
 void CachedImage::error( int /*err*/, const char */*text*/ )
 {
 #ifdef CACHE_DEBUG
-    kdDebug(6060) << "CahcedImage::error" << endl;
+    kdDebug(6060) << "CachedImage::error" << endl;
 #endif
 
     clear();
@@ -931,7 +931,7 @@
 Loader *Cache::m_loader = 0;
 
 int Cache::maxSize = DEFCACHESIZE;
-int Cache::actSize = 0;
+int Cache::flushCount = 0;
 
 QPixmap *Cache::nullPixmap = 0;
 
@@ -957,7 +957,6 @@
     if(!cache)
     {
         cache = new QDict<CachedObject>(401, true);
-        cache->setAutoDelete(true);
     }
     if(!lru)
     {
@@ -972,6 +971,11 @@
 
 void Cache::clear()
 {
+#ifdef CACHE_DEBUG
+    kdDebug( 6060 ) << "Cache: CLEAR!" << endl;
+#endif
+    statistics();
+    cache->setAutoDelete( true );
     delete cache; cache = 0;
     delete lru;   lru = 0;
     delete nullPixmap; nullPixmap = 0;
@@ -1108,10 +1112,13 @@
     return static_cast<CachedScript *>(o);
 }
 
-void Cache::flush()
+void Cache::flush(bool force)
 {
-    CachedObject *o;
-    QString url;
+    if (force) 
+       flushCount = 0;
+    // Don't flush for every image.
+    if (!lru || (lru->count() < flushCount)) 
+       return;
 
     init();
 
@@ -1119,21 +1126,34 @@
     statistics();
     kdDebug( 6060 ) << "Cache: flush()" << endl;
 #endif
-    if( actSize < maxSize ) return;
+    
+    int cacheSize = 0;
 
-    for ( QStringList::Iterator it = lru->begin(); it != lru->end(); ++it )
+    for ( QStringList::Iterator it = lru->fromLast(); it != lru->end(); )
     {
-        o = cache->find( *it );
-        if( !o->canDelete() || o->status() == CachedObject::Persistent )
-            continue; // image is still used or cached permanently
+        QString url = *it;
+        --it; // Update iterator, we might delete the current entry later on.
+        CachedObject *o = cache->find( url );
+
+        if( o->status() != CachedObject::Uncacheable )
+        {
+           cacheSize += o->size();
+           if( !o->canDelete() || o->status() == CachedObject::Persistent )
+               continue; // image is still used or cached permanently
+
+           if( cacheSize < maxSize ) 
+               continue;
+        }
 
-        kdDebug( 6060 ) << "Cache: removing " << url << endl;
-        actSize -= o->size();
+        o->setFree( true );
+
         lru->remove( url );
         cache->remove( url );
-        if( actSize < maxSize ) break;
-    }
 
+        if ( o->canDelete() )
+           delete o;
+    }
+    flushCount = lru->count()+10; // Flush again when the cache has grown.
 #ifdef CACHE_DEBUG
     statistics();
 #endif
@@ -1143,7 +1163,8 @@
 {
     maxSize = bytes;
     // may be we need to clear parts of the cache
-    flush();
+    flushCount = 0;
+    flush(true);
 }
 
 void Cache::statistics()
@@ -1174,8 +1195,8 @@
             if(o->type() == CachedObject::CSSStyleSheet)
                 stylesheets++;
 
-            size += o->size();
         }
+        size += o->size();
     }
     size /= 1024;
 
@@ -1185,7 +1206,6 @@
     kdDebug( 6060 ) << "Number of cached images: " << cache->count()-movie << endl;
     kdDebug( 6060 ) << "Number of cached movies: " << movie << endl;
     kdDebug( 6060 ) << "Number of cached stylesheets: " << stylesheets << endl;
-    kdDebug( 6060 ) << "calculated allocated space approx. " << actSize/1024 << " \
                kB" << endl;
     kdDebug( 6060 ) << "pixmaps:   allocated space approx. " << size << " kB" << \
                endl;
     kdDebug( 6060 ) << "movies :   allocated space approx. " << msize/1024 << " kB" \
                << endl;
     kdDebug( 6060 ) << \
"--------------------------------------------------------------------" << endl; @@ \
-1212,35 +1232,12 @@  // this indicates the deref() method of CachedObject to delete \
itself when the reference counter  // drops down to zero
   object->setFree( true );
-
-  // if the object is still referenced, then don't really kill it but let it get \
                killed
-  // when its reference counter drops down to zero
-  if ( !object->canDelete() )
-  {
-#ifdef CACHE_DEBUG
-    kdDebug( 6060 ) << "cache object for " << key << " is still referenced. Killing \
                it softly..." << endl;
-#endif
-    cache->setAutoDelete( false );
-  }
 
+  cache->remove( key );
+  lru->remove( key );
 
-  if ( cache->remove( key ) )
-  {
-#ifdef CACHE_DEBUG
-    kdDebug( 6060 ) << "removed cache entry for " << key << " from cache dict" << \
                endl;
-#endif
-   }
-
-  cache->setAutoDelete( true );
-
-  LRUList::Iterator it = lru->find( key );
-  if ( it != lru->end() )
-  {
-    lru->remove( it );
-#ifdef CACHE_DEBUG
-    kdDebug( 6060 ) << "removed cache entry for " << key << " from lru" << endl;
-#endif
-  }
+  if ( object->canDelete() )
+     delete object;
 }
 
 void Cache::autoloadImages( bool enable )
Index: loader.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/misc/loader.h,v
retrieving revision 1.19
diff -u -r1.19 loader.h
--- loader.h	2000/09/16 03:48:51	1.19
+++ loader.h	2000/10/15 07:25:14
@@ -384,7 +384,7 @@
 	static void statistics();
 
 	/** clean up cache */
-	static void flush();
+	static void flush(bool force=false);
 
 	/**
 	 * clears the cache
@@ -427,7 +427,7 @@
 	static LRUList *lru;
 
 	static int maxSize;
-	static int actSize;
+	static int flushCount;
 
 	static Loader *m_loader;
 



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic