Răsfoiți Sursa

Use HashSets for increased perf

Bond_009 6 ani în urmă
părinte
comite
64d5ec12e2

+ 2 - 8
Emby.Server.Implementations/Data/BaseSqliteRepository.cs

@@ -375,21 +375,15 @@ namespace Emby.Server.Implementations.Data
             }
             }
         }
         }
 
 
-        public class DummyToken : IDisposable
-        {
-            public void Dispose()
-            {
-            }
-        }
-
         public static IDisposable Read(this ReaderWriterLockSlim obj)
         public static IDisposable Read(this ReaderWriterLockSlim obj)
         {
         {
             //if (BaseSqliteRepository.ThreadSafeMode > 0)
             //if (BaseSqliteRepository.ThreadSafeMode > 0)
             //{
             //{
             //    return new DummyToken();
             //    return new DummyToken();
             //}
             //}
-            return new WriteLockToken(obj);
+            return new ReadLockToken(obj);
         }
         }
+
         public static IDisposable Write(this ReaderWriterLockSlim obj)
         public static IDisposable Write(this ReaderWriterLockSlim obj)
         {
         {
             //if (BaseSqliteRepository.ThreadSafeMode > 0)
             //if (BaseSqliteRepository.ThreadSafeMode > 0)

+ 88 - 95
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -1183,9 +1183,9 @@ namespace Emby.Server.Implementations.Data
         /// <exception cref="ArgumentException"></exception>
         /// <exception cref="ArgumentException"></exception>
         public BaseItem RetrieveItem(Guid id)
         public BaseItem RetrieveItem(Guid id)
         {
         {
-            if (id.Equals(Guid.Empty))
+            if (id == Guid.Empty)
             {
             {
-                throw new ArgumentNullException(nameof(id));
+                throw new ArgumentException(nameof(id), "Guid can't be empty");
             }
             }
 
 
             CheckDisposed();
             CheckDisposed();
@@ -2079,14 +2079,14 @@ namespace Emby.Server.Implementations.Data
                 return false;
                 return false;
             }
             }
 
 
-            var sortingFields = query.OrderBy.Select(i => i.Item1);
+            var sortingFields = new HashSet<string>(query.OrderBy.Select(i => i.Item1), StringComparer.OrdinalIgnoreCase);
 
 
-            return sortingFields.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase)
-                    || sortingFields.Contains(ItemSortBy.IsPlayed, StringComparer.OrdinalIgnoreCase)
-                    || sortingFields.Contains(ItemSortBy.IsUnplayed, StringComparer.OrdinalIgnoreCase)
-                    || sortingFields.Contains(ItemSortBy.PlayCount, StringComparer.OrdinalIgnoreCase)
-                    || sortingFields.Contains(ItemSortBy.DatePlayed, StringComparer.OrdinalIgnoreCase)
-                    || sortingFields.Contains(ItemSortBy.SeriesDatePlayed, StringComparer.OrdinalIgnoreCase)
+            return sortingFields.Contains(ItemSortBy.IsFavoriteOrLiked)
+                    || sortingFields.Contains(ItemSortBy.IsPlayed)
+                    || sortingFields.Contains(ItemSortBy.IsUnplayed)
+                    || sortingFields.Contains(ItemSortBy.PlayCount)
+                    || sortingFields.Contains(ItemSortBy.DatePlayed)
+                    || sortingFields.Contains(ItemSortBy.SeriesDatePlayed)
                     || query.IsFavoriteOrLiked.HasValue
                     || query.IsFavoriteOrLiked.HasValue
                     || query.IsFavorite.HasValue
                     || query.IsFavorite.HasValue
                     || query.IsResumable.HasValue
                     || query.IsResumable.HasValue
@@ -2151,18 +2151,26 @@ namespace Emby.Server.Implementations.Data
             }
             }
         }
         }
 
 
