[mythtv] mythmusic w/o id3 and setting to limit how often rereads dir

Benjamin Binford mythtv-dev@snowman.net
Mon, 9 Dec 2002 09:33:40 -0500


--neYutvxvOLaeuPCA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Like I said, I'm an idiot :)

On Mon, Dec 09, 2002 at 12:02:02AM -0500, Isaac Richards wrote:
> On Saturday 07 December 2002 06:47 pm, Benjamin Binford wrote:
> > Here's the patch that implements the algorithm below. It works pretty well
> > on my medium-small size mp3 collection (600-700 mp3's), but I'm interested
> > to see how it works for other people. I don't have a gcc 2.x compiler to
> > try it on either so your mileage may vary. All the changes are confined to
> > mythmusic's main.cpp, but if you want to use some of the stuff for your
> > mythvideo maybe we should refactor some of it into libmyth. Feel free to
> > mail me directly if you want to use it- I have some ideas on how to rip it
> > out and make it more general.
> 
> Can you resend and attach it this time? =)
> 
> Isaac
> 
> _______________________________________________
> mythtv-dev mailing list
> mythtv-dev@snowman.net
> http://www.snowman.net/mailman/listinfo/mythtv-dev

-- 
I AM NOT THE NEW DALAI LAMA
I AM NOT THE NEW DALAI LAMA
I AM NOT THE NEW DALAI LAMA
I AM NOT THE NEW DALAI LAMA

	Bart Simpson on chalkboard in episode 5F17

--neYutvxvOLaeuPCA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="startupspeed.patch"

Index: main.cpp
===================================================================
RCS file: /var/lib/cvs/mythmusic/mythmusic/main.cpp,v
retrieving revision 1.13
diff -u -r1.13 main.cpp
--- main.cpp	15 Nov 2002 06:09:05 -0000	1.13
+++ main.cpp	7 Dec 2002 23:36:01 -0000
@@ -1,5 +1,8 @@
 #include <qdir.h>
 #include <iostream>
+#include <map>
+#include <vector>
+#include <algorithm>
 using namespace std;
 
 #include <qapplication.h>
@@ -72,7 +75,10 @@
     }
 }
 
-void SearchDir(MythContext *context, QString &directory)
+
+typedef map<QString, bool> MusicLoadedMap_t;
+
+void BuildFileList(MythContext *context, QString &directory, MusicLoadedMap_t& music_files)
 {
     QDir d(directory);
 
@@ -93,9 +99,142 @@
             continue;
         QString filename = fi->absFilePath();
         if (fi->isDir())
-            SearchDir(context, filename);
+            BuildFileList(context, filename, music_files);
         else
-            CheckFile(context, filename);
+	  music_files[filename] = false;
+    }
+
+}
+
+// builds a query of the form select filename where filename in ("file1", "file2")
+// for large enough collections, this could exceed the query limit size,
+// so we break this into multiple queries if necessary
+class AllMusicQueryBuilder
+{
+public:
+  AllMusicQueryBuilder() : unfinished_(false)
+  {
+    initialize_query();
+  }
+  void operator()(const MusicLoadedMap_t::value_type& music_file)
+  {
+    QString addition;
+    
+    addition.append("\"");
+    addition.append(music_file.first);
+    addition.append("\"");
+
+    checkpoint(addition);
+  }
+  
+  vector<QString>::iterator begin()
+  { 
+    if (unfinished_) 
+      { 
+	finish();
+      }
+    return queries_.begin();
+  }
+  vector<QString>::iterator end()
+  { 
+    if (unfinished_) 
+      { 
+	finish();
+      } 
+    return queries_.end();
+  }
+  
+private:
+
+  void checkpoint(const QString& additional_term)
+  {
+    if ((current_query_.length() + additional_term.length() + QUERY_END.length())
+	>= MAX_QUERY_SIZE)
+      {
+	if (first_addition_)
+	  return; // we have some sort of weird dos thing going on
+	finish();
+	checkpoint(additional_term);
+      }
+    else
+      {
+	if (first_addition_)
+	  first_addition_ = false;
+	else
+	  current_query_.append(SEPERATOR);
+	
+	current_query_.append(additional_term);
+	unfinished_ = true;
+      }
+  }
+  void initialize_query()
+  {
+    current_query_ = QUERY_START;
+    first_addition_ = true;
+  }
+  void finish()
+  {
+    unfinished_ = false;
+    current_query_ += QUERY_END;
+    
+    queries_.push_back(current_query_);
+    
+    initialize_query();
+  }
+
+  vector<QString> queries_;
+  QString current_query_;
+  bool first_addition_;
+  bool unfinished_;
+  static const int MAX_QUERY_SIZE = 64000;
+  static const QString SEPERATOR;
+  static const QString QUERY_START;
+  static const QString QUERY_END;
+};
+
+const QString  AllMusicQueryBuilder::SEPERATOR(", ");
+const QString  AllMusicQueryBuilder::QUERY_START("SELECT filename FROM musicmetadata WHERE filename IN (");
+const QString  AllMusicQueryBuilder::QUERY_END(");");
+
+
+void SearchDir(MythContext *context, QString &directory)
+{
+  MusicLoadedMap_t music_files;
+
+  BuildFileList(context, directory, music_files);
+  
+  AllMusicQueryBuilder queries;
+  
+  
+  queries = for_each(music_files.begin(), music_files.end(), queries);
+
+  QSqlDatabase *db = QSqlDatabase::database();
+
+
+  for (vector<QString>::iterator it = queries.begin(); it != queries.end(); it++)
+    {
+      QSqlQuery query = db->exec(*it);
+
+      if (query.isActive() && query.numRowsAffected() > 0)
+	{
+	  while (query.next())
+	    {
+	      QString current_file = query.value(0).toString();
+	      music_files[current_file] = true;
+	    }
+	}
+      
+    }
+  
+  MusicLoadedMap_t::iterator map_it, map_end;
+
+  for (map_it = music_files.begin(), map_end = music_files.end(); map_it != map_end; map_it++)
+    {
+      if (!map_it->second)
+	{
+	  QString file = map_it->first;
+	  CheckFile(context, file);
+	}
     }
 }
 

--neYutvxvOLaeuPCA--