소스 검색

Further reduced disk access in ItemController

LukePulverenti Luke Pulverenti luke pulverenti 13 년 전
부모
커밋
9029d939f3

+ 27 - 28
MediaBrowser.Controller/Events/ItemResolveEventArgs.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Collections.Generic;
 using System.IO;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Model.Entities;
@@ -11,55 +10,55 @@ namespace MediaBrowser.Controller.Events
     /// </summary>
     public class ItemResolveEventArgs : PreBeginResolveEventArgs
     {
-        public KeyValuePair<string, WIN32_FIND_DATA>[] FileSystemChildren { get; set; }
+        public LazyFileInfo[] FileSystemChildren { get; set; }
 
-        public KeyValuePair<string, WIN32_FIND_DATA>? GetFileSystemEntry(string path, bool? isFolder)
+        public LazyFileInfo? GetFileSystemEntry(string path, bool? isFolder = null)
         {
             for (int i = 0; i < FileSystemChildren.Length; i++)
             {
-                KeyValuePair<string, WIN32_FIND_DATA> entry = FileSystemChildren[i];
+                LazyFileInfo entry = FileSystemChildren[i];
 
-                if (isFolder.HasValue)
+                if (entry.Path.Equals(path, StringComparison.OrdinalIgnoreCase))
                 {
-                    if (isFolder.Value && !entry.Value.IsDirectory)
+                    if (isFolder.HasValue)
                     {
-                        continue;
+                        if (isFolder.Value && !entry.FileInfo.IsDirectory)
+                        {
+                            continue;
+                        }
+                        else if (!isFolder.Value && entry.FileInfo.IsDirectory)
+                        {
+                            continue;
+                        }
                     }
-                    else if (!isFolder.Value && entry.Value.IsDirectory)
-                    {
-                        continue;
-                    }
-                }
-
-                if (entry.Key.Equals(path, StringComparison.OrdinalIgnoreCase))
-                {
+                    
                     return entry;
                 }
             }
 
             return null;
         }
-        
-        public KeyValuePair<string, WIN32_FIND_DATA>? GetFileSystemEntryByName(string name, bool? isFolder)
+
+        public LazyFileInfo? GetFileSystemEntryByName(string name, bool? isFolder = null)
         {
             for (int i = 0; i < FileSystemChildren.Length; i++)
             {
-                KeyValuePair<string, WIN32_FIND_DATA> entry = FileSystemChildren[i];
+                LazyFileInfo entry = FileSystemChildren[i];
 
-                if (isFolder.HasValue)
+                if (System.IO.Path.GetFileName(entry.Path).Equals(name, StringComparison.OrdinalIgnoreCase))
                 {
-                    if (isFolder.Value && !entry.Value.IsDirectory)
-                    {
-                        continue;
-                    }
-                    else if (!isFolder.Value && entry.Value.IsDirectory)
+                    if (isFolder.HasValue)
                     {
-                        continue;
+                        if (isFolder.Value && !entry.FileInfo.IsDirectory)
+                        {
+                            continue;
+                        }
+                        else if (!isFolder.Value && entry.FileInfo.IsDirectory)
+                        {
+                            continue;
+                        }
                     }
-                }
 
-                if (System.IO.Path.GetFileName(entry.Key).Equals(name, StringComparison.OrdinalIgnoreCase))
-                {
                     return entry;
                 }
             }

+ 1 - 2
MediaBrowser.Controller/FFMpeg/FFProbeResult.cs

@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 
 namespace MediaBrowser.Controller.FFMpeg
 {

+ 24 - 0
MediaBrowser.Controller/IO/FileData.cs

@@ -93,4 +93,28 @@ namespace MediaBrowser.Controller.IO
         }
     }
 
+    public struct LazyFileInfo
+    {
+        public string Path { get; set; }
+
+        private WIN32_FIND_DATA? _FileInfo { get; set; }
+
+        public WIN32_FIND_DATA FileInfo
+        {
+            get
+            {
+                if (_FileInfo == null)
+                {
+                    _FileInfo = FileData.GetFileData(Path);
+                }
+
+                return _FileInfo.Value;
+            }
+            set
+            {
+                _FileInfo = value;
+            }
+        }
+    }
+
 }

