From d85c8b45225efc27bda3b07e0a71e659fe45f470 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 10 Dec 2008 15:18:26 -0800 Subject: [PATCH] Add ObjectId.startsWith(AbbreviatedObjectId) This test can be useful to determine if the object id at least begins with an abbreviated id. Signed-off-by: Shawn O. Pearce Signed-off-by: Robin Rosenberg --- .../spearce/jgit/lib/AbbreviatedObjectIdTest.java | 58 ++++++++++++++++++++++ .../org/spearce/jgit/lib/AbbreviatedObjectId.java | 57 +++++++++++++++++++++ .../src/org/spearce/jgit/lib/AnyObjectId.java | 11 ++++ 3 files changed, 126 insertions(+) diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/AbbreviatedObjectIdTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/AbbreviatedObjectIdTest.java index f540f491..3f82d505 100644 --- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/AbbreviatedObjectIdTest.java +++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/AbbreviatedObjectIdTest.java @@ -224,4 +224,62 @@ public class AbbreviatedObjectIdTest extends TestCase { assertFalse(a.equals(b)); assertFalse(b.equals(a)); } + + public void testPrefixCompare_Full() { + final String s1 = "7b6e8067ec96acef9a4184b43210d583b6d2f99a"; + final AbbreviatedObjectId a = AbbreviatedObjectId.fromString(s1); + final ObjectId i1 = ObjectId.fromString(s1); + assertEquals(0, a.prefixCompare(i1)); + assertTrue(i1.startsWith(a)); + + final String s2 = "7b6e8067ec96acef9a4184b43210d583b6d2f99b"; + final ObjectId i2 = ObjectId.fromString(s2); + assertTrue(a.prefixCompare(i2) < 0); + assertFalse(i2.startsWith(a)); + + final String s3 = "7b6e8067ec96acef9a4184b43210d583b6d2f999"; + final ObjectId i3 = ObjectId.fromString(s3); + assertTrue(a.prefixCompare(i3) > 0); + assertFalse(i3.startsWith(a)); + } + + public void testPrefixCompare_1() { + final String sa = "7"; + final AbbreviatedObjectId a = AbbreviatedObjectId.fromString(sa); + + final String s1 = "7b6e8067ec96acef9a4184b43210d583b6d2f99a"; + final ObjectId i1 = ObjectId.fromString(s1); + assertEquals(0, a.prefixCompare(i1)); + assertTrue(i1.startsWith(a)); + + final String s2 = "8b6e8067ec96acef9a4184b43210d583b6d2f99a"; + final ObjectId i2 = ObjectId.fromString(s2); + assertTrue(a.prefixCompare(i2) < 0); + assertFalse(i2.startsWith(a)); + + final String s3 = "6b6e8067ec96acef9a4184b43210d583b6d2f99a"; + final ObjectId i3 = ObjectId.fromString(s3); + assertTrue(a.prefixCompare(i3) > 0); + assertFalse(i3.startsWith(a)); + } + + public void testPrefixCompare_17() { + final String sa = "7b6e8067ec96acef9"; + final AbbreviatedObjectId a = AbbreviatedObjectId.fromString(sa); + + final String s1 = "7b6e8067ec96acef9a4184b43210d583b6d2f99a"; + final ObjectId i1 = ObjectId.fromString(s1); + assertEquals(0, a.prefixCompare(i1)); + assertTrue(i1.startsWith(a)); + + final String s2 = "7b6e8067eca6acef9a4184b43210d583b6d2f99a"; + final ObjectId i2 = ObjectId.fromString(s2); + assertTrue(a.prefixCompare(i2) < 0); + assertFalse(i2.startsWith(a)); + + final String s3 = "7b6e8067ec86acef9a4184b43210d583b6d2f99a"; + final ObjectId i3 = ObjectId.fromString(s3); + assertTrue(a.prefixCompare(i3) > 0); + assertFalse(i3.startsWith(a)); + } } diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/AbbreviatedObjectId.java b/org.spearce.jgit/src/org/spearce/jgit/lib/AbbreviatedObjectId.java index 7ef8a9d2..c2b21cfd 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/lib/AbbreviatedObjectId.java +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/AbbreviatedObjectId.java @@ -39,6 +39,8 @@ package org.spearce.jgit.lib; import java.io.UnsupportedEncodingException; +import org.spearce.jgit.util.NB; + /** * A prefix abbreviation of an {@link ObjectId}. *

@@ -119,6 +121,24 @@ public class AbbreviatedObjectId { return r << (8 - n) * 4; } + static int mask(final int nibbles, final int word, final int v) { + final int b = (word - 1) * 8; + if (b + 8 <= nibbles) { + // We have all of the bits required for this word. + // + return v; + } + + if (nibbles < b) { + // We have none of the bits required for this word. + // + return 0; + } + + final int s = 32 - (nibbles - b) * 4; + return (v >>> s) << s; + } + /** Number of half-bytes used by this id. */ final int nibbles; @@ -157,6 +177,43 @@ public class AbbreviatedObjectId { return isComplete() ? new ObjectId(w1, w2, w3, w4, w5) : null; } + /** + * Compares this abbreviation to a full object id. + * + * @param other + * the other object id. + * @return <0 if this abbreviation names an object that is less than + * other; 0 if this abbreviation exactly matches the + * first {@link #length()} digits of other.name(); + * >0 if this abbreviation names an object that is after + * other. + */ + public int prefixCompare(final AnyObjectId other) { + int cmp; + + cmp = NB.compareUInt32(w1, mask(1, other.w1)); + if (cmp != 0) + return cmp; + + cmp = NB.compareUInt32(w2, mask(2, other.w2)); + if (cmp != 0) + return cmp; + + cmp = NB.compareUInt32(w3, mask(3, other.w3)); + if (cmp != 0) + return cmp; + + cmp = NB.compareUInt32(w4, mask(4, other.w4)); + if (cmp != 0) + return cmp; + + return NB.compareUInt32(w5, mask(5, other.w5)); + } + + private int mask(final int word, final int v) { + return mask(nibbles, word, v); + } + @Override public int hashCode() { return w2; diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java b/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java index e88e09d9..df59cdae 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java @@ -226,6 +226,17 @@ public abstract class AnyObjectId implements Comparable { return NB.compareUInt32(w5, bs[p + 4]); } + /** + * Tests if this ObjectId starts with the given abbreviation. + * + * @param abbr + * the abbreviation. + * @return true if this ObjectId begins with the abbreviation; else false. + */ + public boolean startsWith(final AbbreviatedObjectId abbr) { + return abbr.prefixCompare(this) == 0; + } + public int hashCode() { return w2; } -- 2.11.4.GIT