Ejemplo n.º 1
0
        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();
        }