/// <summary>Obtain a unique abbreviation (prefix) of an object SHA-1.</summary> /// <remarks> /// Obtain a unique abbreviation (prefix) of an object SHA-1. /// The returned abbreviation would expand back to the argument ObjectId when /// passed to /// <see cref="Resolve(AbbreviatedObjectId)">Resolve(AbbreviatedObjectId)</see> /// , assuming no new objects /// are added to this repository between calls. /// The default implementation of this method abbreviates the id to the /// minimum length, then resolves it to see if there are multiple results. /// When multiple results are found, the length is extended by 1 and resolve /// is tried again. /// </remarks> /// <param name="objectId">object identity that needs to be abbreviated.</param> /// <param name="len"> /// minimum length of the abbreviated string. Must be in the range /// [2, /// <value>Constants#OBJECT_ID_STRING_LENGTH</value> /// ]. /// </param> /// <returns> /// SHA-1 abbreviation. If no matching objects exist in the /// repository, the abbreviation will match the minimum length. /// </returns> /// <exception cref="System.IO.IOException">the object store cannot be read.</exception> public virtual AbbreviatedObjectId Abbreviate(AnyObjectId objectId, int len) { if (len == Constants.OBJECT_ID_STRING_LENGTH) { return(AbbreviatedObjectId.FromObjectId(objectId)); } AbbreviatedObjectId abbrev = objectId.Abbreviate(len); ICollection <ObjectId> matches = Resolve(abbrev); while (1 < matches.Count && len < Constants.OBJECT_ID_STRING_LENGTH) { abbrev = objectId.Abbreviate(++len); IList <ObjectId> n = new AList <ObjectId>(8); foreach (ObjectId candidate in matches) { if (abbrev.PrefixCompare(candidate) == 0) { n.AddItem(candidate); } } if (1 < n.Count) { matches = n; } else { matches = Resolve(abbrev); } } return(abbrev); }
public virtual void TestPrefixCompare_Full() { string s1 = "7b6e8067ec96acef9a4184b43210d583b6d2f99a"; AbbreviatedObjectId a = AbbreviatedObjectId.FromString(s1); ObjectId i1 = ObjectId.FromString(s1); NUnit.Framework.Assert.AreEqual(0, a.PrefixCompare(i1)); NUnit.Framework.Assert.IsTrue(i1.StartsWith(a)); string s2 = "7b6e8067ec96acef9a4184b43210d583b6d2f99b"; ObjectId i2 = ObjectId.FromString(s2); NUnit.Framework.Assert.IsTrue(a.PrefixCompare(i2) < 0); NUnit.Framework.Assert.IsFalse(i2.StartsWith(a)); string s3 = "7b6e8067ec96acef9a4184b43210d583b6d2f999"; ObjectId i3 = ObjectId.FromString(s3); NUnit.Framework.Assert.IsTrue(a.PrefixCompare(i3) > 0); NUnit.Framework.Assert.IsFalse(i3.StartsWith(a)); }
/// <exception cref="System.IO.IOException"></exception> public override void Resolve(ICollection<ObjectId> matches, AbbreviatedObjectId id , int matchLimit) { int[] data = names[id.FirstByte]; int max = (int)(((uint)offset32[id.FirstByte].Length) >> 2); int high = max; if (high == 0) { return; } int low = 0; do { int p = (int)(((uint)(low + high)) >> 1); int cmp = id.PrefixCompare(data, IdOffset(p)); if (cmp < 0) { high = p; } else { if (cmp == 0) { // We may have landed in the middle of the matches. Move // backwards to the start of matches, then walk forwards. // while (0 < p && id.PrefixCompare(data, IdOffset(p - 1)) == 0) { p--; } for (; p < max && id.PrefixCompare(data, IdOffset(p)) == 0; p++) { matches.AddItem(ObjectId.FromRaw(data, IdOffset(p))); if (matches.Count > matchLimit) { break; } } return; } else { low = p + 1; } } } while (low < high); }
/// <exception cref="System.IO.IOException"></exception> internal override void Resolve(ICollection<ObjectId> matches, AbbreviatedObjectId id) { // Go through the packs once. If we didn't find any resolutions // scan for new packs and check once more. // int oldSize = matches.Count; ObjectDirectory.PackList pList = packList.Get(); for (; ; ) { foreach (PackFile p in pList.packs) { try { p.Resolve(matches, id, RESOLVE_ABBREV_LIMIT); } catch (IOException) { // Assume the pack is corrupted. // RemovePack(p); } if (matches.Count > RESOLVE_ABBREV_LIMIT) { return; } } if (matches.Count == oldSize) { ObjectDirectory.PackList nList = ScanPacks(pList); if (nList == pList || nList.packs.Length == 0) { break; } pList = nList; continue; } break; } string fanOut = Sharpen.Runtime.Substring(id.Name, 0, 2); string[] entries = new FilePath(GetDirectory(), fanOut).List(); if (entries != null) { foreach (string e in entries) { if (e.Length != Constants.OBJECT_ID_STRING_LENGTH - 2) { continue; } try { ObjectId entId = ObjectId.FromString(fanOut + e); if (id.PrefixCompare(entId) == 0) { matches.AddItem(entId); } } catch (ArgumentException) { continue; } if (matches.Count > RESOLVE_ABBREV_LIMIT) { return; } } } foreach (FileObjectDatabase.AlternateHandle alt in MyAlternates()) { alt.db.Resolve(matches, id); if (matches.Count > RESOLVE_ABBREV_LIMIT) { return; } } }
/// <summary>Tests if this ObjectId starts with the given abbreviation.</summary> /// <remarks>Tests if this ObjectId starts with the given abbreviation.</remarks> /// <param name="abbr">the abbreviation.</param> /// <returns>true if this ObjectId begins with the abbreviation; else false.</returns> public virtual bool StartsWith(AbbreviatedObjectId abbr) { return(abbr.PrefixCompare(this) == 0); }
/// <summary>Tests if this ObjectId starts with the given abbreviation.</summary> /// <remarks>Tests if this ObjectId starts with the given abbreviation.</remarks> /// <param name="abbr">the abbreviation.</param> /// <returns>true if this ObjectId begins with the abbreviation; else false.</returns> public virtual bool StartsWith(AbbreviatedObjectId abbr) { return abbr.PrefixCompare(this) == 0; }