/// <inheritdoc /> /// <inheritdoc cref="DisposableBase.ThrowIfDisposed" /> /// <exception cref="ArgumentOutOfRangeException"> <paramref name="index" /> is lower than zero or higher/equals to the <see cref="Length" />. </exception> /// <exception cref="InvalidOperationException"> <see cref="EncryptedSafeByteCollection" /> instance is empty. </exception> /// <seealso cref="ISafeByte" /> public async Task <ISafeByte> GetAsync(int index) { if (index < 0 && index >= Length) { throw new ArgumentOutOfRangeException(nameof(index), index, $"Must be non-negative than zero and lower than length {Length}"); } ThrowIfDisposed(); EnsureNotEmpty(); ICollection <int> list = default; try { using (var key = await _encryptionKey.RevealDecryptedBytesAsync().ConfigureAwait(false)) { list = await DecryptAndDeserializeAsync(_encryptedCollection, key.PlainBytes) .ConfigureAwait(false); } if (index >= list.Count) { throw new ArgumentOutOfRangeException(nameof(index), index, "Inner encrypted collection is corrupt." + $"Must be lower than length {Length} but was {index}."); } var id = list.ElementAt(index); var safeByte = await _safeByteFactory.GetByIdAsync(id) .ConfigureAwait(false); return(safeByte); } finally { list?.Clear(); } }
public async Task GetByIdAsync_Takes_Less_Than_2ms() { const double expectedMax = 50; var idGenerator = SafeOrbitCore.Current.Factory.Get <IByteIdGenerator>(); var id = await idGenerator.GenerateAsync(5); var actual = MeasureAsync(() => _sut.GetByIdAsync(id)); Assert.That(actual, Is.LessThan(expectedMax)); }