public void Add(string key, Stream data, StreamInfo parameters) { try { int fileNo = ++_fileCounter; Utility.ConsoleWriteLine($"Start adding file no: {fileNo}"); data.Dispose(); // Because this stream disposes quickly, I don't want it! if (key is null) { throw new CustomException(ExceptionKey.NullKey); } if (data is null) { throw new CustomException(ExceptionKey.NullData); } if (parameters is null) { throw new CustomException(ExceptionKey.NullParameters); } if (StorageIndex.Contains(key)) { throw new CustomException(ExceptionKey.DuplicateKey); } if (parameters.Length.HasValue && parameters.Length != data.Length) { throw new CustomException(ExceptionKey.StreamLengthNotMatched); } StorageIndex.Add(key); SetupWrite(key, fileNo, parameters).ConfigureAwait(false); } catch (CustomException ex) { switch (ex.ExceptionKey) { case ExceptionKey.NullKey: case ExceptionKey.NullData: case ExceptionKey.NullParameters: /// key is null, data is null, parameters is null throw new ArgumentNullException(); case ExceptionKey.StreamLengthNotMatched: case ExceptionKey.DuplicateKey: /// An element with the same key already exists or /// provided hash or length does not match the data. throw new ArgumentException(); default: throw new Exception(); } } catch (Exception) { //throw new CustomException(ExceptionKey.Unknown); throw; } }
private async Task <Stream> SetupReadAsync(string key, int fileNo) { try { Utility.ConsoleWriteLine($"Start SetupReadAsync file: {fileNo}"); if (!StorageIndex.Contains(key)) { throw new CustomException(ExceptionKey.NoDataRelatedToKey); } byte[] byteArrayData = null; var(indexInformation, indexReference) = StorageIndex.Get(key); var convertor = new Convertor(); if (indexInformation.Data != null) // Use the cached data { byteArrayData = indexInformation.Data; } else { if (!indexInformation.IsStoringCompleted) // Check if index has not setup or data has already written on the file { /// If data has not already written, wait for it var cancellationTokenSource = new CancellationTokenSource(); var taskWriteCompleted = IsWriteCompleted(indexInformation, cancellationTokenSource.Token); var taskIsRemoved = IsRemoved(indexInformation, cancellationTokenSource.Token); await Task.WhenAny(taskWriteCompleted, taskIsRemoved).ContinueWith(action => { if (action.IsFaulted) { foreach (var ex in (action.Exception as AggregateException).InnerExceptions) { throw ex; } } }); cancellationTokenSource.Cancel(); if (taskWriteCompleted.IsCanceled) { /// Item is removed, so can't read anything return(null); } (indexInformation, indexReference) = StorageIndex.Get(key); // It may not filled already } int offset = convertor.ConvertByteArrayToInt(indexReference.Offset); int size = convertor.ConvertByteArrayToInt(indexReference.Size); Utility.ConsoleWriteLine($"Start ReadFileAsync file: {fileNo}"); byteArrayData = await ReadFileAsync(offset, size); Utility.ConsoleWriteLine($"End ReadFileAsync file: {fileNo}"); var crc = new Crc16().ComputeChecksumBytes(byteArrayData); if (!crc.IsEqual(indexInformation.CRC)) { throw new CustomException(ExceptionKey.CorruptedData); } CheckCaching(indexInformation, byteArrayData); } var streamData = (indexInformation.IsCompressed ? convertor.DecompressAsync(byteArrayData).Result : convertor.ConvertByteArrayToStream(byteArrayData)); Utility.ConsoleWriteLine($"End reading file: {fileNo} - Read Files Count: {++_readFilesCounter}"); return(streamData); } catch (CustomException ex) { switch (ex.ExceptionKey) { case ExceptionKey.NullKey: /// key is null. throw new ArgumentNullException(); case ExceptionKey.NoDataRelatedToKey: /// key does not exist throw new KeyNotFoundException(); case ExceptionKey.CorruptedData: case ExceptionKey.Unknown: default: throw new Exception(); } } catch (Exception ex) { throw; } }
public bool Contains(string key) { return(StorageIndex.Contains(key)); }