summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Settenvini <matteo@member.fsf.org>2017-02-16 12:27:50 -0300
committerJens Georg <mail@jensge.org>2017-02-19 13:43:55 +0100
commitd2a2b925ae67307a8b96c1dead05609f87258e04 (patch)
treea204f2bf4102ebc2a25c6b08f286b40433baa8f9
parent72905837ba4f55cc4dc560e61879a848ad2e4438 (diff)
downloadrygel-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
-rw-r--r--src/plugins/media-export/rygel-media-export-extractor.vala11
-rw-r--r--src/plugins/media-export/rygel-media-export-harvester.vala2
-rw-r--r--src/plugins/media-export/rygel-media-export-harvesting-task.vala65
-rw-r--r--src/plugins/media-export/rygel-media-export-media-cache.vala9
-rw-r--r--src/plugins/media-export/rygel-media-export-sql-factory.vala2
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 =