From b6964589faeea411350298dedfd04bdf0036c651 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Mon, 21 Jan 2019 12:57:40 -0600 Subject: [PATCH] Slightly speed up IntegrityVerificationStorage --- src/LibHac/IO/IntegrityVerificationStorage.cs | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/LibHac/IO/IntegrityVerificationStorage.cs b/src/LibHac/IO/IntegrityVerificationStorage.cs index dbf91330..050173d7 100644 --- a/src/LibHac/IO/IntegrityVerificationStorage.cs +++ b/src/LibHac/IO/IntegrityVerificationStorage.cs @@ -31,6 +31,7 @@ namespace LibHac.IO BlockValidities = new Validity[SectorCount]; } + // todo Take short path when integrity checks are disabled private void ReadImpl(Span destination, long offset, IntegrityCheckLevel integrityCheckLevel) { int count = destination.Length; @@ -38,15 +39,29 @@ namespace LibHac.IO if (count < 0 || count > SectorSize) throw new ArgumentOutOfRangeException(nameof(destination), "Length is invalid."); - Span hashBuffer = stackalloc byte[DigestSize]; + + long blockIndex = offset / SectorSize; - long hashPos = blockIndex * DigestSize; if (BlockValidities[blockIndex] == Validity.Invalid && integrityCheckLevel == IntegrityCheckLevel.ErrorOnInvalid) { throw new InvalidDataException("Hash error!"); } + if (Type != IntegrityStorageType.Save && integrityCheckLevel == IntegrityCheckLevel.None) + { + BaseStorage.Read(destination, offset); + return; + } + + if (BlockValidities[blockIndex] != Validity.Unchecked) + { + BaseStorage.Read(destination, offset); + return; + } + + Span hashBuffer = stackalloc byte[DigestSize]; + long hashPos = blockIndex * DigestSize; HashStorage.Read(hashBuffer, hashPos); if (Type == IntegrityStorageType.Save && Util.IsEmpty(hashBuffer)) @@ -59,10 +74,9 @@ namespace LibHac.IO byte[] dataBuffer = ArrayPool.Shared.Rent(SectorSize); try { - BaseStorage.Read(dataBuffer, offset, count, 0); - dataBuffer.AsSpan(0, count).CopyTo(destination); + BaseStorage.Read(destination, offset); + destination.CopyTo(dataBuffer); - if (integrityCheckLevel == IntegrityCheckLevel.None) return; if (BlockValidities[blockIndex] != Validity.Unchecked) return; int bytesToHash = SectorSize;