+ 16 - 20
MediaBrowser.Controller/Library/ItemController.cs

@@ -84,7 +84,7 @@ namespace MediaBrowser.Controller.Library
                 return null;
             }
 
-            KeyValuePair<string, WIN32_FIND_DATA>[] fileSystemChildren;
+            LazyFileInfo[] fileSystemChildren;
 
             // Gather child folder and files
             if (fileData.IsDirectory)
@@ -96,7 +96,7 @@ namespace MediaBrowser.Controller.Library
             }
             else
             {
-                fileSystemChildren = new KeyValuePair<string, WIN32_FIND_DATA>[] { };
+                fileSystemChildren = new LazyFileInfo[] { };
             }
 
             ItemResolveEventArgs args = new ItemResolveEventArgs()
@@ -135,7 +135,7 @@ namespace MediaBrowser.Controller.Library
         /// <summary>
         /// Finds child BaseItems for a given Folder
         /// </summary>
-        private async Task AttachChildren(Folder folder, KeyValuePair<string, WIN32_FIND_DATA>[] fileSystemChildren)
+        private async Task AttachChildren(Folder folder, LazyFileInfo[] fileSystemChildren)
         {
             int count = fileSystemChildren.Length;
 
@@ -145,7 +145,7 @@ namespace MediaBrowser.Controller.Library
             {
                 var child = fileSystemChildren[i];
 
-                tasks[i] = GetItem(child.Key, folder, child.Value);
+                tasks[i] = GetItem(child.Path, folder, child.FileInfo);
             }
 
             BaseItem[] baseItemChildren = await Task<BaseItem>.WhenAll(tasks).ConfigureAwait(false);
@@ -161,23 +161,19 @@ namespace MediaBrowser.Controller.Library
         /// <summary>
         /// Transforms shortcuts into their actual paths
         /// </summary>
-        private KeyValuePair<string, WIN32_FIND_DATA>[] FilterChildFileSystemEntries(KeyValuePair<string, WIN32_FIND_DATA>[] fileSystemChildren, bool flattenShortcuts)
+        private LazyFileInfo[] FilterChildFileSystemEntries(LazyFileInfo[] fileSystemChildren, bool flattenShortcuts)
         {
-            KeyValuePair<string, WIN32_FIND_DATA>[] returnArray = new KeyValuePair<string, WIN32_FIND_DATA>[fileSystemChildren.Length];
-            List<KeyValuePair<string, WIN32_FIND_DATA>> resolvedShortcuts = new List<KeyValuePair<string, WIN32_FIND_DATA>>();
+            LazyFileInfo[] returnArray = new LazyFileInfo[fileSystemChildren.Length];
+            List<LazyFileInfo> resolvedShortcuts = new List<LazyFileInfo>();
 
             for (int i = 0; i < fileSystemChildren.Length; i++)
             {
-                KeyValuePair<string, WIN32_FIND_DATA> file = fileSystemChildren[i];
+                LazyFileInfo file = fileSystemChildren[i];
 
-                if (file.Value.IsDirectory)
-                {
-                    returnArray[i] = file;
-                }
                 // If it's a shortcut, resolve it
-                else if (Shortcut.IsShortcut(file.Key))
+                if (Shortcut.IsShortcut(file.Path))
                 {
-                    string newPath = Shortcut.ResolveShortcut(file.Key);
+                    string newPath = Shortcut.ResolveShortcut(file.Path);
                     WIN32_FIND_DATA newPathData = FileData.GetFileData(newPath);
 
                     // Find out if the shortcut is pointing to a directory or file
@@ -188,18 +184,18 @@ namespace MediaBrowser.Controller.Library
                         if (flattenShortcuts)
                         {
                             returnArray[i] = file;
-                            KeyValuePair<string, WIN32_FIND_DATA>[] newChildren = ConvertFileSystemEntries(Directory.GetFileSystemEntries(newPath, "*", SearchOption.TopDirectoryOnly));
+                            LazyFileInfo[] newChildren = ConvertFileSystemEntries(Directory.GetFileSystemEntries(newPath, "*", SearchOption.TopDirectoryOnly));
 
                             resolvedShortcuts.AddRange(FilterChildFileSystemEntries(newChildren, false));
                         }
                         else
                         {
-                            returnArray[i] = new KeyValuePair<string, WIN32_FIND_DATA>(newPath, newPathData);
+                            returnArray[i] = new LazyFileInfo() { Path = newPath, FileInfo = newPathData };
                         }
                     }
                     else
                     {
-                        returnArray[i] = new KeyValuePair<string, WIN32_FIND_DATA>(newPath, newPathData);
+                        returnArray[i] = new LazyFileInfo() { Path = newPath, FileInfo = newPathData };
                     }
                 }
                 else
@@ -309,15 +305,15 @@ namespace MediaBrowser.Controller.Library
             return item;
         }
 
-        private KeyValuePair<string, WIN32_FIND_DATA>[] ConvertFileSystemEntries(string[] files)
+        private LazyFileInfo[] ConvertFileSystemEntries(string[] files)
         {
-            KeyValuePair<string, WIN32_FIND_DATA>[] items = new KeyValuePair<string, WIN32_FIND_DATA>[files.Length];
+            LazyFileInfo[] items = new LazyFileInfo[files.Length];
 
             for (int i = 0; i < files.Length; i++)
             {
                 string file = files[i];
 
-                items[i] = new KeyValuePair<string, WIN32_FIND_DATA>(file, FileData.GetFileData(file));
+                items[i] = new LazyFileInfo() { Path = file };
             }
 
             return items;

+ 2 - 2
MediaBrowser.Controller/Providers/FolderProviderFromXml.cs

@@ -21,11 +21,11 @@ namespace MediaBrowser.Controller.Providers
 
         public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
         {
-            var metadataFile = args.GetFileSystemEntryByName("folder.xml", false);
+            var metadataFile = args.GetFileSystemEntryByName("folder.xml");
 
             if (metadataFile.HasValue)
             {
-                await Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, metadataFile.Value.Key); }).ConfigureAwait(false);
+                await Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, metadataFile.Value.Path); }).ConfigureAwait(false);
             }
         }
     }

