[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