-        private bool HasProgramAttributes(InternalItemsQuery query)
+        private static readonly HashSet<string> _programExcludeParentTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
         {
         {
-            var excludeParentTypes = new string[]
-            {
-                "Series",
-                "Season",
-                "MusicAlbum",
-                "MusicArtist",
-                "PhotoAlbum"
-            };
+            "Series",
+            "Season",
+            "MusicAlbum",
+            "MusicArtist",
+            "PhotoAlbum"
+        };
 
 
-            if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
+        private static readonly HashSet<string> _programTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
+        {
+            "Program",
+            "TvChannel",
+            "LiveTvProgram",
+            "LiveTvTvChannel"
+        };
+
+        private bool HasProgramAttributes(InternalItemsQuery query)
+        {
+            if (_programExcludeParentTypes.Contains(query.ParentType))
             {
             {
                 return false;
                 return false;
             }
             }
@@ -2172,29 +2180,18 @@ namespace Emby.Server.Implementations.Data
                 return true;
                 return true;
             }
             }
 
 
-            var types = new string[]
-            {
-                "Program",
-                "TvChannel",
-                "LiveTvProgram",
-                "LiveTvTvChannel"
-            };
-
-            return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase));
+            return query.IncludeItemTypes.Any(x => _programTypes.Contains(x));
         }
         }
 
 
-        private bool HasServiceName(InternalItemsQuery query)
+        private static readonly HashSet<string> _serviceTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
         {
         {
-            var excludeParentTypes = new string[]
-            {
-                "Series",
-                "Season",
-                "MusicAlbum",
-                "MusicArtist",
-                "PhotoAlbum"
-            };
+            "TvChannel",
+            "LiveTvTvChannel"
+        };
 
 
-            if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
+        private bool HasServiceName(InternalItemsQuery query)
+        {
+            if (_programExcludeParentTypes.Contains(query.ParentType))
             {
             {
                 return false;
                 return false;
             }
             }
@@ -2204,27 +2201,18 @@ namespace Emby.Server.Implementations.Data
                 return true;
                 return true;
             }
             }
 
 
-            var types = new string[]
-            {
-                "TvChannel",
-                "LiveTvTvChannel"
-            };
-
-            return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase));
+            return query.IncludeItemTypes.Any(x => _serviceTypes.Contains(x));
         }
         }
 
 
-        private bool HasStartDate(InternalItemsQuery query)
+        private static readonly HashSet<string> _startDateTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
         {
         {
-            var excludeParentTypes = new string[]
-            {
-                "Series",
-                "Season",
-                "MusicAlbum",
-                "MusicArtist",
-                "PhotoAlbum"
-            };
+            "Program",
+            "LiveTvProgram"
+        };
 
 
-            if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
+        private bool HasStartDate(InternalItemsQuery query)
+        {
+            if (_programExcludeParentTypes.Contains(query.ParentType))
             {
             {
                 return false;
                 return false;
             }
             }
@@ -2234,13 +2222,7 @@ namespace Emby.Server.Implementations.Data
                 return true;
                 return true;
             }
             }
 
 
-            var types = new string[]
-            {
-                "Program",
-                "LiveTvProgram"
-            };
-
-            return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase));
+            return query.IncludeItemTypes.Any(x => _startDateTypes.Contains(x));
         }
         }
 
 
         private bool HasEpisodeAttributes(InternalItemsQuery query)
         private bool HasEpisodeAttributes(InternalItemsQuery query)
@@ -2263,16 +2245,26 @@ namespace Emby.Server.Implementations.Data
             return query.IncludeItemTypes.Contains("Trailer", StringComparer.OrdinalIgnoreCase);
             return query.IncludeItemTypes.Contains("Trailer", StringComparer.OrdinalIgnoreCase);
         }
         }
 
 
-        private bool HasArtistFields(InternalItemsQuery query)
+
+        private static readonly HashSet<string> _artistExcludeParentTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
         {
         {
-            var excludeParentTypes = new string[]
-            {
-                "Series",
-                "Season",
-                "PhotoAlbum"
-            };
+            "Series",
+            "Season",
+            "PhotoAlbum"
+        };
 
 
-            if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
+        private static readonly HashSet<string> _artistsTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
+        {
+            "Audio",
+            "MusicAlbum",
+            "MusicVideo",
+            "AudioBook",
+            "AudioPodcast"
+        };
+
+        private bool HasArtistFields(InternalItemsQuery query)
+        {
+            if (_artistExcludeParentTypes.Contains(query.ParentType))
             {
             {
                 return false;
                 return false;
             }
             }
@@ -2282,18 +2274,18 @@ namespace Emby.Server.Implementations.Data
                 return true;
                 return true;
             }
             }
 
 
