Bug 121818 - Too many open files with new storage backend.
Summary: Too many open files with new storage backend.
Status: RESOLVED FIXED
Alias: None
Product: akregator
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Debian testing Linux
: NOR normal
Target Milestone: ---
Assignee: kdepim bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-02-12 10:24 UTC by Rex Tsai
Modified: 2006-03-09 17:36 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rex Tsai 2006-02-12 10:24:08 UTC
Version:           3.5.1 (using KDE KDE 3.5.1)
Installed from:    Debian testing/unstable Packages
OS:                Linux

I use akregator for several months to read more than 1024 feeds, the old version of akregator was pretty slow at startup. I know you replaced the backend storage system to metakit, but the new storage system will create 3 metakit files for each feeds, and open the files at the same time when the program startup.

  Yes, the startup time is very quick, but I cannot read the messages anymore, since the program open too many files. Is there any solution to fix that ? Can I change the storage system to old xml format or sqlite ?

  I did not see the sqlite storage system in the codebase, is there any plan to implement sqlite-based storage backend ?
Comment 1 Frank Osterfeld 2006-02-12 21:30:02 UTC
Confirmed, there is a discussion about it on the mailing list:

http://sourceforge.net/mailarchive/forum.php?thread_id=9647734&forum_id=41177

Short version: Yes, the problem is that every feed archive consists of 3 files. We can reduce that for 3.5.2 to two files, which means support for approx. 512 feeds. You can change the limit locally by editing /etc/security/limits.conf (see thread on ml for details)

sqlite/mysql/..: Should be easy to implement, but none of us is working on it currently. Contributions welcome.
Create a second plugin by copying the metakit backend and replace metakit code by SQL queries. 
Comment 2 Rex Tsai 2006-02-13 15:24:54 UTC
Dear Frank,
  I'm interesting about sqlite storage backend, is that working ?  Would you please give me the sqlitestorage-stub.tar.bz2 ? or where can I get the file.

 I have checked out the svn source tree, and looking the new storage model, but it's good if there is an implementation that I can follow.
Comment 3 Frank Osterfeld 2006-03-09 17:36:32 UTC
SVN commit 517018 by osterfeld:

handle tags in metakit backend only if the user has the experimental and unsupported tagging GUI enabled (disabled by 
default). This reduces the number of opened files per feed from 2 to 1, so metakit backend can handle about 1000 feeds
now. And 1000 feeds should be enough for everyone (TM).
BUG: 121818


 M  +8 -4      akregator_part.cpp  
 M  +30 -12    mk4storage/feedstoragemk4impl.cpp  
 M  +1 -0      mk4storage/storagefactorymk4impl.h  
 M  +26 -2     mk4storage/storagemk4impl.cpp  
 M  +2 -0      mk4storage/storagemk4impl.h  


--- branches/KDE/3.5/kdepim/akregator/src/akregator_part.cpp #517017:517018
@@ -144,25 +144,29 @@
     m_storage = 0;
     Backend::StorageFactory* factory = Backend::StorageFactoryRegistry::self()->getFactory(Settings::archiveBackend());
    
+    QStringList storageParams;
+    
+    storageParams.append(QString("taggingEnabled=%1").arg(Settings::showTaggingGUI() ? "true" : "false"));
+    
     if (factory != 0)
     {
         if (factory->allowsMultipleWriteAccess())
         {
-            m_storage = factory->createStorage(QStringList());
+            m_storage = factory->createStorage(storageParams);
         } 
         else
         {
             if (tryToLock(factory->name()))
-                m_storage = factory->createStorage(QStringList());
+                m_storage = factory->createStorage(storageParams);
             else 
-                m_storage = dummyFactory->createStorage(QStringList());
+                m_storage = dummyFactory->createStorage(storageParams);
         }
     }
     
 
     if (!m_storage) // Houston, we have a problem
     {
-        m_storage = Backend::StorageFactoryRegistry::self()->getFactory("dummy")->createStorage(QStringList());
+        m_storage = Backend::StorageFactoryRegistry::self()->getFactory("dummy")->createStorage(storageParams);
 
         KMessageBox::error(parentWidget, i18n("Unable to load storage backend plugin \"%1\". No feeds are archived.").arg(Settings::archiveBackend()), i18n("Plugin error") );
     }
--- branches/KDE/3.5/kdepim/akregator/src/mk4storage/feedstoragemk4impl.cpp #517017:517018
@@ -81,7 +81,8 @@
         c4_Storage* tagStorage;
         c4_View tagView;
         bool autoCommit;
-	    bool modified;
+        bool modified;
+        bool taggingEnabled;
         bool convert;
         QString oldArchivePath;
         c4_StringProp pguid, ptitle, pdescription, plink, pcommentsLink, ptag, pEnclosureType, pEnclosureUrl, pcatTerm, pcatScheme, pcatName;
@@ -133,7 +134,8 @@
     d->autoCommit = main->autoCommit();
     d->url = url;
     d->mainStorage = main;
-
+    d->taggingEnabled = main->taggingEnabled();
+    
     QString url2 = url;
 
     if (url.length() > 255)
@@ -155,12 +157,15 @@
     c4_View hash = d->storage->GetAs("archiveHash[_H:I,_R:I]");
     d->archiveView = d->archiveView.Hash(hash, 1); // hash on guid
 
+    d->tagStorage = 0;
 
