Пример #1
0
        /// <summary>
        ///     Open file by hash
        /// </summary>
        /// <param name="hash"></param>
        /// <returns>file stream</returns>
        /// <exception cref="FileNotFoundException"></exception>
        public DecimaCoreFile OpenFile(long hash)
        {
            if (!RecordTableByHash.TryGetValue(hash, out var recordIndex))
            {
                throw new FileNotFoundException($"Cannot find hash {hash:X16}");
            }

            var record = RecordTable[(int)recordIndex];

            var(chunk, index) = BlockTable.Select((x, y) => new KeyValuePair <DecimaCacheBlockTableEntry, int>(x, y)).First(x =>
            {
                var(key, _) = x;
                return(key.ChunkOffset + key.ChunkSize > record.Offset);
            });

            var buffer = new MemoryStream(record.Size);

            while (buffer.Position < record.Size)
            {
                var block = OpenBlock(chunk);
                var start = 0;
                if (chunk.ChunkOffset < record.Offset)
                {
                    start = (int)(record.Offset - chunk.ChunkOffset);
                }

                var end = block.Length - start;
                if (end + buffer.Position > record.Size)
                {
                    end = (int)(record.Size - buffer.Position);
                }

                buffer.Write(block.Slice(start, end));
                index += 1;

                if (index >= BlockTable.Count)
                {
                    break;
                }

                chunk = BlockTable[index];
            }

            // Debug.Assert(buffer.Length == record.Size, "buffer.Length == record.Size");

            buffer.Position = 0;
            return(new DecimaCoreFile(buffer));
        }