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

List:       kde-core-devel
Subject:    Re: Fast mimetype lookup could be faster
From:       David Smith <dsmith () algonet ! se>
Date:       2001-12-08 23:22:55
[Download RAW message or body]

Waldo Bastian wrote:
> 
> On Wednesday 05 December 2001 11:03 pm, David Smith wrote:
> 
> To answer your question: when ksycoca changes, the factory gets deleted and
> recreated when first used.
> 
Sorry for the late reply!

I'll admit I don't quite understand this. Does it mean that making the 
"cached" pattern list a member variable solves the problem? (That is
what the attached patch does.)

> 
> Looking at the numbers, it seems that these 30 "other" patterns cause the
> biggest problems. What about reading those once into a QStringList in the
> factory constructor and getting rid of the QFile::encodeName's in
> KStringHandler::matchFilename()? That should solve the bulk of the problem,
> wouldn't it?
> 

Yes it would. IMHO, you'd get the problems (if any) of using a cached
list without getting the full benefit, but it certainly would solve most
of the problem. So, what do you think of the following patch?
All it does now is read the "other" patterns into a member string list
and read from there later. (Oh, and then it tries to sneak in a mode 
line for vim at the end :-)

/David
["kservicetypefactory.h.diff" (text/plain)]

Index: kservicetypefactory.h
===================================================================
RCS file: /home/kde/kdelibs/kio/kservicetypefactory.h,v
retrieving revision 1.14
diff -u -r1.14 kservicetypefactory.h
--- kservicetypefactory.h	2001/06/21 00:05:11	1.14
+++ kservicetypefactory.h	2001/12/08 14:31:07
@@ -23,6 +23,7 @@
 #include <assert.h>
 
 #include <qstringlist.h>
+#include <qvaluevector.h>
 
 #include "ksycocafactory.h"
 #include "kmimetype.h"
@@ -102,10 +103,15 @@
 
 private:
   static KServiceTypeFactory *_self;
+
 protected:
   int m_fastPatternOffset;
   int m_otherPatternOffset;
   QMap<QString,int> m_propertyTypeDict;
+
+private:
+  QStringList m_patterns;
+  QValueVector<Q_INT32> m_pattern_offsets;
 };
 
 #endif


["kservicetypefactory.cpp.diff" (text/plain)]

--- kservicetypefactory.cpp.org	Thu Dec  6 18:02:24 2001
+++ kservicetypefactory.cpp	Sat Dec  8 15:27:28 2001
@@ -30,6 +30,8 @@
 #include <kstringhandler.h>
 #include <qfile.h>
 
+#include <qvaluevector.h>
+
 KServiceTypeFactory::KServiceTypeFactory()
  : KSycocaFactory( KST_KServiceTypeFactory )
 {
@@ -118,9 +120,7 @@
 
    Q_INT32 fastOffset =  str->device()->at( );
 
-   QString pattern;
-   Q_INT32 mimetypeOffset;
-   KServiceType * newServiceType = 0L;
+   Q_INT32 matchingOffset = 0;
 
    // Let's go for a binary search in the "fast" pattern index
    Q_INT32 left = 0;
@@ -128,11 +128,13 @@
    Q_INT32 middle;
    // Extract extension
    int lastDot = _filename.findRev('.');
-   if (lastDot != -1) // if no '.', skip the extension lookup
+   int ext_len = _filename.length() - lastDot - 1;
+   if (lastDot != -1 && ext_len <= 4) // if no '.', skip the extension lookup
    {
-      QString extension = _filename.right( _filename.length() - _filename.findRev('.') - 1 );
+      QString extension = _filename.right( ext_len );
       extension = extension.leftJustify(4);
 
+      QString pattern;
       while (left <= right) {
          middle = (left + right) / 2;
          // read pattern at position "middle"
@@ -143,10 +145,7 @@
             left = middle + 1;
          else if (cmp == 0) // found
          {
-            assert( newServiceType == 0L );
-            (*str) >> mimetypeOffset;
-            newServiceType = createEntry(mimetypeOffset);
-            assert (newServiceType && newServiceType->isType( KST_KMimeType ));
+            (*str) >> matchingOffset;
             // don't return newServiceType - there may be an "other" pattern that
             // matches best this file, like *.tar.bz
             break; // but get out of the fast patterns
@@ -157,23 +156,45 @@
    }
 
    // Now try the "other" Pattern table
-   str->device()->at( m_otherPatternOffset );
+   if ( m_patterns.size() == 0 ) {
+      str->device()->at( m_otherPatternOffset );
 
-   while (true)
+      QString pattern;
+      Q_INT32 mimetypeOffset;
+
+      while (true)
+      {
+         (*str) >> pattern;
+         if (pattern.isEmpty()) // end of list
+            break;
+         (*str) >> mimetypeOffset;
+         m_patterns.push_back( pattern );
+         m_pattern_offsets.push_back( mimetypeOffset );
+      }
+   }
+
+   assert( m_patterns.size() == m_pattern_offsets.size() );
+
+   QStringList::const_iterator it = m_patterns.begin();
+   QStringList::const_iterator end = m_patterns.end();
+   QValueVector<Q_INT32>::const_iterator it_offset = m_pattern_offsets.begin();
+   
+   for ( ; it != end; ++it, ++it_offset )
    {
-      (*str) >> pattern;
-      if (pattern.isEmpty()) // end of list
-          return (KMimeType *) newServiceType; // return what we got (0L or real one)
-      (*str) >> mimetypeOffset;
-      if ( KStringHandler::matchFilename( _filename, pattern ) )
+      if ( KStringHandler::matchFilename( _filename, *it ) )
       {
-         if (newServiceType) // we got one, but it's not good enough (like *.bz for a tar.bz file)
-             delete newServiceType;
-         newServiceType = createEntry(mimetypeOffset);
-         assert (newServiceType && newServiceType->isType( KST_KMimeType ));
-         return (KMimeType *) newServiceType;
+         matchingOffset = *it_offset;
+         break;
       }
    }
+
+   if ( matchingOffset ) {
+      KServiceType *newServiceType = createEntry( matchingOffset );
+      assert (newServiceType && newServiceType->isType( KST_KMimeType ));
+      return (KMimeType *) newServiceType;
+   }
+   else
+      return 0;
 }
 
 KMimeType::List KServiceTypeFactory::allMimeTypes()
@@ -258,3 +279,5 @@
 }
 
 KServiceTypeFactory *KServiceTypeFactory::_self = 0;
+
+// vim: ts=3 sw=3 et



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

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