-            var types = new string[]
-            {
-                "Audio",
-                "MusicAlbum",
-                "MusicVideo",
-                "AudioBook",
-                "AudioPodcast"
-            };
-
-            return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase));
+            return query.IncludeItemTypes.Any(x => _artistsTypes.Contains(x));
         }
         }
 
 
+        private static readonly HashSet<string> _seriesTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
+        {
+            "Audio",
+            "MusicAlbum",
+            "MusicVideo",
+            "AudioBook",
+            "AudioPodcast"
+        };
+
         private bool HasSeriesFields(InternalItemsQuery query)
         private bool HasSeriesFields(InternalItemsQuery query)
         {
         {
             if (string.Equals(query.ParentType, "PhotoAlbum", StringComparison.OrdinalIgnoreCase))
             if (string.Equals(query.ParentType, "PhotoAlbum", StringComparison.OrdinalIgnoreCase))
@@ -2306,15 +2298,7 @@ namespace Emby.Server.Implementations.Data
                 return true;
                 return true;
             }
             }
 
 
-            var types = new string[]
-            {
-                "Book",
-                "AudioBook",
-                "Episode",
-                "Season"
-            };
-
-            return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase));
+            return query.IncludeItemTypes.Any(x => _seriesTypes.Contains(x));
         }
         }
 
 
         private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns)
         private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns)
@@ -2325,7 +2309,7 @@ namespace Emby.Server.Implementations.Data
             {
             {
                 if (!HasField(query, field))
                 if (!HasField(query, field))
                 {
                 {
-                    foreach (var fieldToRemove in GetColumnNamesFromField(field).ToList())
+                    foreach (var fieldToRemove in GetColumnNamesFromField(field))
                     {
                     {
                         list.Remove(fieldToRemove);
                         list.Remove(fieldToRemove);
                     }
                     }
@@ -2419,11 +2403,14 @@ namespace Emby.Server.Implementations.Data
 
 
                 list.Add(builder.ToString());
                 list.Add(builder.ToString());
 
 
-                var excludeIds = query.ExcludeItemIds.ToList();
-                excludeIds.Add(item.Id);
-                excludeIds.AddRange(item.ExtraIds);
+                var oldLen = query.ExcludeItemIds.Length;
+                var newLen = oldLen + item.ExtraIds.Length + 1;
+                var excludeIds = new Guid[newLen];
+                query.ExcludeItemIds.CopyTo(excludeIds, 0);
+                excludeIds[oldLen] = item.Id;
+                item.ExtraIds.CopyTo(excludeIds, oldLen + 1);
 
 
-                query.ExcludeItemIds = excludeIds.ToArray();
+                query.ExcludeItemIds = excludeIds;
                 query.ExcludeProviderIds = item.ProviderIds;
                 query.ExcludeProviderIds = item.ProviderIds;
             }
             }
 
 
@@ -2735,6 +2722,7 @@ namespace Emby.Server.Implementations.Data
                     {
                     {
                         continue;
                         continue;
                     }
                     }
+
                     if (item.GetProviderId(providerId.Key) == providerId.Value)
                     if (item.GetProviderId(providerId.Key) == providerId.Value)
                     {
                     {
                         if (newItem.SourceType == SourceType.Library)
                         if (newItem.SourceType == SourceType.Library)
@@ -4952,7 +4940,12 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
                 return result;
                 return result;
             }
             }
 
 
-            return new[] { value }.Where(IsValidType);
+            if (IsValidType(value))
+            {
+                return new[] { value };
+            }
+
+            return Array.Empty<string>();
         }
         }
 
 
         public void DeleteItem(Guid id, CancellationToken cancellationToken)
         public void DeleteItem(Guid id, CancellationToken cancellationToken)

