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

List:       kde-core-devel
Subject:    PATCH SlaveBase::listEntry() faster dir listing
From:       aleXXX <alexander.neundorf () gmx ! net>
Date:       2002-05-26 0:36:10
[Download RAW message or body]

Hi,

I noticed that when changing with konqy into qt-copy/doc/html, sorting the 
dir once takes 2.2 seconds. It gets sorted after every chunk of incoming file 
items. Sometimes it happens that I get 1100 items at once (i.e. 2.2 seconds 
sorting) and then the rest of 150 item in the second chunk (again 2 seconds 
sorting). 
So I tuned the calculation of listEntryCurrentSize a little bit so that this 
shouldn't happen anymore (at least less probably).
I check whether all remaining items may arrive within maximum_updatetime, if 
this is true, listEntryCurrentSize is set big enough to take them all.
If we are below min_updatetime, I calculate how much items might arrive 
within min_updatetime and take twice as much (200 ms is still fast enough).

The patch makes e.g. listing of qt-copy/doc/html on my system noticable 
faster. It assumes that totalSize() is always  called before the first 
listEntry().

Bye
Alex

(the patch also contains the changed signal handler)


["slavebase.h.diff" (text/x-diff)]

Index: slavebase.h
===================================================================
RCS file: /home/kde/kdelibs/kio/kio/slavebase.h,v
retrieving revision 1.77
diff -b -u -p -r1.77 slavebase.h
--- slavebase.h	2002/04/30 23:42:07	1.77
+++ slavebase.h	2002/05/26 00:32:52
@@ -766,6 +766,15 @@ public:
     MetaData mOutgoingMetaData;
     MetaData mIncomingMetaData;
 
+    /** If your ioslave was killed by a signal, wasKilled() returns true.
+     Check it regularly in lengthy functions (e.g. in get();) and return
+     as fast as possible from this function if wasKilled() returns true.
+     This will ensure that your slave destructor will be called correctly.
+     */
+    bool wasKilled() const;
+    /** Internally used.
+     */
+    void setKillFlag();
 private:
     bool storeAuthInfo( const QCString&, const QCString&, const AuthInfo& );
 

["slavebase.cpp.diff" (text/x-diff)]

Index: slavebase.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/kio/slavebase.cpp,v
retrieving revision 1.123
diff -b -u -p -r1.123 slavebase.cpp
--- slavebase.cpp	2002/03/31 03:19:26	1.123
+++ slavebase.cpp	2002/05/26 00:33:05
@@ -104,10 +104,13 @@ public:
     bool resume:1;
     bool needSendCanResume:1;
     bool multipleAuthCaching:1;
+    bool onHold:1;
+    bool wasKilled:1;
+    KIO::filesize_t totalSize;
+    KIO::filesize_t sentListEntries;
     MetaData configData;
     SlaveBaseConfig *config;
     KURL onHoldUrl;
-    bool onHold;
 
     struct timeval last_tv;
     KIO::filesize_t processed_size;
@@ -117,6 +120,16 @@ public:
 
 SlaveBase *globalSlave=0;
 
+void sigalarm_handler(int sigNumber)
+{
+   signal(sigNumber,SIG_IGN);
+   //I don't think we can have the same problem here as in the sigsegv handler
+   kdDebug()<<"kioslave : exiting due alarm signal "<<endl;
+   exit(2);
+};
+
+
+
 void genericsig_handler(int sigNumber)
 {
    signal(sigNumber,SIG_IGN);
@@ -124,8 +137,11 @@ void genericsig_handler(int sigNumber)
    kdDebug()<<"kioslave : exiting due to signal "<<sigNumber<<endl;
    //call the dtor of the slave and exit
    if (globalSlave!=0)
-      globalSlave->~SlaveBase();
-   exit(2);
+      globalSlave->setKillFlag();
+	signal(SIGALRM,&sigalarm_handler);
+   alarm(5);  //generate an alarm signal in 5 seconds, in this time the slave has to \
exit +//      globalSlave->~SlaveBase();
+//   exit(2);
 };
 
 //////////////
@@ -187,6 +203,9 @@ SlaveBase::SlaveBase( const QCString &pr
     d->last_tv.tv_sec = 0;
     d->last_tv.tv_usec = 0;
     d->processed_size = 0;
+    d->wasKilled=false;
+    d->totalSize=0;
+    d->sentListEntries=0;
 
     connectSlave(mAppSocket);
 }
@@ -206,8 +225,10 @@ void SlaveBase::dispatchLoop()
 
     assert(appconn->inited());
     FD_SET(appconn->fd_from(), &rfds);
