Beispiel #1
0
        /// <summary>
        ///     Calls <paramref name="onBlock"/> on the contents of the block at
        ///     address <paramref name="address"/>.
        /// </summary>
        /// <remarks>
        ///     If the block has pending work (such as validating contents, or
        ///     writing them out), that pending work is performed before the call.
        ///
        ///     Fully thread-safe.
        ///
        ///     Function <paramref name="onBlock"/> should endeavour to return
        ///     quickly, as the provided span is pinned, for all intents and
        ///     purposes, until it does.
        /// </remarks>
        /// <returns>
        ///     True of the block could be extracted and passed to <paramref name="onBlock"/>.
        ///     This may fail if the file is being unpinned, or if the block does not
        ///     have the expected realm/hash, or if it is corrupted, or if the address has
        ///     somehow expired.
        ///
        ///     The out argument contains the return value of <paramref name="onBlock"/>.
        /// </returns>
        /// <see cref="BlockFile.TryWithBlockAtAddress"/>
        public bool TryWithBlockAtAddress <T>(
            BlockAddress address,
            uint realm,
            Hash hash,
            WithSpan.ReadOnlyReturns <T> onBlock,
            out T result)
        {
            if (address.IsNone())
            {
                result = default;
                return(false);
            }

            // BlockAddress.File() is 1..1023 but our array is zero-indexed.
            var fid  = address.File() - 1;
            var file = _readFiles[fid];

            if (file == null)
            {
                result = default;
                return(false);
            }

            return(file.TryWithBlockAtAddress(
                       address,
                       realm,
                       hash,
                       onBlock,
                       out result));
        }
Beispiel #2
0
        /// <summary>
        ///     Calls <paramref name="reader"/> on the block represented by the
        ///     realm and hash.
        /// </summary>
        /// <exception cref="MissingBlockException">
        ///     If the block is not present in the scratch space, or was corrupted
        ///     and failed a checksum check.
        /// </exception>
        public T Read <T>(uint realm, Hash hash, WithSpan.ReadOnlyReturns <T> reader)
        {
            var addr = _index.Get(realm, hash);

            try
            {
                if (_wheel.TryWithBlockAtAddress(addr, realm, hash, reader, out var result))
                {
                    return(result);
                }
            }
            // 'MissingBlock' and 'ChecksumFailed', if they happen inside, should
            // converted to a 'MissingBlock' and ensure that the broken block is
            // removed.
            catch (MissingBlockException) {}
            catch (CheckSumFailedException) {}

            _index.Remove(realm, hash, addr);
            throw new MissingBlockException(realm, hash);
        }