+ 10 - 10
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -1225,9 +1225,9 @@ namespace Emby.Server.Implementations.Library
         /// <exception cref="ArgumentNullException">id</exception>
         /// <exception cref="ArgumentNullException">id</exception>
         public BaseItem GetItemById(Guid id)
         public BaseItem GetItemById(Guid id)
         {
         {
-            if (id.Equals(Guid.Empty))
+            if (id == Guid.Empty)
             {
             {
-                throw new ArgumentNullException(nameof(id));
+                throw new ArgumentException(nameof(id), "Guid can't be empty");
             }
             }
 
 
             if (LibraryItemsCache.TryGetValue(id, out BaseItem item))
             if (LibraryItemsCache.TryGetValue(id, out BaseItem item))
@@ -1237,8 +1237,6 @@ namespace Emby.Server.Implementations.Library
 
 
             item = RetrieveItem(id);
             item = RetrieveItem(id);
 
 
-            //_logger.LogDebug("GetitemById {0}", id);
-
             if (item != null)
             if (item != null)
             {
             {
                 RegisterItem(item);
                 RegisterItem(item);
@@ -2005,9 +2003,7 @@ namespace Emby.Server.Implementations.Library
                    .FirstOrDefault();
                    .FirstOrDefault();
             }
             }
 
 
-            var options = collectionFolder == null ? new LibraryOptions() : collectionFolder.GetLibraryOptions();
-
-            return options;
+            return collectionFolder == null ? new LibraryOptions() : collectionFolder.GetLibraryOptions();
         }
         }
 
 
         public string GetContentType(BaseItem item)
         public string GetContentType(BaseItem item)
@@ -2017,11 +2013,13 @@ namespace Emby.Server.Implementations.Library
             {
             {
                 return configuredContentType;
                 return configuredContentType;
             }
             }
+
             configuredContentType = GetConfiguredContentType(item, true);
             configuredContentType = GetConfiguredContentType(item, true);
             if (!string.IsNullOrEmpty(configuredContentType))
             if (!string.IsNullOrEmpty(configuredContentType))
             {
             {
                 return configuredContentType;
                 return configuredContentType;
             }
             }
+
             return GetInheritedContentType(item);
             return GetInheritedContentType(item);
         }
         }
 
 
@@ -2056,6 +2054,7 @@ namespace Emby.Server.Implementations.Library
             {
             {
                 return collectionFolder.CollectionType;
                 return collectionFolder.CollectionType;
             }
             }
+
             return GetContentTypeOverride(item.ContainingFolderPath, inheritConfiguredPath);
             return GetContentTypeOverride(item.ContainingFolderPath, inheritConfiguredPath);
         }
         }
 
 
@@ -2066,6 +2065,7 @@ namespace Emby.Server.Implementations.Library
             {
             {
                 return nameValuePair.Value;
                 return nameValuePair.Value;
             }
             }
+
             return null;
             return null;
         }
         }
 
 
