diff options
author | Matteo Settenvini <matteo@member.fsf.org> | 2017-02-16 12:27:50 -0300 |
---|---|---|
committer | Jens Georg <mail@jensge.org> | 2017-02-19 13:43:55 +0100 |
commit | d2a2b925ae67307a8b96c1dead05609f87258e04 (patch) | |
tree | a204f2bf4102ebc2a25c6b08f286b40433baa8f9 | |
parent | 72905837ba4f55cc4dc560e61879a848ad2e4438 (diff) | |
download | rygel-d2a2b925ae67307a8b96c1dead05609f87258e04.tar.gz |
Avoid always re-reading all mime-types on startup
This commits optimizes startup time, when scanning directories with
many files which are already cached and up-to-date. Before, we were
always opening and reading from them to determine their mime-type,
even though it was already in the local database. Now we re-use
this information, getting a speed up which can be even of
several minutes, especially on systems with rotational drives.
https://bugzilla.gnome.org/show_bug.cgi?id=778778
5 files changed, 51 insertions, 38 deletions
diff --git a/src/plugins/media-export/rygel-media-export-extractor.vala b/src/plugins/media-export/rygel-media-export-extractor.vala index 2fd93468..3625469d 100644 --- a/src/plugins/media-export/rygel-media-export-extractor.vala +++ b/src/plugins/media-export/rygel-media-export-extractor.vala @@ -91,12 +91,11 @@ public class Rygel.MediaExport.Extractor : Object { public virtual async void run () throws Error { var file_info = yield file.query_info_async (FileAttribute.STANDARD_TYPE + "," + - FileAttribute.STANDARD_CONTENT_TYPE - + "," + - FileAttribute.STANDARD_SIZE + "," + - FileAttribute.TIME_MODIFIED + "," + - FileAttribute.STANDARD_DISPLAY_NAME, - FileQueryInfoFlags.NONE); + FileAttribute.STANDARD_CONTENT_TYPE + "," + + FileAttribute.STANDARD_SIZE + "," + + FileAttribute.TIME_MODIFIED + "," + + FileAttribute.STANDARD_DISPLAY_NAME, + FileQueryInfoFlags.NONE); var display_name = file_info.get_display_name (); var title = this.strip_invalid_entities (display_name); this.serialized_info.insert (Serializer.TITLE, "s", title); diff --git a/src/plugins/media-export/rygel-media-export-harvester.vala b/src/plugins/media-export/rygel-media-export-harvester.vala index d72c7de1..0d470320 100644 --- a/src/plugins/media-export/rygel-media-export-harvester.vala +++ b/src/plugins/media-export/rygel-media-export-harvester.vala @@ -80,7 +80,7 @@ internal class Rygel.MediaExport.Harvester : GLib.Object { var is_blacklisted = cache.is_blacklisted (file); if (is_blacklisted) { - debug ("URI %s is not eligble due to blacklising", + debug ("URI %s is not eligible due to blacklisting", file.get_uri ()); } diff --git a/src/plugins/media-export/rygel-media-export-harvesting-task.vala b/src/plugins/media-export/rygel-media-export-harvesting-task.vala index 2023e589..a3f92272 100644 --- a/src/plugins/media-export/rygel-media-export-harvesting-task.vala +++ b/src/plugins/media-export/rygel-media-export-harvesting-task.vala @@ -51,11 +51,13 @@ public class Rygel.MediaExport.HarvestingTask : Rygel.StateMachine, private const string HARVESTER_ATTRIBUTES = FileAttribute.STANDARD_NAME + "," + FileAttribute.STANDARD_TYPE + "," + - FileAttribute.TIME_MODIFIED + "," + - FileAttribute.STANDARD_CONTENT_TYPE + "," + FileAttribute.STANDARD_SIZE + "," + + FileAttribute.TIME_MODIFIED + "," + FileAttribute.STANDARD_IS_HIDDEN; + private const string HARVESTER_MIME_TYPE_ATTRIBUTES = + FileAttribute.STANDARD_CONTENT_TYPE; + public HarvestingTask (RecursiveFileMonitor monitor, File file, MediaContainer parent) { @@ -142,35 +144,49 @@ public class Rygel.MediaExport.HarvestingTask : Rygel.StateMachine, * - The current mtime of the file is larger than the cached * - The size has changed * @param file to check - * @param info FileInfo of the file to check + * @param info FileInfo of the file to check, containing at + * least size, mtime and type (but not necessarily + * mime type) * @return true, if the file has been queued, false otherwise. */ private bool push_if_changed_or_unknown (File file, FileInfo info) { - int64 timestamp; - int64 size; try { - if (this.cache.exists (file, out timestamp, out size)) { + int64 timestamp; + int64 size; + string mime_type; + + bool is_cached = this.cache.exists (file, out timestamp, out size, out mime_type); + if (is_cached) { int64 mtime = (int64) info.get_attribute_uint64 (FileAttribute.TIME_MODIFIED); + if (mtime <= timestamp && + info.get_size () == size) { + return false; + } - if (mtime > timestamp || - info.get_size () != size) { - var entry = new FileQueueEntry (file, - true, - info.get_content_type ()); - this.files.offer (entry); + info.set_content_type(mime_type); + } - return true; - } - } else { - var entry = new FileQueueEntry (file, - false, - info.get_content_type ()); - this.files.offer (entry); + if (info.get_content_type () == null) { + var extended_info = file.query_info + (HARVESTER_MIME_TYPE_ATTRIBUTES, + FileQueryInfoFlags.NONE); + info.set_content_type (extended_info.get_content_type ()); + } - return true; + // Check if the file needs to be harvested at all either because + // it is denied by filter or it hasn't updated + if (!Harvester.is_eligible (file, info)) { + return false; } + + var entry = new FileQueueEntry (file, + is_cached, + info.get_content_type ()); + this.files.offer (entry); + + return true; } catch (Error error) { warning (_("Failed to query database: %s"), error.message); } @@ -185,7 +201,6 @@ public class Rygel.MediaExport.HarvestingTask : Rygel.StateMachine, return false; } - if (info.get_file_type () == FileType.DIRECTORY) { // Check if we have an "exploded" DVD structure if (file.get_child ("VIDEO_TS").query_exists ()) { @@ -211,13 +226,7 @@ public class Rygel.MediaExport.HarvestingTask : Rygel.StateMachine, return true; } else { - // Check if the file needs to be harvested at all either because - // it is denied by filter or it hasn't updated - if (Harvester.is_eligible (file, info)) { - return this.push_if_changed_or_unknown (file, info); - } - - return false; + return this.push_if_changed_or_unknown (file, info); } } diff --git a/src/plugins/media-export/rygel-media-export-media-cache.vala b/src/plugins/media-export/rygel-media-export-media-cache.vala index 74bbdf10..272e21d7 100644 --- a/src/plugins/media-export/rygel-media-export-media-cache.vala +++ b/src/plugins/media-export/rygel-media-export-media-cache.vala @@ -44,6 +44,7 @@ internal enum Rygel.MediaExport.ObjectType { internal struct Rygel.MediaExport.ExistsCacheEntry { int64 mtime; int64 size; + string content_type; } /** @@ -219,15 +220,18 @@ public class Rygel.MediaExport.MediaCache : Object { public bool exists (File file, out int64 timestamp, - out int64 size) throws DatabaseError { + out int64 size, + out string mime_type) throws DatabaseError { var uri = file.get_uri (); GLib.Value[] values = { uri }; + mime_type = null; if (this.exists_cache.has_key (uri)) { var entry = this.exists_cache.get (uri); this.exists_cache.unset (uri); timestamp = entry.mtime; size = entry.size; + mime_type = entry.content_type; return true; } @@ -634,7 +638,8 @@ public class Rygel.MediaExport.MediaCache : Object { var entry = ExistsCacheEntry (); entry.mtime = statement.column_int64 (1); entry.size = statement.column_int64 (0); - this.exists_cache.set (statement.column_text (2), entry); + entry.content_type = statement.column_text (2); + this.exists_cache.set (statement.column_text (3), entry); } } diff --git a/src/plugins/media-export/rygel-media-export-sql-factory.vala b/src/plugins/media-export/rygel-media-export-sql-factory.vala index 298f01b1..8d4ee4ed 100644 --- a/src/plugins/media-export/rygel-media-export-sql-factory.vala +++ b/src/plugins/media-export/rygel-media-export-sql-factory.vala @@ -305,7 +305,7 @@ internal class Rygel.MediaExport.SQLFactory : Object { "CREATE INDEX IF NOT EXISTS idx_blacklist on blacklist(uri);"; private const string EXISTS_CACHE_STRING = - "SELECT m.size, o.timestamp, o.uri FROM Object o " + + "SELECT m.size, o.timestamp, m.mime_type, o.uri FROM Object o " + "JOIN meta_data m ON o.upnp_id = m.object_fk"; private const string STATISTICS_STRING = |