/// <summary> /// Initializes a new instance of the <see cref="DedupNodeOrChunkHashAlgorithm"/> class. /// </summary> public DedupNodeOrChunkHashAlgorithm(DedupNodeTree.Algorithm treeAlgorithm) { _treeAlgorithm = treeAlgorithm; _chunker = DedupNodeHashAlgorithm.CreateChunker(); Initialize(); }
private void ChunksAndNodesInCommonInSimilarFiles(DedupNodeTree.Algorithm algorithm) { using (var hasher = new DedupNodeHashAlgorithm(algorithm)) { byte[] bytes = new byte[50 * 1024 * 1024]; int offsetForSecondFile = 200 * 1024; var r = new Random(Seed: 0); r.NextBytes(bytes); hasher.Initialize(); byte[] hash1 = hasher.ComputeHash(bytes, 0, bytes.Length); var node1 = hasher.GetNode(); HashSet <string> chunks1 = node1.EnumerateChunkLeafsInOrder().Select(c => c.Hash.ToHex()).ToHashSet(); HashSet <string> nodes1 = node1.EnumerateInnerNodesDepthFirst().Select(c => c.Hash.ToHex()).ToHashSet(); hasher.Initialize(); byte[] hash2 = hasher.ComputeHash(bytes, offsetForSecondFile, bytes.Length - offsetForSecondFile); var node2 = hasher.GetNode(); HashSet <string> chunks2 = node2.EnumerateChunkLeafsInOrder().Select(c => c.Hash.ToHex()).ToHashSet(); HashSet <string> nodes2 = node2.EnumerateInnerNodesDepthFirst().Select(c => c.Hash.ToHex()).ToHashSet(); Assert.NotEqual(hash1, hash2, ByteArrayComparer.Instance); var commonChunks = new HashSet <string>(chunks1); commonChunks.IntersectWith(chunks2); Assert.Subset(chunks1, commonChunks); Assert.Subset(chunks2, commonChunks); Assert.InRange(commonChunks.Count, chunks1.Count - (chunks1.Count / 10), chunks1.Count); Assert.InRange(commonChunks.Count, chunks2.Count - (chunks2.Count / 10), chunks2.Count); var commonNodes = new HashSet <string>(nodes1); commonNodes.IntersectWith(nodes2); Assert.Subset(nodes1, commonNodes); Assert.Subset(nodes2, commonNodes); int nodeQueries = 0; int chunkQueries = 0; node2.VisitPreorder(n => { switch (n.Type) { case DedupNode.NodeType.ChunkLeaf: chunkQueries++; break; case DedupNode.NodeType.InnerNode: nodeQueries++; break; } return(!nodes1.Contains(n.Hash.ToHex())); }); switch (algorithm) { case DedupNodeTree.Algorithm.MaximallyPacked: Assert.Equal(0, commonNodes.Count); Assert.Equal(nodeQueries, nodes2.Count); Assert.Equal(chunkQueries, chunks2.Count); break; case DedupNodeTree.Algorithm.RollingHash: Assert.True(commonNodes.Count > 0); Assert.True(nodeQueries <= nodes2.Count); Assert.True(chunkQueries < chunks2.Count); break; default: Assert.True(false); break; } } }
/// <summary> /// Initializes a new instance of the <see cref="DedupNodeHashAlgorithm"/> class. /// </summary> public DedupNodeHashAlgorithm(DedupNodeTree.Algorithm treeAlgorithm, IChunker chunker) : base(treeAlgorithm, chunker) { }
/// <summary> /// Initializes a new instance of the <see cref="DedupNodeOrChunkHashAlgorithm"/> class. /// </summary> public DedupNodeOrChunkHashAlgorithm(DedupNodeTree.Algorithm treeAlgorithm, IChunker chunker) { _treeAlgorithm = treeAlgorithm; _chunker = chunker; Initialize(); }
/// <summary> /// Initializes a new instance of the <see cref="DedupNodeHashAlgorithm"/> class. /// </summary> public DedupNodeHashAlgorithm(ChunkerConfiguration configuration, DedupNodeTree.Algorithm treeAlgorithm) : this(treeAlgorithm, Chunker.Create(configuration)) { }