@@ -2108,9 +2108,9 @@ namespace Emby.Server.Implementations.Library
             string viewType,
             string viewType,
             string sortName)
             string sortName)
         {
         {
-            var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views");
-
-            path = Path.Combine(path, _fileSystem.GetValidFilename(viewType));
+            var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath,
+                                    "views",
+                                    _fileSystem.GetValidFilename(viewType));
 
 
             var id = GetNewItemId(path + "_namedview_" + name, typeof(UserView));
             var id = GetNewItemId(path + "_namedview_" + name, typeof(UserView));
 
 

+ 2 - 2
Emby.Server.Implementations/Library/UserManager.cs

@@ -171,9 +171,9 @@ namespace Emby.Server.Implementations.Library
         /// <exception cref="ArgumentNullException"></exception>
         /// <exception cref="ArgumentNullException"></exception>
         public User GetUserById(Guid id)
         public User GetUserById(Guid id)
         {
         {
-            if (id.Equals(Guid.Empty))
+            if (id == Guid.Empty)
             {
             {
-                throw new ArgumentNullException(nameof(id));
+                throw new ArgumentException(nameof(id), "Guid can't be empty");
             }
             }
 
 
             return Users.FirstOrDefault(u => u.Id == id);
             return Users.FirstOrDefault(u => u.Id == id);

+ 23 - 9
MediaBrowser.Api/BaseApiService.cs

@@ -9,6 +9,7 @@ using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
+using MediaBrowser.Model.Querying;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
 namespace MediaBrowser.Api
 namespace MediaBrowser.Api
@@ -118,8 +119,7 @@ namespace MediaBrowser.Api
         {
         {
             var options = new DtoOptions();
             var options = new DtoOptions();
 
 
-            var hasFields = request as IHasItemFields;
-            if (hasFields != null)
+            if (request is IHasItemFields hasFields)
             {
             {
                 options.Fields = hasFields.GetItemFields();
                 options.Fields = hasFields.GetItemFields();
             }
             }
@@ -133,9 +133,11 @@ namespace MediaBrowser.Api
                     client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
                     client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
                     client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1)
                     client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1)
                 {
                 {
-                    var list = options.Fields.ToList();
-                    list.Add(Model.Querying.ItemFields.RecursiveItemCount);
-                    options.Fields = list.ToArray();
+                    int oldLen = options.Fields.Length;
+                    var arr = new ItemFields[oldLen + 1];
+                    options.Fields.CopyTo(arr, 0);
+                    arr[oldLen] = Model.Querying.ItemFields.RecursiveItemCount;
+                    options.Fields = arr;
                 }
                 }
 
 
                 if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
                 if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
@@ -146,9 +148,12 @@ namespace MediaBrowser.Api
                    client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("androidtv", StringComparison.OrdinalIgnoreCase) != -1)
                    client.IndexOf("androidtv", StringComparison.OrdinalIgnoreCase) != -1)
                 {
                 {
-                    var list = options.Fields.ToList();
-                    list.Add(Model.Querying.ItemFields.ChildCount);
-                    options.Fields = list.ToArray();
+
+                    int oldLen = options.Fields.Length;
+                    var arr = new ItemFields[oldLen + 1];
+                    options.Fields.CopyTo(arr, 0);
+                    arr[oldLen] = Model.Querying.ItemFields.ChildCount;
+                    options.Fields = arr;
                 }
                 }
             }
             }
 
 
@@ -167,7 +172,16 @@ namespace MediaBrowser.Api
 
 
                 if (!string.IsNullOrWhiteSpace(hasDtoOptions.EnableImageTypes))
                 if (!string.IsNullOrWhiteSpace(hasDtoOptions.EnableImageTypes))
                 {
                 {
-                    options.ImageTypes = (hasDtoOptions.EnableImageTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(v => (ImageType)Enum.Parse(typeof(ImageType), v, true)).ToArray();
+                    if (string.IsNullOrEmpty(hasDtoOptions.EnableImageTypes))
+                    {
+                        options.ImageTypes = Array.Empty<ImageType>();
+                    }
+                    else
+                    {
+                        options.ImageTypes = hasDtoOptions.EnableImageTypes.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries)
+                                                                            .Select(v => (ImageType)Enum.Parse(typeof(ImageType), v, true))
+                                                                            .ToArray();
+                    }
                 }
                 }
             }
             }
 
 

+ 3 - 6
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -155,7 +155,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="request">The request.</param>
         private QueryResult<BaseItemDto> GetItems(GetItems request)
         private QueryResult<BaseItemDto> GetItems(GetItems request)
         {
         {
-            var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
+            var user = request.UserId == Guid.Empty ? null : _userManager.GetUserById(request.UserId);
 
 
             var dtoOptions = GetDtoOptions(_authContext, request);
             var dtoOptions = GetDtoOptions(_authContext, request);
 
 
@@ -190,11 +190,8 @@ namespace MediaBrowser.Api.UserLibrary
         /// </summary>
         /// </summary>
         private QueryResult<BaseItem> GetQueryResult(GetItems request, DtoOptions dtoOptions, User user)
         private QueryResult<BaseItem> GetQueryResult(GetItems request, DtoOptions dtoOptions, User user)
         {
         {
-            if (string.Equals(request.IncludeItemTypes, "Playlist", StringComparison.OrdinalIgnoreCase))
-            {
-                request.ParentId = null;
-            }
-            else if (string.Equals(request.IncludeItemTypes, "BoxSet", StringComparison.OrdinalIgnoreCase))
+            if (string.Equals(request.IncludeItemTypes, "Playlist", StringComparison.OrdinalIgnoreCase)
+                || string.Equals(request.IncludeItemTypes, "BoxSet", StringComparison.OrdinalIgnoreCase))
             {
             {
                 request.ParentId = null;
                 request.ParentId = null;
             }
             }