private bool DownloadPackedObject(ProgressMonitor monitor, AnyObjectId id)
        {
            // Search for the object in a remote pack whose index we have,
            // but whose pack we do not yet have.
            //
            var iter = new LinkedListIterator <RemotePack>(_unfetchedPacks);

            while (iter.hasNext() && !monitor.IsCancelled)
            {
                RemotePack pack = iter.next();
                try
                {
                    pack.OpenIndex(monitor);
                }
                catch (IOException err)
                {
                    // If the index won't open its either not found or
                    // its a format we don't recognize. In either case
                    // we may still be able to obtain the object from
                    // another source, so don't consider it a failure.
                    //
                    RecordError(id, err);
                    iter.remove();
                    continue;
                }

                if (monitor.IsCancelled)
                {
                    // If we were cancelled while the index was opening
                    // the open may have aborted. We can't search an
                    // unopen index.
                    //
                    return(false);
                }

                if (!pack.Index.HasObject(id))
                {
                    // Not in this pack? Try another.
                    //
                    continue;
                }

                // It should be in the associated pack. Download that
                // and attach it to the local repository so we can use
                // all of the contained objects.
                //
                try
                {
                    pack.DownloadPack(monitor);
                }
                catch (IOException err)
                {
                    // If the pack failed to download, index correctly,
                    // or open in the local repository we may still be
                    // able to obtain this object from another pack or
                    // an alternate.
                    //
                    RecordError(id, err);
                    continue;
                }
                finally
                {
                    // If the pack was good its in the local repository
                    // and Repository.hasObject(id) will succeed in the
                    // future, so we do not need this data anymore. If
                    // it failed the index and pack are unusable and we
                    // shouldn't consult them again.
                    //
                    pack.TmpIdx.DeleteFile();
                    iter.remove();
                }

                if (!_local.HasObject(id))
                {
                    // What the hell? This pack claimed to have
                    // the object, but after indexing we didn't
                    // actually find it in the pack.
                    //
                    RecordError(id,
                                new FileNotFoundException("Object " + id.Name + " not found in " + pack.PackName + "."));
                    continue;
                }

                // Complete any other objects that we can.
                //
                IIterator <ObjectId> pending = SwapFetchQueue();
                while (pending.hasNext())
                {
                    ObjectId p = pending.next();
                    if (pack.Index.HasObject(p))
                    {
                        pending.remove();
                        Process(p);
                    }
                    else
                    {
                        _workQueue.AddLast(p);
                    }
                }
                return(true);
            }
            return(false);
        }
예제 #2
0
        private bool DownloadPackedObject(ProgressMonitor monitor, AnyObjectId id)
        {
            IEnumerator <RemotePack> packItr = _unfetchedPacks.GetEnumerator();

            while (packItr.MoveNext() && !monitor.IsCancelled)
            {
                RemotePack pack = packItr.Current;
                try
                {
                    pack.OpenIndex(monitor);
                }
                catch (IOException err)
                {
                    RecordError(id, err);
                    _unfetchedPacks.Remove(pack);
                    continue;
                }

                if (monitor.IsCancelled)
                {
                    return(false);
                }

                if (!pack.Index.HasObject(id))
                {
                    continue;
                }

                try
                {
                    pack.DownloadPack(monitor);
                }
                catch (IOException err)
                {
                    RecordError(id, err);
                    continue;
                }
                finally
                {
                    pack.TmpIdx.Delete();
                    _unfetchedPacks.Remove(pack);
                }

                if (!_local.HasObject(id))
                {
                    RecordError(id,
                                new FileNotFoundException("Object " + id.Name + " not found in " + pack.PackName + "."));
                    continue;
                }

                IEnumerator <ObjectId> pending = SwapFetchQueue();
                while (pending.MoveNext())
                {
                    ObjectId p = pending.Current;
                    if (pack.Index.HasObject(p))
                    {
                        _workQueue.Remove(p);
                        Process(p);
                    }
                    else
                    {
                        _workQueue.AddLast(p);
                    }
                }
                return(true);
            }
            return(false);
        }