mirror of
https://github.com/ppy/osu
synced 2025-01-10 08:09:40 +00:00
Add optimised existing check earlier in import process
This commit is contained in:
parent
15af28d2a0
commit
e493685c14
@ -317,7 +317,11 @@ namespace osu.Game.Database
|
||||
/// </remarks>
|
||||
protected virtual string ComputeHash(TModel item, ArchiveReader reader = null)
|
||||
{
|
||||
// for now, concatenate all .osu files in the set to create a unique hash.
|
||||
if (reader != null)
|
||||
// fast hashing for cases where the item's files may not be populated.
|
||||
return computeHashFast(reader);
|
||||
|
||||
// for now, concatenate all hashable files in the set to create a unique hash.
|
||||
MemoryStream hashable = new MemoryStream();
|
||||
|
||||
foreach (TFileModel file in item.Files.Where(f => HashableFileTypes.Any(ext => f.Filename.EndsWith(ext, StringComparison.OrdinalIgnoreCase))).OrderBy(f => f.Filename))
|
||||
@ -329,12 +333,25 @@ namespace osu.Game.Database
|
||||
if (hashable.Length > 0)
|
||||
return hashable.ComputeSHA2Hash();
|
||||
|
||||
if (reader != null)
|
||||
return reader.Name.ComputeSHA2Hash();
|
||||
|
||||
return item.Hash;
|
||||
}
|
||||
|
||||
private string computeHashFast(ArchiveReader reader)
|
||||
{
|
||||
MemoryStream hashable = new MemoryStream();
|
||||
|
||||
foreach (var file in reader.Filenames.Where(f => HashableFileTypes.Any(ext => f.EndsWith(ext, StringComparison.OrdinalIgnoreCase))).OrderBy(f => f))
|
||||
{
|
||||
using (Stream s = reader.GetStream(file))
|
||||
s.CopyTo(hashable);
|
||||
}
|
||||
|
||||
if (hashable.Length > 0)
|
||||
return hashable.ComputeSHA2Hash();
|
||||
|
||||
return reader.Name.ComputeSHA2Hash();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Silently import an item from a <typeparamref name="TModel"/>.
|
||||
/// </summary>
|
||||
@ -348,6 +365,21 @@ namespace osu.Game.Database
|
||||
|
||||
delayEvents();
|
||||
|
||||
if (archive != null)
|
||||
{
|
||||
// fast bail to improve large import performance.
|
||||
item.Hash = computeHashFast(archive);
|
||||
|
||||
var fastExisting = CheckForExisting(item);
|
||||
|
||||
if (fastExisting != null)
|
||||
{
|
||||
// bare minimum comparisons
|
||||
if (getFilenames(fastExisting.Files).SequenceEqual(getShortenedFilenames(archive).Select(p => p.shortened)))
|
||||
return fastExisting;
|
||||
}
|
||||
}
|
||||
|
||||
void rollback()
|
||||
{
|
||||
if (!Delete(item))
|
||||
@ -644,18 +676,14 @@ namespace osu.Game.Database
|
||||
{
|
||||
var fileInfos = new List<TFileModel>();
|
||||
|
||||
string prefix = reader.Filenames.GetCommonPrefix();
|
||||
if (!(prefix.EndsWith('/') || prefix.EndsWith('\\')))
|
||||
prefix = string.Empty;
|
||||
|
||||
// import files to manager
|
||||
foreach (string file in reader.Filenames)
|
||||
foreach (var filenames in getShortenedFilenames(reader))
|
||||
{
|
||||
using (Stream s = reader.GetStream(file))
|
||||
using (Stream s = reader.GetStream(filenames.original))
|
||||
{
|
||||
fileInfos.Add(new TFileModel
|
||||
{
|
||||
Filename = file.Substring(prefix.Length).ToStandardisedPath(),
|
||||
Filename = filenames.shortened,
|
||||
FileInfo = files.Add(s)
|
||||
});
|
||||
}
|
||||
@ -664,6 +692,17 @@ namespace osu.Game.Database
|
||||
return fileInfos;
|
||||
}
|
||||
|
||||
private IEnumerable<(string original, string shortened)> getShortenedFilenames(ArchiveReader reader)
|
||||
{
|
||||
string prefix = reader.Filenames.GetCommonPrefix();
|
||||
if (!(prefix.EndsWith('/') || prefix.EndsWith('\\')))
|
||||
prefix = string.Empty;
|
||||
|
||||
// import files to manager
|
||||
foreach (string file in reader.Filenames)
|
||||
yield return (file, file.Substring(prefix.Length).ToStandardisedPath());
|
||||
}
|
||||
|
||||
#region osu-stable import
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
Reference in New Issue
Block a user