Beispiel #1
0
        /// <summary>
        /// Create a node out of the list of chunks.
        /// </summary>
        protected internal virtual DedupNode CreateNode()
        {
            if (SingleChunkHotPath)
            {
                Contract.Assert(_chunks.Count == 0);
                Contract.Check(_bytesChunked == _sizeHint)?.Assert($"_bytesChunked != _sizeHint. _bytesChunked={_bytesChunked} _sizeHint={_sizeHint}");
                Contract.Assert(_session == null);
                byte[] chunkHash = _chunkHasher.HashFinalInternal();
                return(new DedupNode(DedupNode.NodeType.ChunkLeaf, (ulong)_sizeHint, chunkHash, 0));
            }
            else
            {
                _session?.Dispose();
                _session = null;

                if (_chunks.Count == 0)
                {
                    return(new DedupNode(new ChunkInfo(0, 0, DedupChunkHashInfo.Instance.EmptyHash.ToHashByteArray())));
                }
                else if (_chunks.Count == 1)
                {
                    // Content is small enough to track as a chunk.
                    var node = new DedupNode(_chunks.Single());
                    Contract.Assert(node.Type == DedupNode.NodeType.ChunkLeaf);
                    return(node);
                }
                else
                {
                    return(DedupNodeTree.Create(_chunks, _treeAlgorithm));
                }
            }
        }
        /// <summary>
        /// Create a node out of the list of chunks.
        /// </summary>
        protected internal virtual DedupNode CreateNode()
        {
            if (SingleChunkHotPath)
            {
                Contract.Check(_chunks.Count == 0)?.Assert($"Chunk count: {_chunks.Count} sizehint: {_sizeHint} chunker min chunk size: {_chunker.Configuration.MinChunkSize}");
                Contract.Check(_bytesChunked == _sizeHint)?.Assert($"_bytesChunked != _sizeHint. _bytesChunked={_bytesChunked} _sizeHint={_sizeHint}");
                Contract.Assert(_session == null, "Dedup session cannot be null.");
                byte[] chunkHash = _chunkHasher.HashFinalInternal();
                return(new DedupNode(DedupNode.NodeType.ChunkLeaf, (ulong)_sizeHint, chunkHash, 0));
            }
            else
            {
                _session?.Dispose();
                _session = null;

                if (_chunks.Count == 0)
                {
                    return(new DedupNode(new ChunkInfo(0, 0, DedupSingleChunkHashInfo.Instance.EmptyHash.ToHashByteArray())));
                }
                else if (_chunks.Count == 1)
                {
                    // Content is small enough to track as a chunk.
                    var node = new DedupNode(_chunks.Single());
                    Contract.Check(node.Type == DedupNode.NodeType.ChunkLeaf)?.Assert($"{nameof(CreateNode)}: expected chunk leaf: {DedupNode.NodeType.ChunkLeaf} got {node.Type} instead.");
                    return(node);
                }
                else
                {
                    return(DedupNodeTree.Create(_chunks));
                }
            }
        }
        /// <inheritdoc />
        protected override byte[] HashFinal()
        {
            _session.Dispose();

            if (_chunker.TotalBytes == 0)
            {
                _chunks.Add(new ChunkInfo(0, 0, DedupChunkHashInfo.Instance.EmptyHash.ToHashByteArray()));
            }

            _lastNode = DedupNodeTree.Create(_chunks, _treeAlgorithm);

            // The array returned by this function will be cleared when this is disposed, so clone it.
            return(_lastNode.Value.Hash.ToArray());
        }
        /// <inheritdoc />
        /// <remarks>
        /// Extends DedupNode algorithm to tag hash as DedupChunk or DedupNode.
        /// </remarks>
        protected override byte[] HashFinal()
        {
            _session.Dispose();

            if (_chunker.TotalBytes == 0)
            {
                _chunks.Add(new ChunkInfo(0, 0, DedupChunkHashInfo.Instance.EmptyHash.ToHashByteArray()));
            }

            _lastNode = DedupNodeTree.Create(_chunks, _treeAlgorithm);

            if (_lastNode.Value.ChildNodes.Count == 1)
            {
                // Content is small enough to track as a chunk.
                _lastNode = _lastNode.Value.ChildNodes.Single();
            }

            return(SerializeHashAndId());
        }
Beispiel #5
0
        /// <summary>
        /// Creates a tree or a single node containing the given chunk(s).
        /// </summary>
        /// <returns>
        /// The root of the tree, or a single chunk node encapsulating the chunk.
        /// </returns>
        public static DedupNode Create(IList <ChunkInfo> chunks)
        {
            if (chunks.Count == 0)
            {
                return(new DedupNode(new ChunkInfo(0, 0, DedupSingleChunkHashInfo.Instance.EmptyHash.ToHashByteArray())));
            }
            else if (chunks.Count == 1)
            {
                // Content is small enough to track as a chunk.
                var node = new DedupNode(chunks.Single());
                Contract.Check(node.Type == DedupNode.NodeType.ChunkLeaf)?.Assert(
                    $"{nameof(Create)}: expected chunk leaf: {DedupNode.NodeType.ChunkLeaf} got {node.Type} instead.");

                return(node);
            }
            else
            {
                return(DedupNodeTree.Create(chunks));
            }
        }
Beispiel #6
0
        /// <inheritdoc />
        /// <remarks>
        /// Extends DedupNode algorithm to tag hash as DedupChunk or DedupNode.
        /// </remarks>
        protected override byte[] HashFinal()
        {
            _session.Dispose();

            if (_chunks.Count == 0)
            {
                _chunks.Add(new ChunkInfo(0, 0, DedupChunkHashInfo.Instance.EmptyHash.ToHashByteArray()));
            }

            if (_chunks.Count == 1)
            {
                // Content is small enough to track as a chunk.
                _lastNode = new DedupNode(_chunks.Single());
                Contract.Assert(_lastNode.Value.Type == DedupNode.NodeType.ChunkLeaf);
            }
            else
            {
                _lastNode = DedupNodeTree.Create(_chunks, _treeAlgorithm);
            }

            return(SerializeHashAndId());
        }