-
-    retval = select(appconn->fd_from()+ 1, &rfds, NULL, NULL, 0);
+    struct timeval tv;
+    tv.tv_sec = 0;
+    tv.tv_usec = 500*1000; // 0.5 seconds
+    retval = select(appconn->fd_from()+ 1, &rfds, NULL, NULL, &tv);
     //kdDebug(7019) << "dispatchLoop(): select returned " << retval << endl;
     if (retval && FD_ISSET(appconn->fd_from(), &rfds))
     { // dispatch application messages
@@ -235,11 +256,19 @@ void SlaveBase::dispatchLoop()
     }
     else
     {
+       if (retval<0)
+       {
        kdDebug(7019) << "dispatchLoop(): select returned " << retval << " "
                      << \
(errno==EBADF?"EBADF":errno==EINTR?"EINTR":errno==EINVAL?"EINVAL":errno==ENOMEM?"ENOMEM":"unknown")
  << " (" << errno << ")" << endl;
        return;
     }
+       if (wasKilled())
+       {
+          kdDebug(7019)<<" dispatchLoop() slave was killed, returning"<<endl;
+          return;
+       };
+    }
   }
 }
 
@@ -323,6 +352,10 @@ void SlaveBase::error( int _errid, const
     KIO_DATA << _errid << _text;
 
     m_pConnection->send( MSG_ERROR, data );
+    //reset
+    listEntryCurrentSize = 100;
+    d->sentListEntries=0;
+    d->totalSize=0;
 }
 
 void SlaveBase::connected()
@@ -339,6 +372,8 @@ void SlaveBase::finished()
 
     // reset
     listEntryCurrentSize = 100;
+    d->sentListEntries=0;
+    d->totalSize=0;
 }
 
 void SlaveBase::needSubURLData()
@@ -365,6 +400,13 @@ void SlaveBase::totalSize( KIO::filesize
 {
     KIO_DATA << KIO_FILESIZE_T(_bytes);
     m_pConnection->send( INF_TOTAL_SIZE, data );
+    //this one is usually called before the first item is listed in listDir()
+    struct timeval tp;
+    gettimeofday(&tp, 0);
+    listEntry_sec = tp.tv_sec;
+    listEntry_usec = tp.tv_usec;
+    d->totalSize=_bytes;
+    d->sentListEntries=0;
 }
 
 void SlaveBase::processedSize( KIO::filesize_t _bytes )
@@ -517,19 +559,40 @@ void SlaveBase::listEntry( const UDSEntr
 
             gettimeofday(&tp, 0);
 
+            int opt=0;
+
             long diff = ((tp.tv_sec - listEntry_sec) * 1000000 +
                          tp.tv_usec - listEntry_usec) / 1000;
+            if (diff==0) diff=1;
 
             if (diff > maximum_updatetime) {
                 listEntryCurrentSize = listEntryCurrentSize * 3 / 4;
                 _ready = true;
-            } else if (diff < minimum_updatetime) {
-                listEntryCurrentSize = listEntryCurrentSize * 5 / 4;
+                opt=0;
             } else {
-                _ready = true;
+//if we can send all list entries of this dir which have not yet been sent
+//within maximum_updatetime, then make listEntryCurrentSize big enough for all of \
them +               if ((pendingListEntries.count()*maximum_updatetime/diff) <= \
(d->totalSize-d->sentListEntries)) +               {
+                  listEntryCurrentSize=d->totalSize-d->sentListEntries+1;
+                  opt=1;
+               }
+//if we are below minimum_updatetime, estimate how much we will get within
+//minimum_updatetime and take twice as much :-)
+               else if (diff < minimum_updatetime)
+               {
+                  listEntryCurrentSize = 2 * pendingListEntries.count() * \
minimum_updatetime / diff; +                  opt=2;
             }
+               else
+               {
+                  _ready=true;
+                  opt=3;
+               };
         }
+            fprintf(stderr,"SlaveBase::listEntry() diff: %d count: %d currSize: %d \
ready: %d opt: %d\n",diff,pendingListEntries.count(),listEntryCurrentSize,(_ready?1:0),opt);
  }
+    }
 
     if (_ready) { // may happen when we started with !ready
     gettimeofday(&tp, 0);
@@ -544,12 +607,14 @@ void SlaveBase::listEntry( const UDSEntr
 
 void SlaveBase::listEntries( const UDSEntryList& list )
 {
+   fprintf(stderr,"SlaveBase::listEntries() %d \n",list.count());
     KIO_DATA << (uint)list.count();
     UDSEntryListConstIterator it = list.begin();
     UDSEntryListConstIterator end = list.end();
     for (; it != end; ++it)
       stream << *it;
     m_pConnection->send( MSG_LIST_ENTRIES, data);
+    d->sentListEntries+=(uint)list.count();
 }
 
 void SlaveBase::sendAuthenticationKey( const QCString& key,
@@ -1266,6 +1331,17 @@ int SlaveBase::readTimeout()
        return result;
     return DEFAULT_READ_TIMEOUT;
 }
+
+bool SlaveBase::wasKilled() const
+{
+   return d->wasKilled;
+};
+
+void SlaveBase::setKillFlag()
+{
+   d->wasKilled=true;
+};
+
 
 void SlaveBase::virtual_hook( int, void* )
 { /*BASE::virtual_hook( id, data );*/ }



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

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