banshee r3963 - in trunk/banshee: . src/Core/Banshee.Core src/Core/Banshee.Core/Banshee.Kernel src/Core/Banshee.Services/Banshee.Database src/Extensions/Banshee.Podcasting/Banshee.Podcasting src/Libraries/Hyena/Hyena.Data.Sqlite src/Libraries/Migo/Migo.Syndication
- From: gburt svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r3963 - in trunk/banshee: . src/Core/Banshee.Core src/Core/Banshee.Core/Banshee.Kernel src/Core/Banshee.Services/Banshee.Database src/Extensions/Banshee.Podcasting/Banshee.Podcasting src/Libraries/Hyena/Hyena.Data.Sqlite src/Libraries/Migo/Migo.Syndication
- Date: Thu, 22 May 2008 19:49:27 +0000 (UTC)
Author: gburt
Date: Thu May 22 19:49:27 2008
New Revision: 3963
URL: http://svn.gnome.org/viewvc/banshee?rev=3963&view=rev
Log:
2008-05-22 Gabriel Burt <gabriel burt gmail com>
There were some pretty big performance issues with podcasting if you had
quite a few items in your library. The two issues were not having proper
indices (to join CoreTracks.ExternalID = PodcastItems.ItemID for example)
and hitting the database to get Migo.Feed/FeedItem/FeedEnclosure objects
when we already had them cached in MigoModelProvider's dictionary.
* src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastService.cs:
Schedule a delegate job to reload the feeds on startup.
* src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs:
Add an index on CoreTracks for the ExternalID column.
* src/Core/Banshee.Core/Makefile.am:
* src/Core/Banshee.Core/Banshee.Core.mdp:
* src/Core/Banshee.Core/Banshee.Kernel/DelegateJob.cs: New class for
running parameterless methods/delegates as a Job.
* src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs: Add a
CreateIndex convenience method, and make FetchSingle virtual
* src/Libraries/Migo/Migo.Syndication/FeedItem.cs:
* src/Libraries/Migo/Migo.Syndication/FeedEnclosure.cs:
* src/Libraries/Migo/Migo.Syndication/Feed.cs: Add indices, speeds up
podcast queries a whole lot.
* src/Libraries/Migo/Migo.Syndication/MigoModelProvider.cs: Override
FetchSingle to pull directly from the dictionary and avoid the DB entirely
if possible (happens very frequently).
* src/Libraries/Migo/Migo.Syndication/FeedManager.cs: Only download 2
feeds at at time, not 4.
Added:
trunk/banshee/src/Core/Banshee.Core/Banshee.Kernel/DelegateJob.cs
Modified:
trunk/banshee/ChangeLog
trunk/banshee/src/Core/Banshee.Core/Banshee.Core.mdp
trunk/banshee/src/Core/Banshee.Core/Makefile.am
trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs
trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastService.cs
trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs
trunk/banshee/src/Libraries/Migo/Migo.Syndication/Feed.cs
trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedEnclosure.cs
trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedItem.cs
trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedManager.cs
trunk/banshee/src/Libraries/Migo/Migo.Syndication/MigoModelProvider.cs
Modified: trunk/banshee/src/Core/Banshee.Core/Banshee.Core.mdp
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Banshee.Core.mdp (original)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.Core.mdp Thu May 22 19:49:27 2008
@@ -1,4 +1,4 @@
-<Project name="Banshee.Core" fileversion="2.0" language="C#" clr-version="Net_2_0" UseParentDirectoryAsNamespace="True" ctype="DotNetProject">
+<Project name="Banshee.Core" fileversion="2.0" UseParentDirectoryAsNamespace="True" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
<Configurations active="Debug">
<Configuration name="Debug" ctype="DotNetProjectConfiguration">
<Output directory="../../../bin" assemblyKeyFile="." assembly="Banshee.Core" />
@@ -69,6 +69,7 @@
<File name="Banshee.Base/XdgBaseDirectorySpec.cs" subtype="Code" buildaction="Compile" />
<File name="Banshee.Base/Tests/FileNamePatternTests.cs" subtype="Code" buildaction="Compile" />
<File name="Banshee.Base/Tests/TaglibReadWriteTests.cs" subtype="Code" buildaction="Compile" />
+ <File name="Banshee.Kernel/DelegateJob.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References>
<ProjectReference type="Project" localcopy="False" refto="Hyena" />
Added: trunk/banshee/src/Core/Banshee.Core/Banshee.Kernel/DelegateJob.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.Kernel/DelegateJob.cs Thu May 22 19:49:27 2008
@@ -0,0 +1,48 @@
+//
+// DelegateJob.cs
+//
+// Authors:
+// Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace Banshee.Kernel
+{
+ public class DelegateJob : Job
+ {
+ public delegate void JobDelegate ();
+ private JobDelegate method;
+
+ public DelegateJob (JobDelegate method)
+ {
+ this.method = method;
+ }
+
+ protected override void RunJob ()
+ {
+ method ();
+ }
+ }
+}
Modified: trunk/banshee/src/Core/Banshee.Core/Makefile.am
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Makefile.am (original)
+++ trunk/banshee/src/Core/Banshee.Core/Makefile.am Thu May 22 19:49:27 2008
@@ -49,6 +49,7 @@
Banshee.IO/Provider.cs \
Banshee.IO/StreamAssist.cs \
Banshee.IO/Utilities.cs \
+ Banshee.Kernel/DelegateJob.cs \
Banshee.Kernel/IInstanceCriticalJob.cs \
Banshee.Kernel/IJob.cs \
Banshee.Kernel/Job.cs \
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs Thu May 22 19:49:27 2008
@@ -52,7 +52,7 @@
// NOTE: Whenever there is a change in ANY of the database schema,
// this version MUST be incremented and a migration method
// MUST be supplied to match the new version number
- protected const int CURRENT_VERSION = 10;
+ protected const int CURRENT_VERSION = 11;
protected const int CURRENT_METADATA_VERSION = 1;
#region Migration Driver
@@ -381,6 +381,8 @@
#endregion
+#region Version 10
+
[DatabaseVersion (10)]
private bool Migrate_10 ()
{
@@ -391,6 +393,19 @@
Execute ("ALTER TABLE CoreTracks ADD COLUMN ExternalID INTEGER");
return true;
}
+
+#endregion
+
+#region Version 11
+
+ [DatabaseVersion (11)]
+ private bool Migrate_11 ()
+ {
+ Execute("CREATE INDEX CoreTracksExternalIDIndex ON CoreTracks(PrimarySourceID, ExternalID)");
+ return true;
+ }
+
+#endregion
#pragma warning restore 0169
@@ -474,6 +489,7 @@
", (int)TrackMediaAttributes.Default, (int)StreamPlaybackError.None));
Execute("CREATE INDEX CoreTracksPrimarySourceIndex ON CoreTracks(ArtistID, AlbumID, PrimarySourceID, Disc, TrackNumber, Uri)");
Execute("CREATE INDEX CoreTracksAggregatesIndex ON CoreTracks(FileSize, Duration)");
+ Execute("CREATE INDEX CoreTracksExternalIDIndex ON CoreTracks(PrimarySourceID, ExternalID)");
Execute(@"
CREATE TABLE CoreAlbums (
Modified: trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastService.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastService.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastService.cs Thu May 22 19:49:27 2008
@@ -90,7 +90,7 @@
InitializeInterface ();
}
- private void MigrateIfPossible ()
+ private void MigrateLegacyIfNeeded ()
{
if (DatabaseConfigurationClient.Client.Get<int> ("Podcast", "Version", 0) == 0) {
if (ServiceManager.DbConnection.TableExists ("Podcasts") &&
@@ -180,12 +180,14 @@
public void DelayedInitialize ()
{
// Migrate data from 0.13.2 podcast tables, if they exist
- MigrateIfPossible ();
-
- foreach (Feed feed in Feed.Provider.FetchAll ()) {
- feed.Update ();
- RefreshArtworkFor (feed);
- }
+ MigrateLegacyIfNeeded ();
+
+ Banshee.Kernel.Scheduler.Schedule (new Banshee.Kernel.DelegateJob (delegate {
+ foreach (Feed feed in Feed.Provider.FetchAll ()) {
+ feed.Update ();
+ RefreshArtworkFor (feed);
+ }
+ }));
}
bool disposing;
@@ -227,7 +229,7 @@
private void RefreshArtworkFor (Feed feed)
{
if (feed.LastDownloadTime != DateTime.MinValue)
- Banshee.Kernel.Scheduler.Schedule (new PodcastImageFetchJob (feed), Banshee.Kernel.JobPriority.Highest);
+ Banshee.Kernel.Scheduler.Schedule (new PodcastImageFetchJob (feed), Banshee.Kernel.JobPriority.Normal);
}
private void OnItemAdded (FeedItem item)
Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs (original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs Thu May 22 19:49:27 2008
@@ -267,6 +267,14 @@
}
}
+ protected void CreateIndex (string name, string columns)
+ {
+ Connection.Execute (String.Format (
+ "CREATE INDEX {0} ON {1} ({2})",
+ name, TableName, columns
+ ));
+ }
+
public virtual void Save (T target)
{
try {
@@ -392,7 +400,7 @@
return FetchSingle ((long) id);
}
- public T FetchSingle (long id)
+ public virtual T FetchSingle (long id)
{
using (IDataReader reader = connection.Query (SelectSingleCommand, id)) {
if (reader.Read ()) {
Modified: trunk/banshee/src/Libraries/Migo/Migo.Syndication/Feed.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo.Syndication/Feed.cs (original)
+++ trunk/banshee/src/Libraries/Migo/Migo.Syndication/Feed.cs Thu May 22 19:49:27 2008
@@ -69,17 +69,28 @@
{
}
+ protected override void CreateTable ()
+ {
+ base.CreateTable ();
+
+ CreateIndex ("PodcastSyndicationsIndex", "IsSubscribed, Title");
+ }
+
protected override int ModelVersion {
- get { return 2; }
+ get { return 3; }
}
protected override void MigrateTable (int old_version)
{
- Log.Debug("WE DID IT!");
+ CheckTable ();
+
if (old_version < 2) {
- CheckTable ();
Connection.Execute (String.Format ("UPDATE {0} SET IsSubscribed=1", TableName));
- } else Log.Debug ("Um... no we didn't");
+ }
+
+ if (old_version < 3) {
+ CreateIndex ("PodcastSyndicationsIndex", "IsSubscribed, Title");
+ }
}
}
Modified: trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedEnclosure.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedEnclosure.cs (original)
+++ trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedEnclosure.cs Thu May 22 19:49:27 2008
@@ -231,7 +231,7 @@
protected set { dbid = value; }
}
- [DatabaseColumn ("ItemID")]
+ [DatabaseColumn ("ItemID", Index = "PodcastEnclosuresItemIDIndex")]
protected long item_id;
public long ItemId {
get { return Item.DbId; }
Modified: trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedItem.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedItem.cs (original)
+++ trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedItem.cs Thu May 22 19:49:27 2008
@@ -36,6 +36,13 @@
namespace Migo.Syndication
{
+ public class FeedItemProvider : MigoModelProvider<FeedItem>
+ {
+ public FeedItemProvider (HyenaSqliteConnection connection) : base (connection, "PodcastItems")
+ {
+ }
+ }
+
public class FeedItem : MigoItem<FeedItem>
{
private static SqliteModelProvider<FeedItem> provider;
@@ -49,7 +56,7 @@
}
public static void Init () {
- provider = new MigoModelProvider<FeedItem> (FeedsManager.Instance.Connection, "PodcastItems");
+ provider = new FeedItemProvider (FeedsManager.Instance.Connection);
}
private bool active = true;
@@ -78,7 +85,7 @@
protected set { dbid = value; }
}
- [DatabaseColumn("FeedID")]
+ [DatabaseColumn("FeedID", Index = "PodcastItemsFeedIDIndex")]
protected long feed_id;
public long FeedId {
get { return feed_id; }
@@ -112,7 +119,7 @@
set { description = value; }
}
- [DatabaseColumn]
+ [DatabaseColumn("Guid", Index = "PodcastItemsGuidIndex")]
public string Guid {
get { return guid; }
set { guid = value; }
Modified: trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedManager.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedManager.cs (original)
+++ trunk/banshee/src/Libraries/Migo/Migo.Syndication/FeedManager.cs Thu May 22 19:49:27 2008
@@ -59,7 +59,7 @@
update_task_list = new TaskList<FeedUpdateTask> ();
// Limit to 4 feeds downloading at a time
- update_task_group = new TaskGroup<FeedUpdateTask> (4, update_task_list);
+ update_task_group = new TaskGroup<FeedUpdateTask> (2, update_task_list);
update_task_group.TaskStopped += OnUpdateTaskStopped;
update_task_group.TaskAssociated += OnUpdateTaskAdded;
Modified: trunk/banshee/src/Libraries/Migo/Migo.Syndication/MigoModelProvider.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo.Syndication/MigoModelProvider.cs (original)
+++ trunk/banshee/src/Libraries/Migo/Migo.Syndication/MigoModelProvider.cs Thu May 22 19:49:27 2008
@@ -36,33 +36,32 @@
{
// Caches all results retrieved from the database, such that any subsequent retrieval will
// return the same instance.
- public class MigoModelProvider<T> : SqliteModelProvider<T> where T : ICacheableItem, new()
+ public class MigoModelProvider<T> : SqliteModelProvider<T> where T : ICacheableItem, MigoItem<T>, new()
{
private Dictionary<long, T> full_cache = new Dictionary<long, T> ();
public MigoModelProvider (HyenaSqliteConnection connection, string table_name) : base (connection, table_name)
{
}
+
+#region Overrides
+
+ public override T FetchSingle (long id)
+ {
+ return GetCached (id) ?? CacheResult (base.FetchSingle (id));
+ }
public override void Save (T target)
{
base.Save (target);
- long dbid = PrimaryKeyFor (target);
- if (!full_cache.ContainsKey (dbid)) {
- full_cache[dbid] = target;
+ if (!full_cache.ContainsKey (target.DbId)) {
+ full_cache[target.DbId] = target;
}
}
public override T Load (System.Data.IDataReader reader)
{
- long dbid = PrimaryKeyFor (reader);
- if (full_cache.ContainsKey (dbid)) {
- return full_cache[dbid];
- } else {
- T item = base.Load (reader);
- full_cache[dbid] = item;
- return item;
- }
+ return GetCached (PrimaryKeyFor (reader)) ?? CacheResult (base.Load (reader));
}
public override void Delete (long id)
@@ -80,5 +79,27 @@
base.Delete (items);
}
+
+#endregion
+
+#region Utility Methods
+
+ private T GetCached (long id)
+ {
+ if (full_cache.ContainsKey (id)) {
+ return full_cache[id];
+ } else {
+ return null;
+ }
+ }
+
+ private T CacheResult (T item)
+ {
+ full_cache[item.DbId] = item;
+ return item;
+ }
+
+#endregion
+
}
}
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]