1 /* 2 * Copyright (C) 2010, Google Inc. and others 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the Eclipse Distribution License v. 1.0 which is available at 6 * https://www.eclipse.org/org/documents/edl-v10.php. 7 * 8 * SPDX-License-Identifier: BSD-3-Clause 9 */ 10 11 package org.eclipse.jgit.diff; 12 13 /** 14 * Equivalence function for a {@link org.eclipse.jgit.diff.Sequence} compared by 15 * difference algorithm. 16 * <p> 17 * Difference algorithms can use a comparator to compare portions of two 18 * sequences and discover the minimal edits required to transform from one 19 * sequence to the other sequence. 20 * <p> 21 * Indexes within a sequence are zero-based. 22 * 23 * @param <S> 24 * type of sequence the comparator supports. 25 */ 26 public abstract class SequenceComparator<S extends Sequence> { 27 /** 28 * Compare two items to determine if they are equivalent. 29 * 30 * It is permissible to compare sequence {@code a} with itself (by passing 31 * {@code a} again in position {@code b}). 32 * 33 * @param a 34 * the first sequence. 35 * @param ai 36 * item of {@code ai} to compare. 37 * @param b 38 * the second sequence. 39 * @param bi 40 * item of {@code bi} to compare. 41 * @return true if the two items are identical according to this function's 42 * equivalence rule. 43 */ 44 public abstract boolean equals(S a, int ai, S b, int bi); 45 46 /** 47 * Get a hash value for an item in a sequence. 48 * 49 * If two items are equal according to this comparator's 50 * {@link #equals(Sequence, int, Sequence, int)} method, then this hash 51 * method must produce the same integer result for both items. 52 * 53 * It is not required for two items to have different hash values if they 54 * are unequal according to the {@code equals()} method. 55 * 56 * @param seq 57 * the sequence. 58 * @param ptr 59 * the item to obtain the hash for. 60 * @return hash the hash value. 61 */ 62 public abstract int hash(S seq, int ptr); 63 64 /** 65 * Modify the edit to remove common leading and trailing items. 66 * 67 * The supplied edit {@code e} is reduced in size by moving the beginning A 68 * and B points so the edit does not cover any items that are in common 69 * between the two sequences. The ending A and B points are also shifted to 70 * remove common items from the end of the region. 71 * 72 * @param a 73 * the first sequence. 74 * @param b 75 * the second sequence. 76 * @param e 77 * the edit to start with and update. 78 * @return {@code e} if it was updated in-place, otherwise a new edit 79 * containing the reduced region. 80 */ 81 public Edit reduceCommonStartEnd(S a, S b, Edit e) { 82 // Skip over items that are common at the start. 83 // 84 while (e.beginA < e.endA && e.beginB < e.endB 85 && equals(a, e.beginA, b, e.beginB)) { 86 e.beginA++; 87 e.beginB++; 88 } 89 90 // Skip over items that are common at the end. 91 // 92 while (e.beginA < e.endA && e.beginB < e.endB 93 && equals(a, e.endA - 1, b, e.endB - 1)) { 94 e.endA--; 95 e.endB--; 96 } 97 98 return e; 99 } 100 }