public ArraySegment <byte> GetBlock(Hash hash) { // Cache { var result = _blocksManager.Get(hash); if (result != null) { return(result.Value); } } // Share { ArraySegment <byte>?result = null; string path = null; lock (_lockObject) { var shareInfo = _contentInfoManager.GetShareInfo(hash); if (shareInfo != null) { var buffer = _bufferManager.TakeBuffer(shareInfo.BlockLength); try { int length; try { using (var stream = new UnbufferedFileStream(shareInfo.Path, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.None, _bufferManager)) { stream.Seek((long)shareInfo.GetIndex(hash) * shareInfo.BlockLength, SeekOrigin.Begin); length = (int)Math.Min(stream.Length - stream.Position, shareInfo.BlockLength); stream.Read(buffer, 0, length); } } catch (ArgumentOutOfRangeException) { throw new BlockNotFoundException(); } catch (IOException) { throw new BlockNotFoundException(); } result = new ArraySegment <byte>(buffer, 0, length); path = shareInfo.Path; } catch (Exception) { _bufferManager.ReturnBuffer(buffer); throw; } } } if (result != null) { if (hash.Algorithm == HashAlgorithm.Sha256 && Unsafe.Equals(Sha256.Compute(result.Value), hash.Value)) { return(result.Value); } else { _bufferManager.ReturnBuffer(result.Value.Array); result = null; this.RemoveContent(path); } } } throw new BlockNotFoundException(); }