-    d->tagStorage = new c4_Storage((filePath + ".mk4___TAGS").local8Bit(), true);
-    d->tagView = d->tagStorage->GetAs("tagIndex[tag:S,taggedArticles[guid:S]]");
-    hash = d->tagStorage->GetAs("archiveHash[_H:I,_R:I]");
-    d->tagView = d->tagView.Hash(hash, 1); // hash on tag
-
+    if (d->taggingEnabled)
+    {
+        d->tagStorage = new c4_Storage((filePath + ".mk4___TAGS").local8Bit(), true);
+        d->tagView = d->tagStorage->GetAs("tagIndex[tag:S,taggedArticles[guid:S]]");
+        hash = d->tagStorage->GetAs("archiveHash[_H:I,_R:I]");
+        d->tagView = d->tagView.Hash(hash, 1); // hash on tag
+    }
     //d->catStorage = new c4_Storage((filePath + ".mk4___CATEGORIES").local8Bit(), true);
     //d->catView = d->catStorage->GetAs("catIndex[catTerm:S,catScheme:S,catName:S,categorizedArticles[guid:S]]");
 }
@@ -169,7 +174,8 @@
 FeedStorageMK4Impl::~FeedStorageMK4Impl()
 {
     delete d->storage;
-    delete d->tagStorage;
+    if (d->taggingEnabled)
+        delete d->tagStorage;
 //    delete d->catStorage;
     delete d; d = 0;
 }
@@ -179,7 +185,8 @@
     if (d->modified)
     {
         d->storage->Commit();
-        d->tagStorage->Commit();
+        if (d->taggingEnabled)
+            d->tagStorage->Commit();
 //        d->catStorage->Commit();
     }
     d->modified = false;
@@ -188,7 +195,8 @@
 void FeedStorageMK4Impl::rollback()
 {
     d->storage->Rollback();
-    d->tagStorage->Rollback();
+    if (d->taggingEnabled)
+        d->tagStorage->Rollback();
 //    d->catStorage->Rollback();
 }
 
@@ -235,7 +243,7 @@
         for (int i = 0; i < size; i++) // fill with guids
             list += QString(d->pguid(d->archiveView.GetAt(i)));
     }
-    else
+    else if (d->taggingEnabled)
     {
         c4_Row tagrow;
         d->ptag(tagrow) = tag.utf8().data();
@@ -620,6 +628,9 @@
 
 void FeedStorageMK4Impl::addTag(const QString& guid, const QString& tag)
 {
+    if (!d->taggingEnabled)
+        return;
+    
     int findidx = findArticle(guid);
     if (findidx == -1)
         return;
@@ -661,6 +672,9 @@
 
 void FeedStorageMK4Impl::removeTag(const QString& guid, const QString& tag)
 {
+    if (!d->taggingEnabled)
+        return;
+    
     int findidx = findArticle(guid);
     if (findidx == -1)
         return;
@@ -705,6 +719,9 @@
 {
     QStringList list;
     
+    if (!d->taggingEnabled)
+        return list;
+    
     if (!guid.isNull()) // return tags for an articles
     {
         int findidx = findArticle(guid);
@@ -812,7 +829,8 @@
 void FeedStorageMK4Impl::clear()
 {
     d->storage->RemoveAll();
-    d->tagStorage->RemoveAll();
+    if (d->taggingEnabled)
+        d->tagStorage->RemoveAll();
     setUnread(0);
     d->modified = true;
 }
--- branches/KDE/3.5/kdepim/akregator/src/mk4storage/storagefactorymk4impl.h #517017:517018
@@ -44,6 +44,7 @@
     virtual Storage* createStorage(const QStringList& params) const;
     virtual bool isConfigurable() const { return false; }
     virtual bool allowsMultipleWriteAccess() const { return false; }
+    
 };
 
 }
--- branches/KDE/3.5/kdepim/akregator/src/mk4storage/storagemk4impl.cpp #517017:517018
@@ -59,11 +59,18 @@
         c4_IntProp punread, ptotalCount, plastFetch;
         QTimer* commitTimer;
         QString archivePath;
-
+        
+        bool taggingEnabled;
+        
         c4_Storage* feedListStorage;
         c4_View feedListView;
 };
 
+bool StorageMK4Impl::taggingEnabled() const
+{
+    return d->taggingEnabled;
+}
+
 void StorageMK4Impl::setArchivePath(const QString& archivePath)
 {
     if (archivePath.isNull()) // if isNull, reset to default
@@ -97,7 +104,24 @@
     delete d;
     d = 0;
 }
-void StorageMK4Impl::initialize(const QStringList&) {}
+void StorageMK4Impl::initialize(const QStringList& params)
+{
+    d->taggingEnabled = false;
+    
+    QStringList::ConstIterator it = params.begin();
+    QStringList::ConstIterator end = params.end();
+    
+    for ( ; it != end; ++it)
+    {
+        QStringList tokens = QStringList::split("=", *it);
+        if (tokens.count() == 2 && *(tokens.at(0)) == "taggingEnabled" 
+            && *(tokens.at(1)) == "true")
+        {
+            d->taggingEnabled = true;
+        }
+        
+    }
+}
 
 bool StorageMK4Impl::open(bool autoCommit)
 {
--- branches/KDE/3.5/kdepim/akregator/src/mk4storage/storagemk4impl.h #517017:517018
@@ -112,6 +112,8 @@
         /** deletes all feed storages in this archive */
         virtual void clear();
         
+        virtual bool taggingEnabled() const;
+        
     protected slots:
         virtual void slotCommit();