/// <exception cref="System.IO.IOException"></exception> public override Ref Peel(Ref @ref) { Ref leaf = @ref.GetLeaf(); if (leaf.IsPeeled() || leaf.GetObjectId() == null) { return(@ref); } ObjectIdRef newLeaf = DoPeel(leaf); // Try to remember this peeling in the cache, so we don't have to do // it again in the future, but only if the reference is unchanged. if (leaf.GetStorage().IsLoose()) { RefList <RefDirectory.LooseRef> curList = looseRefs.Get(); int idx = curList.Find(leaf.GetName()); if (0 <= idx && curList.Get(idx) == leaf) { RefDirectory.LooseRef asPeeled = ((RefDirectory.LooseRef)leaf).Peel(newLeaf); RefList <RefDirectory.LooseRef> newList = curList.Set(idx, asPeeled); looseRefs.CompareAndSet(curList, newList); } } return(Recreate(@ref, newLeaf)); }
/// <exception cref="System.IO.IOException"></exception> public override bool IsNameConflicting(string name) { RefList <Ref> packed = GetPackedRefs(); RefList <RefDirectory.LooseRef> loose = GetLooseRefs(); // Cannot be nested within an existing reference. int lastSlash = name.LastIndexOf('/'); while (0 < lastSlash) { string needle = Sharpen.Runtime.Substring(name, 0, lastSlash); if (loose.Contains(needle) || packed.Contains(needle)) { return(true); } lastSlash = name.LastIndexOf('/', lastSlash - 1); } // Cannot be the container of an existing reference. string prefix = name + '/'; int idx; idx = -(packed.Find(prefix) + 1); if (idx < packed.Size() && packed.Get(idx).GetName().StartsWith(prefix)) { return(true); } idx = -(loose.Find(prefix) + 1); if (idx < loose.Size() && loose.Get(idx).GetName().StartsWith(prefix)) { return(true); } return(false); }
/// <exception cref="System.IO.IOException"></exception> private Ref ReadRef(string name, RefList <Ref> packed) { RefList <RefDirectory.LooseRef> curList = looseRefs.Get(); int idx = curList.Find(name); if (0 <= idx) { RefDirectory.LooseRef o = curList.Get(idx); RefDirectory.LooseRef n = ScanRef(o, name); if (n == null) { if (looseRefs.CompareAndSet(curList, curList.Remove(idx))) { modCnt.IncrementAndGet(); } return(packed.Get(name)); } if (o == n) { return(n); } if (looseRefs.CompareAndSet(curList, curList.Set(idx, n))) { modCnt.IncrementAndGet(); } return(n); } RefDirectory.LooseRef n_1 = ScanRef(null, name); if (n_1 == null) { return(packed.Get(name)); } // check whether the found new ref is the an additional ref. These refs // should not go into looseRefs for (int i = 0; i < additionalRefsNames.Length; i++) { if (name.Equals(additionalRefsNames[i])) { return(n_1); } } if (looseRefs.CompareAndSet(curList, curList.Add(idx, n_1))) { modCnt.IncrementAndGet(); } return(n_1); }
/// <exception cref="System.IO.IOException"></exception> private Ref Resolve(Ref @ref, int depth, string prefix, RefList <RefDirectory.LooseRef > loose, RefList <Ref> packed) { if (@ref.IsSymbolic()) { Ref dst = @ref.GetTarget(); if (MAX_SYMBOLIC_REF_DEPTH <= depth) { return(null); } // claim it doesn't exist // If the cached value can be assumed to be current due to a // recent scan of the loose directory, use it. if (loose != null && dst.GetName().StartsWith(prefix)) { int idx; if (0 <= (idx = loose.Find(dst.GetName()))) { dst = loose.Get(idx); } else { if (0 <= (idx = packed.Find(dst.GetName()))) { dst = packed.Get(idx); } else { return(@ref); } } } else { dst = ReadRef(dst.GetName(), packed); if (dst == null) { return(@ref); } } dst = Resolve(dst, depth + 1, prefix, loose, packed); if (dst == null) { return(null); } return(new SymbolicRef(@ref.GetName(), dst)); } return(@ref); }
public virtual void TestPut_WithPrefix() { Ref refA_one = NewRef("refs/heads/A", ID_ONE); Ref refA_two = NewRef("refs/heads/A", ID_TWO); packed = ToList(refA_one); RefMap map = new RefMap("refs/heads/", packed, loose, resolved); NUnit.Framework.Assert.AreSame(refA_one, map.Get("A")); NUnit.Framework.Assert.AreSame(refA_one, map.Put("A", refA_two)); // map changed, but packed, loose did not NUnit.Framework.Assert.AreSame(refA_two, map.Get("A")); NUnit.Framework.Assert.AreSame(refA_one, packed.Get(0)); NUnit.Framework.Assert.AreEqual(0, loose.Size()); NUnit.Framework.Assert.AreSame(refA_two, map.Put("A", refA_one)); NUnit.Framework.Assert.AreSame(refA_one, map.Get("A")); }
public virtual void TestCopyConstructorReusesArray() { RefListBuilder<Ref> one = new RefListBuilder<Ref>(); one.Add(REF_A); RefList<Ref> two = new RefList<Ref>(one.ToRefList()); one.Set(0, REF_B); NUnit.Framework.Assert.AreSame(REF_B, two.Get(0)); }