MemoryStream optimizations
This commit is contained in:
parent
75bb127599
commit
371a09c60b
|
@ -1,3 +1,5 @@
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -22,7 +24,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
{
|
{
|
||||||
object configuration;
|
object configuration;
|
||||||
|
|
||||||
byte[] buffer = null;
|
byte[]? buffer = null;
|
||||||
|
|
||||||
// Use try/catch to avoid the extra file system lookup using File.Exists
|
// Use try/catch to avoid the extra file system lookup using File.Exists
|
||||||
try
|
try
|
||||||
|
@ -36,19 +38,23 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
configuration = Activator.CreateInstance(type);
|
configuration = Activator.CreateInstance(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
using var stream = new MemoryStream();
|
using var stream = new MemoryStream(buffer?.Length ?? 0);
|
||||||
xmlSerializer.SerializeToStream(configuration, stream);
|
xmlSerializer.SerializeToStream(configuration, stream);
|
||||||
|
|
||||||
// Take the object we just got and serialize it back to bytes
|
// Take the object we just got and serialize it back to bytes
|
||||||
var newBytes = stream.ToArray();
|
byte[] newBytes = stream.GetBuffer();
|
||||||
|
int newBytesLen = (int)stream.Length;
|
||||||
|
|
||||||
// If the file didn't exist before, or if something has changed, re-save
|
// If the file didn't exist before, or if something has changed, re-save
|
||||||
if (buffer == null || !buffer.SequenceEqual(newBytes))
|
if (buffer == null || !newBytes.AsSpan(0, newBytesLen).SequenceEqual(buffer))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||||
|
|
||||||
// Save it after load in case we got new items
|
// Save it after load in case we got new items
|
||||||
File.WriteAllBytes(path, newBytes);
|
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
|
{
|
||||||
|
fs.Write(newBytes, 0, newBytesLen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return configuration;
|
return configuration;
|
||||||
|
|
|
@ -105,7 +105,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
responseHeaders = new Dictionary<string, string>();
|
responseHeaders = new Dictionary<string, string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out string expires))
|
if (addCachePrevention && !responseHeaders.TryGetValue(HeaderNames.Expires, out _))
|
||||||
{
|
{
|
||||||
responseHeaders[HeaderNames.Expires] = "0";
|
responseHeaders[HeaderNames.Expires] = "0";
|
||||||
}
|
}
|
||||||
|
@ -326,7 +326,8 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
return GetHttpResult(request, ms, contentType, true, responseHeaders);
|
return GetHttpResult(request, ms, contentType, true, responseHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IHasHeaders GetCompressedResult(byte[] content,
|
private IHasHeaders GetCompressedResult(
|
||||||
|
byte[] content,
|
||||||
string requestedCompressionType,
|
string requestedCompressionType,
|
||||||
IDictionary<string, string> responseHeaders,
|
IDictionary<string, string> responseHeaders,
|
||||||
bool isHeadRequest,
|
bool isHeadRequest,
|
||||||
|
|
|
@ -95,13 +95,13 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
|
|
||||||
if (bytes != null)
|
if (bytes != null)
|
||||||
{
|
{
|
||||||
await responseStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
|
await responseStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using (var src = SourceStream)
|
using (var src = SourceStream)
|
||||||
{
|
{
|
||||||
await src.CopyToAsync(responseStream).ConfigureAwait(false);
|
await src.CopyToAsync(responseStream, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.Serialization
|
||||||
/// <returns>System.Object.</returns>
|
/// <returns>System.Object.</returns>
|
||||||
public object DeserializeFromBytes(Type type, byte[] buffer)
|
public object DeserializeFromBytes(Type type, byte[] buffer)
|
||||||
{
|
{
|
||||||
using (var stream = new MemoryStream(buffer))
|
using (var stream = new MemoryStream(buffer, 0, buffer.Length, false, true))
|
||||||
{
|
{
|
||||||
return DeserializeFromStream(type, stream);
|
return DeserializeFromStream(type, stream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -969,7 +969,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
var text = await reader.ReadToEndAsync().ConfigureAwait(false);
|
var text = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
var bytes = Convert.FromBase64String(text);
|
var bytes = Convert.FromBase64String(text);
|
||||||
return new MemoryStream(bytes) { Position = 0 };
|
return new MemoryStream(bytes, 0, bytes.Length, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImageInfo? GetImageInfo(BaseItem item, ItemImageInfo info, int? imageIndex)
|
private ImageInfo? GetImageInfo(BaseItem item, ItemImageInfo info, int? imageIndex)
|
||||||
|
|
|
@ -124,6 +124,8 @@ namespace MediaBrowser.Providers.Manager
|
||||||
var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false);
|
var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false);
|
||||||
|
|
||||||
// If there are more than one output paths, the stream will need to be seekable
|
// If there are more than one output paths, the stream will need to be seekable
|
||||||
|
if (paths.Length > 1 && !source.CanSeek)
|
||||||
|
{
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
await using (source.ConfigureAwait(false))
|
await using (source.ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
|
@ -131,6 +133,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
source = memoryStream;
|
source = memoryStream;
|
||||||
|
}
|
||||||
|
|
||||||
var currentImage = GetCurrentImage(item, type, index);
|
var currentImage = GetCurrentImage(item, type, index);
|
||||||
var currentImageIsLocalFile = currentImage != null && currentImage.IsLocalFile;
|
var currentImageIsLocalFile = currentImage != null && currentImage.IsLocalFile;
|
||||||
|
@ -140,20 +143,21 @@ namespace MediaBrowser.Providers.Manager
|
||||||
|
|
||||||
await using (source.ConfigureAwait(false))
|
await using (source.ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
var currentPathIndex = 0;
|
for (int i = 0; i < paths.Length; i++)
|
||||||
|
{
|
||||||
foreach (var path in paths)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
source.Position = 0;
|
source.Position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
string retryPath = null;
|
string retryPath = null;
|
||||||
if (paths.Length == retryPaths.Length)
|
if (paths.Length == retryPaths.Length)
|
||||||
{
|
{
|
||||||
retryPath = retryPaths[currentPathIndex];
|
retryPath = retryPaths[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
var savedPath = await SaveImageToLocation(source, path, retryPath, cancellationToken).ConfigureAwait(false);
|
var savedPath = await SaveImageToLocation(source, paths[i], retryPath, cancellationToken).ConfigureAwait(false);
|
||||||
savedPaths.Add(savedPath);
|
savedPaths.Add(savedPath);
|
||||||
currentPathIndex++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +228,6 @@ namespace MediaBrowser.Providers.Manager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source.Position = 0;
|
|
||||||
await SaveImageToLocation(source, retryPath, cancellationToken).ConfigureAwait(false);
|
await SaveImageToLocation(source, retryPath, cancellationToken).ConfigureAwait(false);
|
||||||
return retryPath;
|
return retryPath;
|
||||||
}
|
}
|
||||||
|
@ -253,7 +256,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
|
|
||||||
await using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
|
await using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
|
||||||
{
|
{
|
||||||
await source.CopyToAsync(fs, IODefaults.CopyToBufferSize, cancellationToken).ConfigureAwait(false);
|
await source.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_config.Configuration.SaveMetadataHidden)
|
if (_config.Configuration.SaveMetadataHidden)
|
||||||
|
|
|
@ -148,7 +148,7 @@ namespace MediaBrowser.Providers.Subtitles
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var parts = subtitleId.Split(new[] { '_' }, 2);
|
var parts = subtitleId.Split(new[] { '_' }, 2);
|
||||||
var provider = GetProvider(parts.First());
|
var provider = GetProvider(parts[0]);
|
||||||
|
|
||||||
var saveInMediaFolder = libraryOptions.SaveSubtitlesWithMedia;
|
var saveInMediaFolder = libraryOptions.SaveSubtitlesWithMedia;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user