+ 2 - 12
MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs

@@ -50,12 +50,7 @@ namespace MediaBrowser.Controller.Providers
             {
                 var file = args.FileSystemChildren[i];
                 
-                if (file.Value.IsDirectory)
-                {
-                    continue;
-                }
-
-                string filePath = file.Key;
+                string filePath = file.Path;
 
                 string ext = Path.GetExtension(filePath);
 
@@ -85,12 +80,7 @@ namespace MediaBrowser.Controller.Providers
             {
                 var file = args.FileSystemChildren[i];
 
-                if (file.Value.IsDirectory)
-                {
-                    continue;
-                }
-
-                string filePath = file.Key;
+                string filePath = file.Path;
 
                 string ext = Path.GetExtension(filePath);
 

+ 1 - 1
MediaBrowser.Controller/Providers/LocalTrailerProvider.cs

@@ -28,7 +28,7 @@ namespace MediaBrowser.Controller.Providers
 
             if (trailerPath.HasValue)
             {
-                string[] allFiles = Directory.GetFileSystemEntries(trailerPath.Value.Key, "*", SearchOption.TopDirectoryOnly);
+                string[] allFiles = Directory.GetFileSystemEntries(trailerPath.Value.Path, "*", SearchOption.TopDirectoryOnly);
 
                 List<Video> localTrailers = new List<Video>();
 

+ 3 - 5
MediaBrowser.Controller/Resolvers/BaseItemResolver.cs

@@ -1,10 +1,8 @@
 using System;
 using System.IO;
-using System.Threading.Tasks;
 using MediaBrowser.Controller.Events;
-using MediaBrowser.Model.Entities;
 using MediaBrowser.Controller.IO;
-using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Controller.Resolvers
 {
@@ -88,11 +86,11 @@ namespace MediaBrowser.Controller.Resolvers
             // See if a different path came out of the resolver than what went in
             if (!args.Path.Equals(item.Path, StringComparison.OrdinalIgnoreCase))
             {
-                KeyValuePair<string, WIN32_FIND_DATA>? childData = args.GetFileSystemEntry(item.Path, null);
+                LazyFileInfo? childData = args.GetFileSystemEntry(item.Path);
 
                 if (childData != null)
                 {
-                    fileData = childData.Value.Value;
+                    fileData = childData.Value.FileInfo;
                 }
                 else
                 {

+ 2 - 2
MediaBrowser.Controller/Resolvers/VideoResolver.cs

@@ -53,12 +53,12 @@ namespace MediaBrowser.Controller.Resolvers
                 {
                     var folder = args.FileSystemChildren[i];
 
-                    if (!folder.Value.IsDirectory)
+                    if (!folder.FileInfo.IsDirectory)
                     {
                         continue;
                     }
 
-                    item = ResolveFromFolderName(folder.Key);
+                    item = ResolveFromFolderName(folder.Path);
 
                     if (item != null)
                     {

+ 0 - 1
MediaBrowser.Controller/Xml/XmlExtensions.cs

@@ -1,5 +1,4 @@
 using System.Globalization;
-using System.Threading.Tasks;
 using System.Xml;
 
 namespace MediaBrowser.Controller.Xml

+ 2 - 2
MediaBrowser.Movies/Providers/MovieProviderFromXml.cs

@@ -23,11 +23,11 @@ namespace MediaBrowser.Movies.Providers
 
         public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
         {
-            var metadataFile = args.GetFileSystemEntryByName("movie.xml", false);
+            var metadataFile = args.GetFileSystemEntryByName("movie.xml");
 
             if (metadataFile.HasValue)
             {
-                await Task.Run(() => { new BaseItemXmlParser<Movie>().Fetch(item as Movie, metadataFile.Value.Key); }).ConfigureAwait(false);
+                await Task.Run(() => { new BaseItemXmlParser<Movie>().Fetch(item as Movie, metadataFile.Value.Path); }).ConfigureAwait(false);
             }
         }
     }

+ 5 - 6
MediaBrowser.Movies/Resolvers/MovieResolver.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Collections.Generic;
 using System.ComponentModel.Composition;
 using System.IO;
 using System.Linq;
@@ -19,7 +18,7 @@ namespace MediaBrowser.Movies.Resolvers
         {
             if (args.IsFolder && (args.VirtualFolderCollectionType ?? string.Empty).Equals("Movies", StringComparison.OrdinalIgnoreCase))
             {
-                var metadataFile = args.GetFileSystemEntryByName("movie.xml", false);
+                var metadataFile = args.GetFileSystemEntryByName("movie.xml");
 
                 if (metadataFile.HasValue || Path.GetFileName(args.Path).IndexOf("[tmdbid=", StringComparison.OrdinalIgnoreCase) != -1)
                 {
@@ -53,9 +52,9 @@ namespace MediaBrowser.Movies.Resolvers
 
                 ItemResolveEventArgs childArgs = new ItemResolveEventArgs()
                 {
-                    Path = child.Key,
-                    FileData = child.Value,
-                    FileSystemChildren = new KeyValuePair<string, WIN32_FIND_DATA>[] { }
+                    Path = child.Path,
+                    FileData = child.FileInfo,
+                    FileSystemChildren = new LazyFileInfo[] { }
                 };
 
                 var item = base.Resolve(childArgs);
@@ -79,7 +78,7 @@ namespace MediaBrowser.Movies.Resolvers
 
             if (trailerPath.HasValue)
             {
-                string[] allFiles = Directory.GetFileSystemEntries(trailerPath.Value.Key, "*", SearchOption.TopDirectoryOnly);
+                string[] allFiles = Directory.GetFileSystemEntries(trailerPath.Value.Path, "*", SearchOption.TopDirectoryOnly);
 
                 item.SpecialFeatures = allFiles.Select(f => Kernel.Instance.ItemController.GetItem(f)).OfType<Video>();
             }

+ 0 - 1
MediaBrowser.TV/Metadata/EpisodeXmlParser.cs

@@ -1,5 +1,4 @@
 using System.IO;
-using System.Threading.Tasks;
 using System.Xml;
 using MediaBrowser.Controller.Xml;
 using MediaBrowser.TV.Entities;

+ 0 - 1
MediaBrowser.TV/Metadata/SeriesXmlParser.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Threading.Tasks;
 using System.Xml;
 using MediaBrowser.Controller.Xml;
 using MediaBrowser.Model.Entities;

+ 2 - 2
MediaBrowser.TV/Providers/SeriesProviderFromXml.cs

@@ -23,11 +23,11 @@ namespace MediaBrowser.TV.Providers
 
         public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
         {
-            var metadataFile = args.GetFileSystemEntryByName("series.xml", false);
+            var metadataFile = args.GetFileSystemEntryByName("series.xml");
 
             if (metadataFile.HasValue)
             {
-                await Task.Run(() => { new SeriesXmlParser().Fetch(item as Series, metadataFile.Value.Key); }).ConfigureAwait(false);
+                await Task.Run(() => { new SeriesXmlParser().Fetch(item as Series, metadataFile.Value.Path); }).ConfigureAwait(false);
             }
         }
     }

+ 1 - 1
MediaBrowser.TV/Resolvers/SeriesResolver.cs

@@ -20,7 +20,7 @@ namespace MediaBrowser.TV.Resolvers
                     return null;
                 }
 
-                var metadataFile = args.GetFileSystemEntryByName("series.xml", false);
+                var metadataFile = args.GetFileSystemEntryByName("series.xml");
 
                 if (metadataFile.HasValue || Path.GetFileName(args.Path).IndexOf("[tvdbid=", StringComparison.OrdinalIgnoreCase) != -1 || TVUtils.IsSeriesFolder(args.Path, args.FileSystemChildren))
                 {

+ 5 - 7
MediaBrowser.TV/TVUtils.cs

@@ -1,6 +1,4 @@
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
+using System.Linq;
 using System.Text.RegularExpressions;
 using MediaBrowser.Controller.IO;
 
@@ -53,22 +51,22 @@ namespace MediaBrowser.TV
             return seasonPathExpressions.Any(r => r.IsMatch(path));
         }
 
-        public static bool IsSeriesFolder(string path, KeyValuePair<string, WIN32_FIND_DATA>[] fileSystemChildren)
+        public static bool IsSeriesFolder(string path, LazyFileInfo[] fileSystemChildren)
         {
             for (int i = 0; i < fileSystemChildren.Length; i++)
             {
                 var child = fileSystemChildren[i];
 
-                if (child.Value.IsDirectory)
+                if (child.FileInfo.IsDirectory)
                 {
-                    if (IsSeasonFolder(child.Key))
+                    if (IsSeasonFolder(child.Path))
                     {
                         return true;
                     }
                 }
                 else
                 {
-                    if (!string.IsNullOrEmpty(EpisodeNumberFromFile(child.Key, false)))
+                    if (!string.IsNullOrEmpty(EpisodeNumberFromFile(child.Path, false)))
                     {
                         return true;
                     }