Пример #1
0
 private void InsertPack(PackFile pf)
 {
     ObjectDirectory.PackList o;
     ObjectDirectory.PackList n;
     do
     {
         o = packList.Get();
         // If the pack in question is already present in the list
         // (picked up by a concurrent thread that did a scan?) we
         // do not want to insert it a second time.
         //
         PackFile[] oldList = o.packs;
         string     name    = pf.GetPackFile().GetName();
         foreach (PackFile p in oldList)
         {
             if (PackFile.SORT.Compare(pf, p) < 0)
             {
                 break;
             }
             if (name.Equals(p.GetPackFile().GetName()))
             {
                 return;
             }
         }
         PackFile[] newList = new PackFile[1 + oldList.Length];
         newList[0] = pf;
         System.Array.Copy(oldList, 0, newList, 1, oldList.Length);
         n = new ObjectDirectory.PackList(o.snapshot, newList);
     }while (!packList.CompareAndSet(o, n));
 }
Пример #2
0
        private static IDictionary <string, PackFile> ReuseMap(ObjectDirectory.PackList old
                                                               )
        {
            IDictionary <string, PackFile> forReuse = new Dictionary <string, PackFile>();

            foreach (PackFile p in old.packs)
            {
                if (p.Invalid())
                {
                    // The pack instance is corrupted, and cannot be safely used
                    // again. Do not include it in our reuse map.
                    //
                    p.Close();
                    continue;
                }
                PackFile prior = forReuse.Put(p.GetPackFile().GetName(), p);
                if (prior != null)
                {
                    // This should never occur. It should be impossible for us
                    // to have two pack files with the same name, as all of them
                    // came out of the same directory. If it does, we promised to
                    // close any PackFiles we did not reuse, so close the second,
                    // readers are likely to be actively using the first.
                    //
                    forReuse.Put(prior.GetPackFile().GetName(), prior);
                    p.Close();
                }
            }
            return(forReuse);
        }
Пример #3
0
        public virtual void TestKeepFiles()
        {
            BranchBuilder bb = tr.Branch("refs/heads/master");

            bb.Commit().Add("A", "A").Add("B", "B").Create();
            stats = gc.GetStatistics();
            NUnit.Framework.Assert.AreEqual(4, stats.numberOfLooseObjects);
            NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
            NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackFiles);
            gc.Gc();
            stats = gc.GetStatistics();
            NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
            NUnit.Framework.Assert.AreEqual(4, stats.numberOfPackedObjects);
            NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
            Iterator <PackFile> packIt = ((ObjectDirectory)repo.ObjectDatabase).GetPacks().Iterator
                                             ();
            PackFile singlePack = packIt.Next();

            NUnit.Framework.Assert.IsFalse(packIt.HasNext());
            FilePath keepFile = new FilePath(singlePack.GetPackFile().GetPath() + ".keep");

            NUnit.Framework.Assert.IsFalse(keepFile.Exists());
            NUnit.Framework.Assert.IsTrue(keepFile.CreateNewFile());
            bb.Commit().Add("A", "A2").Add("B", "B2").Create();
            stats = gc.GetStatistics();
            NUnit.Framework.Assert.AreEqual(4, stats.numberOfLooseObjects);
            NUnit.Framework.Assert.AreEqual(4, stats.numberOfPackedObjects);
            NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
            gc.Gc();
            stats = gc.GetStatistics();
            NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
            NUnit.Framework.Assert.AreEqual(8, stats.numberOfPackedObjects);
            NUnit.Framework.Assert.AreEqual(2, stats.numberOfPackFiles);
            // check that no object is packed twice
            Iterator <PackFile> packs = ((ObjectDirectory)repo.ObjectDatabase).GetPacks().Iterator
                                            ();
            PackIndex ind1 = packs.Next().GetIndex();

            NUnit.Framework.Assert.AreEqual(4, ind1.GetObjectCount());
            PackIndex ind2 = packs.Next().GetIndex();

            NUnit.Framework.Assert.AreEqual(4, ind2.GetObjectCount());
            foreach (PackIndex.MutableEntry e in ind1)
            {
                if (ind2.HasObject(e.ToObjectId()))
                {
                    NUnit.Framework.Assert.IsFalse(ind2.HasObject(e.ToObjectId()), "the following object is in both packfiles: "
                                                   + e.ToObjectId());
                }
            }
        }
Пример #4
0
        /// <exception cref="System.IO.IOException"></exception>
        internal void CopyPackAsIs(PackFile pack, long length, bool validate, PackOutputStream
                                   @out)
        {
            MessageDigest md = null;

            if (validate)
            {
                md = Constants.NewMessageDigest();
                byte[] buf = @out.GetCopyBuffer();
                Pin(pack, 0);
                if (window.Copy(0, buf, 0, 12) != 12)
                {
                    pack.SetInvalid();
                    throw new IOException(JGitText.Get().packfileIsTruncated);
                }
                md.Update(buf, 0, 12);
            }
            long position  = 12;
            long remaining = length - (12 + 20);

            while (0 < remaining)
            {
                Pin(pack, position);
                int ptr = (int)(position - window.start);
                int n   = (int)Math.Min(window.Size() - ptr, remaining);
                window.Write(@out, position, n, md);
                position  += n;
                remaining -= n;
            }
            if (md != null)
            {
                byte[] buf     = new byte[20];
                byte[] actHash = md.Digest();
                Pin(pack, position);
                if (window.Copy(position, buf, 0, 20) != 20)
                {
                    pack.SetInvalid();
                    throw new IOException(JGitText.Get().packfileIsTruncated);
                }
                if (!Arrays.Equals(actHash, buf))
                {
                    pack.SetInvalid();
                    throw new IOException(MessageFormat.Format(JGitText.Get().packfileCorruptionDetected
                                                               , pack.GetPackFile().GetPath()));
                }
            }
        }