Merge pull request #848 from Bond-009/perf

Minor changes to reduce allocations
This commit is contained in:
Joshua M. Boniface
2019-02-19 21:24:51 -05:00
committed by GitHub
21 changed files with 303 additions and 304 deletions

View File

@@ -224,7 +224,7 @@ namespace Emby.Server.Implementations.Data
});
}
db.ExecuteAll(string.Join(";", queries.ToArray()));
db.ExecuteAll(string.Join(";", queries));
Logger.LogInformation("PRAGMA synchronous=" + db.Query("PRAGMA synchronous").SelectScalarString().First());
}
@@ -232,23 +232,6 @@ namespace Emby.Server.Implementations.Data
protected virtual int? CacheSize => null;
internal static void CheckOk(int rc)
{
string msg = "";
if (raw.SQLITE_OK != rc)
{
throw CreateException((ErrorCode)rc, msg);
}
}
internal static Exception CreateException(ErrorCode rc, string msg)
{
var exp = new Exception(msg);
return exp;
}
private bool _disposed;
protected void CheckDisposed()
{
@@ -375,13 +358,6 @@ namespace Emby.Server.Implementations.Data
}
}
public class DummyToken : IDisposable
{
public void Dispose()
{
}
}
public static IDisposable Read(this ReaderWriterLockSlim obj)
{
//if (BaseSqliteRepository.ThreadSafeMode > 0)
@@ -390,6 +366,7 @@ namespace Emby.Server.Implementations.Data
//}
return new WriteLockToken(obj);
}
public static IDisposable Write(this ReaderWriterLockSlim obj)
{
//if (BaseSqliteRepository.ThreadSafeMode > 0)

View File

@@ -536,7 +536,7 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException(nameof(item));
}
SaveItems(new List<BaseItem> { item }, cancellationToken);
SaveItems(new [] { item }, cancellationToken);
}
public void SaveImages(BaseItem item)
@@ -576,7 +576,7 @@ namespace Emby.Server.Implementations.Data
/// or
/// cancellationToken
/// </exception>
public void SaveItems(List<BaseItem> items, CancellationToken cancellationToken)
public void SaveItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken)
{
if (items == null)
{
@@ -587,7 +587,7 @@ namespace Emby.Server.Implementations.Data
CheckDisposed();
var tuples = new List<Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>>();
var tuples = new List<(BaseItem, List<Guid>, BaseItem, string, List<string>)>();
foreach (var item in items)
{
var ancestorIds = item.SupportsAncestors ?
@@ -599,7 +599,7 @@ namespace Emby.Server.Implementations.Data
var userdataKey = item.GetUserDataKeys().FirstOrDefault();
var inheritedTags = item.GetInheritedTags();
tuples.Add(new Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>(item, ancestorIds, topParent, userdataKey, inheritedTags));
tuples.Add((item, ancestorIds, topParent, userdataKey, inheritedTags));
}
using (WriteLock.Write())
@@ -615,7 +615,7 @@ namespace Emby.Server.Implementations.Data
}
}
private void SaveItemsInTranscation(IDatabaseConnection db, List<Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>> tuples)
private void SaveItemsInTranscation(IDatabaseConnection db, IEnumerable<(BaseItem, List<Guid>, BaseItem, string, List<string>)> tuples)
{
var statements = PrepareAllSafe(db, new string[]
{
@@ -966,7 +966,7 @@ namespace Emby.Server.Implementations.Data
if (item.ExtraIds.Length > 0)
{
saveItemStatement.TryBind("@ExtraIds", string.Join("|", item.ExtraIds.ToArray()));
saveItemStatement.TryBind("@ExtraIds", string.Join("|", item.ExtraIds));
}
else
{
@@ -1183,9 +1183,9 @@ namespace Emby.Server.Implementations.Data
/// <exception cref="ArgumentException"></exception>
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();
@@ -2079,14 +2079,14 @@ namespace Emby.Server.Implementations.Data
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.IsFavorite.HasValue
|| query.IsResumable.HasValue
@@ -2094,9 +2094,9 @@ namespace Emby.Server.Implementations.Data
|| query.IsLiked.HasValue;
}
private readonly List<ItemFields> allFields = Enum.GetNames(typeof(ItemFields))
private readonly ItemFields[] _allFields = Enum.GetNames(typeof(ItemFields))
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
.ToList();
.ToArray();
private string[] GetColumnNamesFromField(ItemFields field)
{
@@ -2151,18 +2151,26 @@ namespace Emby.Server.Implementations.Data
}
}
private static readonly HashSet<string> _programExcludeParentTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Series",
"Season",
"MusicAlbum",
"MusicArtist",
"PhotoAlbum"
};
private static readonly HashSet<string> _programTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Program",
"TvChannel",
"LiveTvProgram",
"LiveTvTvChannel"
};
private bool HasProgramAttributes(InternalItemsQuery query)
{
var excludeParentTypes = new string[]
{
"Series",
"Season",
"MusicAlbum",
"MusicArtist",
"PhotoAlbum"
};
if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
if (_programExcludeParentTypes.Contains(query.ParentType))
{
return false;
}
@@ -2172,29 +2180,18 @@ namespace Emby.Server.Implementations.Data
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 static readonly HashSet<string> _serviceTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"TvChannel",
"LiveTvTvChannel"
};
private bool HasServiceName(InternalItemsQuery query)
{
var excludeParentTypes = new string[]
{
"Series",
"Season",
"MusicAlbum",
"MusicArtist",
"PhotoAlbum"
};
if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
if (_programExcludeParentTypes.Contains(query.ParentType))
{
return false;
}
@@ -2204,27 +2201,18 @@ namespace Emby.Server.Implementations.Data
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 static readonly HashSet<string> _startDateTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Program",
"LiveTvProgram"
};
private bool HasStartDate(InternalItemsQuery query)
{
var excludeParentTypes = new string[]
{
"Series",
"Season",
"MusicAlbum",
"MusicArtist",
"PhotoAlbum"
};
if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
if (_programExcludeParentTypes.Contains(query.ParentType))
{
return false;
}
@@ -2234,13 +2222,7 @@ namespace Emby.Server.Implementations.Data
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)
@@ -2263,16 +2245,26 @@ namespace Emby.Server.Implementations.Data
return query.IncludeItemTypes.Contains("Trailer", StringComparer.OrdinalIgnoreCase);
}
private static readonly HashSet<string> _artistExcludeParentTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Series",
"Season",
"PhotoAlbum"
};
private static readonly HashSet<string> _artistsTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Audio",
"MusicAlbum",
"MusicVideo",
"AudioBook",
"AudioPodcast"
};
private bool HasArtistFields(InternalItemsQuery query)
{
var excludeParentTypes = new string[]
{
"Series",
"Season",
"PhotoAlbum"
};
if (excludeParentTypes.Contains(query.ParentType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
if (_artistExcludeParentTypes.Contains(query.ParentType))
{
return false;
}
@@ -2282,18 +2274,18 @@ namespace Emby.Server.Implementations.Data
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)
{
if (string.Equals(query.ParentType, "PhotoAlbum", StringComparison.OrdinalIgnoreCase))
@@ -2306,26 +2298,18 @@ namespace Emby.Server.Implementations.Data
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 List<string> GetFinalColumnsToSelect(InternalItemsQuery query, IEnumerable<string> startColumns)
{
var list = startColumns.ToList();
foreach (var field in allFields)
foreach (var field in _allFields)
{
if (!HasField(query, field))
{
foreach (var fieldToRemove in GetColumnNamesFromField(field).ToList())
foreach (var fieldToRemove in GetColumnNamesFromField(field))
{
list.Remove(fieldToRemove);
}
@@ -2419,11 +2403,14 @@ namespace Emby.Server.Implementations.Data
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;
}
@@ -2444,7 +2431,7 @@ namespace Emby.Server.Implementations.Data
list.Add(builder.ToString());
}
return list.ToArray();
return list;
}
private void BindSearchParams(InternalItemsQuery query, IStatement statement)
@@ -2723,18 +2710,17 @@ namespace Emby.Server.Implementations.Data
private void AddItem(List<BaseItem> items, BaseItem newItem)
{
var providerIds = newItem.ProviderIds.ToList();
for (var i = 0; i < items.Count; i++)
{
var item = items[i];
foreach (var providerId in providerIds)
foreach (var providerId in newItem.ProviderIds)
{
if (providerId.Key == MetadataProviders.TmdbCollection.ToString())
{
continue;
}
if (item.GetProviderId(providerId.Key) == providerId.Value)
{
if (newItem.SourceType == SourceType.Library)
@@ -2753,10 +2739,10 @@ namespace Emby.Server.Implementations.Data
{
var elapsed = (DateTime.UtcNow - startDate).TotalMilliseconds;
int slowThreshold = 1000;
int slowThreshold = 100;
#if DEBUG
slowThreshold = 250;
slowThreshold = 10;
#endif
if (elapsed >= slowThreshold)
@@ -2806,7 +2792,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses);
commandText += whereText
+ GetGroupBy(query)
@@ -2930,25 +2916,31 @@ namespace Emby.Server.Implementations.Data
private string GetOrderByText(InternalItemsQuery query)
{
var orderBy = query.OrderBy.ToList();
var enableOrderInversion = false;
if (query.SimilarTo != null && orderBy.Count == 0)
if (string.IsNullOrEmpty(query.SearchTerm))
{
orderBy.Add(new ValueTuple<string, SortOrder>("SimilarityScore", SortOrder.Descending));
orderBy.Add(new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending));
int oldLen = query.OrderBy.Length;
if (query.SimilarTo != null && oldLen == 0)
{
var arr = new (string, SortOrder)[oldLen + 2];
query.OrderBy.CopyTo(arr, 0);
arr[oldLen] = ("SimilarityScore", SortOrder.Descending);
arr[oldLen + 1] = (ItemSortBy.Random, SortOrder.Ascending);
query.OrderBy = arr;
}
}
else
{
query.OrderBy = new []
{
("SearchScore", SortOrder.Descending),
(ItemSortBy.SortName, SortOrder.Ascending)
};
}
if (!string.IsNullOrEmpty(query.SearchTerm))
{
orderBy = new List<(string, SortOrder)>();
orderBy.Add(new ValueTuple<string, SortOrder>("SearchScore", SortOrder.Descending));
orderBy.Add(new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending));
}
var orderBy = query.OrderBy;
query.OrderBy = orderBy.ToArray();
if (orderBy.Count == 0)
if (orderBy.Length == 0)
{
return string.Empty;
}
@@ -2957,6 +2949,7 @@ namespace Emby.Server.Implementations.Data
{
var columnMap = MapOrderByField(i.Item1, query);
var columnAscending = i.Item2 == SortOrder.Ascending;
const bool enableOrderInversion = false;
if (columnMap.Item2 && enableOrderInversion)
{
columnAscending = !columnAscending;
@@ -2968,7 +2961,7 @@ namespace Emby.Server.Implementations.Data
}));
}
private ValueTuple<string, bool> MapOrderByField(string name, InternalItemsQuery query)
private (string, bool) MapOrderByField(string name, InternalItemsQuery query)
{
if (string.Equals(name, ItemSortBy.AirTime, StringComparison.OrdinalIgnoreCase))
{
@@ -3218,7 +3211,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
" where " + string.Join(" AND ", whereClauses);
commandText += whereText
+ GetGroupBy(query)
@@ -4378,7 +4371,7 @@ namespace Emby.Server.Implementations.Data
}
else if (query.Years.Length > 1)
{
var val = string.Join(",", query.Years.ToArray());
var val = string.Join(",", query.Years);
whereClauses.Add("ProductionYear in (" + val + ")");
}
@@ -4952,7 +4945,12 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
return result;
}
return new[] { value }.Where(IsValidType);
if (IsValidType(value))
{
return new[] { value };
}
return Array.Empty<string>();
}
public void DeleteItem(Guid id, CancellationToken cancellationToken)
@@ -5215,32 +5213,32 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
}
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetAllArtists(InternalItemsQuery query)
{
return GetItemValues(query, new[] { 0, 1 }, typeof(MusicArtist).FullName);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetArtists(InternalItemsQuery query)
{
return GetItemValues(query, new[] { 0 }, typeof(MusicArtist).FullName);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetAlbumArtists(InternalItemsQuery query)
{
return GetItemValues(query, new[] { 1 }, typeof(MusicArtist).FullName);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetStudios(InternalItemsQuery query)
{
return GetItemValues(query, new[] { 3 }, typeof(Studio).FullName);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetGenres(InternalItemsQuery query)
{
return GetItemValues(query, new[] { 2 }, typeof(Genre).FullName);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetMusicGenres(InternalItemsQuery query)
{
return GetItemValues(query, new[] { 2 }, typeof(MusicGenre).FullName);
}
@@ -5317,7 +5315,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
}
}
private QueryResult<Tuple<BaseItem, ItemCounts>> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType)
private QueryResult<(BaseItem, ItemCounts)> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType)
{
if (query == null)
{
@@ -5335,7 +5333,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
var typeClause = itemValueTypes.Length == 1 ?
("Type=" + itemValueTypes[0].ToString(CultureInfo.InvariantCulture)) :
("Type in (" + string.Join(",", itemValueTypes.Select(i => i.ToString(CultureInfo.InvariantCulture)).ToArray()) + ")");
("Type in (" + string.Join(",", itemValueTypes.Select(i => i.ToString(CultureInfo.InvariantCulture))) + ")");
InternalItemsQuery typeSubQuery = null;
@@ -5363,11 +5361,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
whereClauses.Add("guid in (select ItemId from ItemValues where ItemValues.CleanValue=A.CleanName AND " + typeClause + ")");
var typeWhereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses);
itemCountColumnQuery += typeWhereText;
itemCountColumnQuery += " where " + string.Join(" AND ", whereClauses);
itemCountColumns = new Dictionary<string, string>()
{
@@ -5400,7 +5394,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
IsSeries = query.IsSeries
};
columns = GetFinalColumnsToSelect(query, columns.ToArray()).ToList();
columns = GetFinalColumnsToSelect(query, columns);
var commandText = "select "
+ string.Join(",", columns)
@@ -5492,8 +5486,8 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
return connection.RunInTransaction(db =>
{
var list = new List<Tuple<BaseItem, ItemCounts>>();
var result = new QueryResult<Tuple<BaseItem, ItemCounts>>();
var list = new List<(BaseItem, ItemCounts)>();
var result = new QueryResult<(BaseItem, ItemCounts)>();
var statements = PrepareAllSafe(db, statementTexts);
@@ -5531,7 +5525,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
var countStartColumn = columns.Count - 1;
list.Add(new Tuple<BaseItem, ItemCounts>(item, GetItemCounts(row, countStartColumn, typesToCount)));
list.Add((item, GetItemCounts(row, countStartColumn, typesToCount)));
}
}
@@ -6198,6 +6192,5 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
return item;
}
}
}

View File

@@ -90,7 +90,7 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
private IHasHeaders GetHttpResult(IRequest requestContext, Stream content, string contentType, bool addCachePrevention, IDictionary<string, string> responseHeaders = null)
{
var result = new StreamWriter(content, contentType, _logger);
var result = new StreamWriter(content, contentType);
if (responseHeaders == null)
{
@@ -131,7 +131,7 @@ namespace Emby.Server.Implementations.HttpServer
content = Array.Empty<byte>();
}
result = new StreamWriter(content, contentType, contentLength, _logger);
result = new StreamWriter(content, contentType, contentLength);
}
else
{
@@ -143,7 +143,7 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>();
}
if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string expires))
if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string _))
{
responseHeaders["Expires"] = "-1";
}
@@ -175,7 +175,7 @@ namespace Emby.Server.Implementations.HttpServer
bytes = Array.Empty<byte>();
}
result = new StreamWriter(bytes, contentType, contentLength, _logger);
result = new StreamWriter(bytes, contentType, contentLength);
}
else
{
@@ -187,7 +187,7 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>();
}
if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string expires))
if (addCachePrevention && !responseHeaders.TryGetValue("Expires", out string _))
{
responseHeaders["Expires"] = "-1";
}
@@ -277,9 +277,10 @@ namespace Emby.Server.Implementations.HttpServer
private object ToOptimizedResultInternal<T>(IRequest request, T dto, IDictionary<string, string> responseHeaders = null)
{
var contentType = request.ResponseContentType;
// TODO: @bond use Span and .Equals
var contentType = request.ResponseContentType?.Split(';')[0].Trim().ToLowerInvariant();
switch (GetRealContentType(contentType))
switch (contentType)
{
case "application/xml":
case "text/xml":
@@ -333,13 +334,13 @@ namespace Emby.Server.Implementations.HttpServer
if (isHeadRequest)
{
var result = new StreamWriter(Array.Empty<byte>(), contentType, contentLength, _logger);
var result = new StreamWriter(Array.Empty<byte>(), contentType, contentLength);
AddResponseHeaders(result, responseHeaders);
return result;
}
else
{
var result = new StreamWriter(content, contentType, contentLength, _logger);
var result = new StreamWriter(content, contentType, contentLength);
AddResponseHeaders(result, responseHeaders);
return result;
}
@@ -348,13 +349,19 @@ namespace Emby.Server.Implementations.HttpServer
private byte[] Compress(byte[] bytes, string compressionType)
{
if (string.Equals(compressionType, "br", StringComparison.OrdinalIgnoreCase))
{
return CompressBrotli(bytes);
}
if (string.Equals(compressionType, "deflate", StringComparison.OrdinalIgnoreCase))
{
return Deflate(bytes);
}
if (string.Equals(compressionType, "gzip", StringComparison.OrdinalIgnoreCase))
{
return GZip(bytes);
}
throw new NotSupportedException(compressionType);
}
@@ -390,13 +397,6 @@ namespace Emby.Server.Implementations.HttpServer
}
}
public static string GetRealContentType(string contentType)
{
return contentType == null
? null
: contentType.Split(';')[0].ToLowerInvariant().Trim();
}
private static string SerializeToXmlString(object from)
{
using (var ms = new MemoryStream())
@@ -603,7 +603,7 @@ namespace Emby.Server.Implementations.HttpServer
}
}
var hasHeaders = new StreamWriter(stream, contentType, _logger)
var hasHeaders = new StreamWriter(stream, contentType)
{
OnComplete = options.OnComplete,
OnError = options.OnError

View File

@@ -14,8 +14,6 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
public class StreamWriter : IAsyncStreamWriter, IHasHeaders
{
private ILogger Logger { get; set; }
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
@@ -45,7 +43,7 @@ namespace Emby.Server.Implementations.HttpServer
/// <param name="source">The source.</param>
/// <param name="contentType">Type of the content.</param>
/// <param name="logger">The logger.</param>
public StreamWriter(Stream source, string contentType, ILogger logger)
public StreamWriter(Stream source, string contentType)
{
if (string.IsNullOrEmpty(contentType))
{
@@ -53,7 +51,6 @@ namespace Emby.Server.Implementations.HttpServer
}
SourceStream = source;
Logger = logger;
Headers["Content-Type"] = contentType;
@@ -69,7 +66,7 @@ namespace Emby.Server.Implementations.HttpServer
/// <param name="source">The source.</param>
/// <param name="contentType">Type of the content.</param>
/// <param name="logger">The logger.</param>
public StreamWriter(byte[] source, string contentType, int contentLength, ILogger logger)
public StreamWriter(byte[] source, string contentType, int contentLength)
{
if (string.IsNullOrEmpty(contentType))
{
@@ -77,7 +74,6 @@ namespace Emby.Server.Implementations.HttpServer
}
SourceBytes = source;
Logger = logger;
Headers["Content-Type"] = contentType;

View File

@@ -1225,9 +1225,9 @@ namespace Emby.Server.Implementations.Library
/// <exception cref="ArgumentNullException">id</exception>
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))
@@ -1237,8 +1237,6 @@ namespace Emby.Server.Implementations.Library
item = RetrieveItem(id);
//_logger.LogDebug("GetitemById {0}", id);
if (item != null)
{
RegisterItem(item);
@@ -1333,7 +1331,7 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetItemIdsList(query);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetStudios(InternalItemsQuery query)
{
if (query.User != null)
{
@@ -1344,7 +1342,7 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetStudios(query);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetGenres(InternalItemsQuery query)
{
if (query.User != null)
{
@@ -1355,7 +1353,7 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetGenres(query);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetMusicGenres(InternalItemsQuery query)
{
if (query.User != null)
{
@@ -1366,7 +1364,7 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetMusicGenres(query);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetAllArtists(InternalItemsQuery query)
{
if (query.User != null)
{
@@ -1377,7 +1375,7 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetAllArtists(query);
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetArtists(InternalItemsQuery query)
{
if (query.User != null)
{
@@ -1421,7 +1419,7 @@ namespace Emby.Server.Implementations.Library
}
}
public QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query)
public QueryResult<(BaseItem, ItemCounts)> GetAlbumArtists(InternalItemsQuery query)
{
if (query.User != null)
{
@@ -1808,18 +1806,16 @@ namespace Emby.Server.Implementations.Library
/// <returns>Task.</returns>
public void CreateItems(IEnumerable<BaseItem> items, BaseItem parent, CancellationToken cancellationToken)
{
var list = items.ToList();
ItemRepository.SaveItems(items, cancellationToken);
ItemRepository.SaveItems(list, cancellationToken);
foreach (var item in list)
foreach (var item in items)
{
RegisterItem(item);
}
if (ItemAdded != null)
{
foreach (var item in list)
foreach (var item in items)
{
// With the live tv guide this just creates too much noise
if (item.SourceType != SourceType.Library)
@@ -1853,7 +1849,7 @@ namespace Emby.Server.Implementations.Library
/// <summary>
/// Updates the item.
/// </summary>
public void UpdateItems(List<BaseItem> items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken)
public void UpdateItems(IEnumerable<BaseItem> items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken)
{
foreach (var item in items)
{
@@ -1908,7 +1904,7 @@ namespace Emby.Server.Implementations.Library
/// <returns>Task.</returns>
public void UpdateItem(BaseItem item, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken)
{
UpdateItems(new List<BaseItem> { item }, parent, updateReason, cancellationToken);
UpdateItems(new [] { item }, parent, updateReason, cancellationToken);
}
/// <summary>
@@ -2005,9 +2001,7 @@ namespace Emby.Server.Implementations.Library
.FirstOrDefault();
}
var options = collectionFolder == null ? new LibraryOptions() : collectionFolder.GetLibraryOptions();
return options;
return collectionFolder == null ? new LibraryOptions() : collectionFolder.GetLibraryOptions();
}
public string GetContentType(BaseItem item)
@@ -2017,11 +2011,13 @@ namespace Emby.Server.Implementations.Library
{
return configuredContentType;
}
configuredContentType = GetConfiguredContentType(item, true);
if (!string.IsNullOrEmpty(configuredContentType))
{
return configuredContentType;
}
return GetInheritedContentType(item);
}
@@ -2056,6 +2052,7 @@ namespace Emby.Server.Implementations.Library
{
return collectionFolder.CollectionType;
}
return GetContentTypeOverride(item.ContainingFolderPath, inheritConfiguredPath);
}
@@ -2066,6 +2063,7 @@ namespace Emby.Server.Implementations.Library
{
return nameValuePair.Value;
}
return null;
}
@@ -2108,9 +2106,9 @@ namespace Emby.Server.Implementations.Library
string viewType,
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));

View File

@@ -168,9 +168,9 @@ namespace Emby.Server.Implementations.Library
/// <exception cref="ArgumentNullException"></exception>
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);

View File

@@ -184,7 +184,7 @@ namespace Emby.Server.Implementations.LiveTv
public QueryResult<BaseItem> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken)
{
var user = query.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(query.UserId);
var user = query.UserId == Guid.Empty ? null : _userManager.GetUserById(query.UserId);
var topFolder = GetInternalLiveTvFolder(cancellationToken);

View File

@@ -41,6 +41,27 @@ namespace Emby.Server.Implementations.Serialization
ServiceStack.Text.JsonSerializer.SerializeToStream(obj, obj.GetType(), stream);
}
/// <summary>
/// Serializes to stream.
/// </summary>
/// <param name="obj">The obj.</param>
/// <param name="stream">The stream.</param>
/// <exception cref="ArgumentNullException">obj</exception>
public void SerializeToStream<T>(T obj, Stream stream)
{
if (obj == null)
{
throw new ArgumentNullException(nameof(obj));
}
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
ServiceStack.Text.JsonSerializer.SerializeToStream<T>(obj, stream);
}
/// <summary>
/// Serializes to file.
/// </summary>