/** * Create a new similarity index for the given object * * @param obj * the object to hash * @return similarity index for this object * @throws java.io.IOException * file contents cannot be read from the repository. * @throws org.eclipse.jgit.diff.SimilarityIndex.TableFullException * object hashing overflowed the storage capacity of the * SimilarityIndex. */ public static SimilarityIndex create(ObjectLoader obj) throws IOException, TableFullException { SimilarityIndex idx = new SimilarityIndex(); idx.hash(obj); idx.sort(); return idx; }
} while (n < 64 && n < remaining); hashedCnt += blockHashedCnt; add(hash, blockHashedCnt); remaining -= n;
private static long common(SimilarityIndex src, SimilarityIndex dst) { int srcIdx = src.packedIndex(0); int dstIdx = dst.packedIndex(0); long[] srcHash = src.idHash; long[] dstHash = dst.idHash; return common(srcHash, srcIdx, dstHash, dstIdx); }
long count(int idx) { return countOf(idHash[packedIndex(idx)]); }
int key(int idx) { return keyOf(idHash[packedIndex(idx)]); }
void add(int key, int cnt) throws TableFullException { key = (key * 0x9e370001) >>> 1; // Mix bits and ensure not negative. int j = slot(key); for (;;) { long v = idHash[j]; if (v == 0) { // Empty slot in the table, store here. if (idGrowAt <= idSize) { grow(); j = slot(key); continue; } idHash[j] = pair(key, cnt); idSize++; return; } else if (keyOf(v) == key) { // Same key, increment the counter. If it overflows, fail // indexing to prevent the key from being impacted. // idHash[j] = pair(key, countOf(v) + cnt); return; } else if (++j >= idHash.length) { j = 0; } } }
private int calculateModifyScore(ContentSource.Pair reader, DiffEntry d) throws IOException { try { SimilarityIndex src = new SimilarityIndex(); src.hash(reader.open(OLD, d)); src.sort(); SimilarityIndex dst = new SimilarityIndex(); dst.hash(reader.open(NEW, d)); dst.sort(); return src.score(dst, 100); } catch (TableFullException tableFull) { // If either table overflowed while being constructed, don't allow // the pair to be broken. Returning 1 higher than breakScore will // ensure its not similar, but not quite dissimilar enough to break. // overRenameLimit = true; return breakScore + 1; } }
private void grow() throws TableFullException { if (idHashBits == 30) throw new TableFullException(); long[] oldHash = idHash; int oldSize = idHash.length; idHashBits++; idGrowAt = growAt(idHashBits); try { idHash = new long[1 << idHashBits]; } catch (OutOfMemoryError noMemory) { throw TABLE_FULL_OUT_OF_MEMORY; } for (int i = 0; i < oldSize; i++) { long v = oldHash[i]; if (v != 0) { int j = slot(keyOf(v)); while (idHash[j] != 0) if (++j >= idHash.length) j = 0; idHash[j] = v; } } }
void hash(ObjectLoader obj) throws MissingObjectException, IOException, TableFullException { if (obj.isLarge()) { hashLargeObject(obj); } else { byte[] raw = obj.getCachedBytes(); hash(raw, 0, raw.length); } }
long common(SimilarityIndex dst) { return common(this, dst); }
int findIndex(int key) { for (int i = 0; i < idSize; i++) if (key(i) == key) return i; return -1; }
SimilarityIndex() { idHashBits = 8; idHash = new long[1 << idHashBits]; idGrowAt = growAt(idHashBits); }
private void hashLargeObject(ObjectLoader obj) throws IOException, TableFullException { boolean text; try (ObjectStream in1 = obj.openStream()) { text = !RawText.isBinary(in1); } try (ObjectStream in2 = obj.openStream()) { hash(in2, in2.getSize(), text); } }
void add(int key, int cnt) throws TableFullException { key = (key * 0x9e370001) >>> 1; // Mix bits and ensure not negative. int j = slot(key); for (;;) { long v = idHash[j]; if (v == 0) { // Empty slot in the table, store here. if (idGrowAt <= idSize) { grow(); j = slot(key); continue; } idHash[j] = pair(key, cnt); idSize++; return; } else if (keyOf(v) == key) { // Same key, increment the counter. If it overflows, fail // indexing to prevent the key from being impacted. // idHash[j] = pair(key, countOf(v) + cnt); return; } else if (++j >= idHash.length) { j = 0; } } }
private int calculateModifyScore(ContentSource.Pair reader, DiffEntry d) throws IOException { try { SimilarityIndex src = new SimilarityIndex(); src.hash(reader.open(OLD, d)); src.sort(); SimilarityIndex dst = new SimilarityIndex(); dst.hash(reader.open(NEW, d)); dst.sort(); return src.score(dst, 100); } catch (TableFullException tableFull) { // If either table overflowed while being constructed, don't allow // the pair to be broken. Returning 1 higher than breakScore will // ensure its not similar, but not quite dissimilar enough to break. // overRenameLimit = true; return breakScore + 1; } }
private void grow() throws TableFullException { if (idHashBits == 30) throw new TableFullException(); long[] oldHash = idHash; int oldSize = idHash.length; idHashBits++; idGrowAt = growAt(idHashBits); try { idHash = new long[1 << idHashBits]; } catch (OutOfMemoryError noMemory) { throw TABLE_FULL_OUT_OF_MEMORY; } for (int i = 0; i < oldSize; i++) { long v = oldHash[i]; if (v != 0) { int j = slot(keyOf(v)); while (idHash[j] != 0) if (++j >= idHash.length) j = 0; idHash[j] = v; } } }
void hash(ObjectLoader obj) throws MissingObjectException, IOException, TableFullException { if (obj.isLarge()) { hashLargeObject(obj); } else { byte[] raw = obj.getCachedBytes(); hash(raw, 0, raw.length); } }
long count(int idx) { return countOf(idHash[packedIndex(idx)]); }
int key(int idx) { return keyOf(idHash[packedIndex(idx)]); }