Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

HistogramDiffTest.java 4.7KB

Fix broken HistogramDiff HistogramDiff failed on cases where the initial element for the LCS was actually very common (e.g. has 20 occurrences), and the first element of the inserted region after the LCS was also common but had fewer occurrences (e.g. 10), while the LCS also contained a unique element (1 occurrence). This happens often in Java source code. The initial element for the LCS might be the empty line ("\n"), and the inserted but common element might be "\t/**\n", with the LCS being a large span of lines that contains unique method declarations. Even though "/**" occurs less often than the empty line its not a better LCS if the LCS we already have contains a unique element. The logic in HistogramDiff would normally have worked fine, except I tried to optimize scanning of B by making tryLongestCommonSequence return the end of the region when there are matching elements found in A. This allows us to skip over the current LCS region, as it has already been examined, but caused us to fail to identify an element that had a lower occurrence count within the region. The solution used here is to trade space-for-time by keeping a table of A positions to their occurrence counts. This allows the matching logic to always use the smallest count for this region, even if the smallest count doesn't appear on the initial element. The new unit test testEdit_LcsContainsUnique() verifies this new behavior works as expected. Bug: 328895 Change-Id: Id170783b891f645b6a8cf6f133c6682b8de40aaf Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 anos atrás
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Copyright (C) 2010, Google Inc.
  3. * and other copyright owners as documented in the project's IP log.
  4. *
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Distribution License v1.0 which
  7. * accompanies this distribution, is reproduced below, and is
  8. * available at http://www.eclipse.org/org/documents/edl-v10.php
  9. *
  10. * All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or
  13. * without modification, are permitted provided that the following
  14. * conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimer.
  18. *
  19. * - Redistributions in binary form must reproduce the above
  20. * copyright notice, this list of conditions and the following
  21. * disclaimer in the documentation and/or other materials provided
  22. * with the distribution.
  23. *
  24. * - Neither the name of the Eclipse Foundation, Inc. nor the
  25. * names of its contributors may be used to endorse or promote
  26. * products derived from this software without specific prior
  27. * written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  30. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  31. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  34. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  38. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  41. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. */
  43. package org.eclipse.jgit.diff;
  44. import static org.junit.Assert.assertEquals;
  45. import org.junit.Test;
  46. public class HistogramDiffTest extends AbstractDiffTestCase {
  47. @Override
  48. protected HistogramDiff algorithm() {
  49. HistogramDiff hd = new HistogramDiff();
  50. hd.setFallbackAlgorithm(null);
  51. return hd;
  52. }
  53. @Test
  54. public void testEdit_NoUniqueMiddleSide_FlipBlocks() {
  55. EditList r = diff(t("aRRSSz"), t("aSSRRz"));
  56. assertEquals(2, r.size());
  57. assertEquals(new Edit(1, 3, 1, 1), r.get(0)); // DELETE "RR"
  58. assertEquals(new Edit(5, 5, 3, 5), r.get(1)); // INSERT "RR
  59. }
  60. @Test
  61. public void testEdit_NoUniqueMiddleSide_Insert2() {
  62. EditList r = diff(t("aRSz"), t("aRRSSz"));
  63. assertEquals(1, r.size());
  64. assertEquals(new Edit(2, 2, 2, 4), r.get(0));
  65. }
  66. @Test
  67. public void testEdit_NoUniqueMiddleSide_FlipAndExpand() {
  68. EditList r = diff(t("aRSz"), t("aSSRRz"));
  69. assertEquals(2, r.size());
  70. assertEquals(new Edit(1, 2, 1, 1), r.get(0)); // DELETE "R"
  71. assertEquals(new Edit(3, 3, 2, 5), r.get(1)); // INSERT "SRR"
  72. }
  73. @Test
  74. public void testEdit_LcsContainsUnique() {
  75. EditList r = diff(t("nqnjrnjsnm"), t("AnqnjrnjsnjTnmZ"));
  76. assertEquals(new Edit(0, 0, 0, 1), r.get(0)); // INSERT "A";
  77. assertEquals(new Edit(9, 9, 10, 13), r.get(1)); // INSERT "jTn";
  78. assertEquals(new Edit(10, 10, 14, 15), r.get(2)); // INSERT "Z";
  79. assertEquals(3, r.size());
  80. }
  81. @Test
  82. public void testExceedsChainLength_DuringScanOfA() {
  83. HistogramDiff hd = new HistogramDiff();
  84. hd.setFallbackAlgorithm(null);
  85. hd.setMaxChainLength(3);
  86. SequenceComparator<RawText> cmp = new SequenceComparator<RawText>() {
  87. @Override
  88. public boolean equals(RawText a, int ai, RawText b, int bi) {
  89. return RawTextComparator.DEFAULT.equals(a, ai, b, bi);
  90. }
  91. @Override
  92. public int hash(RawText a, int ai) {
  93. return 1;
  94. }
  95. };
  96. EditList r = hd.diff(cmp, t("RabS"), t("QabT"));
  97. assertEquals(1, r.size());
  98. assertEquals(new Edit(0, 4, 0, 4), r.get(0));
  99. }
  100. @Test
  101. public void testExceedsChainLength_DuringScanOfB() {
  102. HistogramDiff hd = new HistogramDiff();
  103. hd.setFallbackAlgorithm(null);
  104. hd.setMaxChainLength(1);
  105. EditList r = hd.diff(RawTextComparator.DEFAULT, t("RaaS"), t("QaaT"));
  106. assertEquals(1, r.size());
  107. assertEquals(new Edit(0, 4, 0, 4), r.get(0));
  108. }
  109. @Test
  110. public void testFallbackToMyersDiff() {
  111. HistogramDiff hd = new HistogramDiff();
  112. hd.setMaxChainLength(4);
  113. RawTextComparator cmp = RawTextComparator.DEFAULT;
  114. RawText ac = t("bbbbb");
  115. RawText bc = t("AbCbDbEFbZ");
  116. EditList r;
  117. // Without fallback our results are limited due to collisions.
  118. hd.setFallbackAlgorithm(null);
  119. r = hd.diff(cmp, ac, bc);
  120. assertEquals(1, r.size());
  121. // Results go up when we add a fallback for the high collision regions.
  122. hd.setFallbackAlgorithm(MyersDiff.INSTANCE);
  123. r = hd.diff(cmp, ac, bc);
  124. assertEquals(5, r.size());
  125. }
  126. }