apt @VERSION@
acquire.h
Go to the documentation of this file.
00001 // -*- mode: cpp; mode: fold -*-
00002 // Description                                                          /*{{{*/
00003 // $Id: acquire.h,v 1.29.2.1 2003/12/24 23:09:17 mdz Exp $
00004 /* ######################################################################
00005 
00006    Acquire - File Acquiration
00007    
00008    This module contians the Acquire system. It is responsible for bringing
00009    files into the local pathname space. It deals with URIs for files and
00010    URI handlers responsible for downloading or finding the URIs.
00011    
00012    Each file to download is represented by an Acquire::Item class subclassed
00013    into a specialization. The Item class can add itself to several URI
00014    acquire queues each prioritized by the download scheduler. When the 
00015    system is run the proper URI handlers are spawned and the the acquire 
00016    queues are fed into the handlers by the schedular until the queues are
00017    empty. This allows for an Item to be downloaded from an alternate source
00018    if the first try turns out to fail. It also alows concurrent downloading
00019    of multiple items from multiple sources as well as dynamic balancing
00020    of load between the sources.
00021    
00022    Schedualing of downloads is done on a first ask first get basis. This
00023    preserves the order of the download as much as possible. And means the
00024    fastest source will tend to process the largest number of files.
00025    
00026    Internal methods and queues for performing gzip decompression,
00027    md5sum hashing and file copying are provided to allow items to apply
00028    a number of transformations to the data files they are working with.
00029    
00030    ##################################################################### */
00031                                                                         /*}}}*/
00032                                                                         /*}}}*/
00058 
00066 #ifndef PKGLIB_ACQUIRE_H
00067 #define PKGLIB_ACQUIRE_H
00068 
00069 #include <apt-pkg/macros.h>
00070 #include <apt-pkg/weakptr.h>
00071 
00072 #include <vector>
00073 #include <string>
00074 
00075 using std::vector;
00076 using std::string;
00077 
00078 
00079 #include <sys/time.h>
00080 #include <unistd.h>
00081 
00082 class pkgAcquireStatus;
00083 
00092 class pkgAcquire
00093 {   
00094    public:
00095    
00096    class Item;
00097    class Queue;
00098    class Worker;
00099    struct MethodConfig;
00100    struct ItemDesc;
00101    friend class Item;
00102    friend class Queue;
00103 
00104    typedef vector<Item *>::iterator ItemIterator;
00105    typedef vector<Item *>::const_iterator ItemCIterator;
00106 
00107    protected:
00108    
00114    vector<Item *> Items;
00115    
00121    Queue *Queues;
00122 
00128    Worker *Workers;
00129 
00140    MethodConfig *Configs;
00141 
00143    pkgAcquireStatus *Log;
00144 
00151    unsigned long ToFetch;
00152 
00153    // Configurable parameters for the scheduler
00154 
00156    enum QueueStrategy {
00160      QueueHost,
00164      QueueAccess} QueueMode;
00165 
00167    bool const Debug;
00169    bool Running;
00170 
00172    void Add(Item *Item);
00173 
00175    void Remove(Item *Item);
00176 
00178    void Add(Worker *Work);
00179 
00181    void Remove(Worker *Work);
00182    
00189    void Enqueue(ItemDesc &Item);
00190 
00192    void Dequeue(Item *Item);
00193 
00204    string QueueName(string URI,MethodConfig const *&Config);
00205 
00220    virtual void SetFds(int &Fd,fd_set *RSet,fd_set *WSet);
00221 
00232    virtual void RunFds(fd_set *RSet,fd_set *WSet);   
00233 
00240    void Bump();
00241    
00242    public:
00243 
00250    MethodConfig *GetConfig(string Access);
00251 
00253    enum RunResult {
00255      Continue,
00256 
00258      Failed,
00259 
00263      Cancelled};
00264 
00276    RunResult Run(int PulseInterval=500000);
00277 
00281    void Shutdown();
00282    
00287    inline Worker *WorkersBegin() {return Workers;};
00288 
00294    Worker *WorkerStep(Worker *I);
00295 
00297    inline ItemIterator ItemsBegin() {return Items.begin();};
00298 
00300    inline ItemIterator ItemsEnd() {return Items.end();};
00301    
00302    // Iterate over queued Item URIs
00303    class UriIterator;
00309    UriIterator UriBegin();
00311    UriIterator UriEnd();
00312    
00321    bool Clean(string Dir);
00322 
00326    unsigned long long TotalNeeded();
00327 
00331    unsigned long long FetchNeeded();
00332 
00336    unsigned long long PartialPresent();
00337 
00349    bool Setup(pkgAcquireStatus *Progress = NULL, string const &Lock = "");
00350 
00351    void SetLog(pkgAcquireStatus *Progress) { Log = Progress; }
00352 
00354    pkgAcquire(pkgAcquireStatus *Log) __deprecated;
00355    pkgAcquire();
00356 
00362    virtual ~pkgAcquire();
00363 
00364    private:
00366    int LockFD;
00367 };
00368 
00374 struct pkgAcquire::ItemDesc : public WeakPointable
00375 {
00377    string URI;
00379    string Description;
00381    string ShortDesc;
00383    Item *Owner;
00384 };
00385                                                                         /*}}}*/
00390 class pkgAcquire::Queue
00391 {
00392    friend class pkgAcquire;
00393    friend class pkgAcquire::UriIterator;
00394    friend class pkgAcquire::Worker;
00395 
00397    Queue *Next;
00398    
00399    protected:
00400 
00402    struct QItem : pkgAcquire::ItemDesc
00403    {
00405       QItem *Next;
00407       pkgAcquire::Worker *Worker;
00408 
00412       void operator =(pkgAcquire::ItemDesc const &I)
00413       {
00414          URI = I.URI;
00415          Description = I.Description;
00416          ShortDesc = I.ShortDesc;
00417          Owner = I.Owner;
00418       };
00419    };
00420    
00422    string Name;
00423 
00428    QItem *Items;
00429 
00439    pkgAcquire::Worker *Workers;
00440 
00442    pkgAcquire *Owner;
00443 
00447    signed long PipeDepth;
00448 
00452    unsigned long MaxPipeDepth;
00453    
00454    public:
00455    
00461    bool Enqueue(ItemDesc &Item);
00462 
00467    bool Dequeue(Item *Owner);
00468 
00477    QItem *FindItem(string URI,pkgAcquire::Worker *Owner);
00478 
00483    bool ItemStart(QItem *Itm,unsigned long Size);
00484 
00495    bool ItemDone(QItem *Itm);
00496    
00504    bool Startup();
00505 
00515    bool Shutdown(bool Final);
00516 
00521    bool Cycle();
00522 
00533    void Bump();
00534    
00540    Queue(string Name,pkgAcquire *Owner);
00541 
00545    ~Queue();
00546 };
00547                                                                         /*}}}*/
00549 class pkgAcquire::UriIterator
00550 {
00552    pkgAcquire::Queue *CurQ;
00554    pkgAcquire::Queue::QItem *CurItem;
00555    
00556    public:
00557    
00558    inline void operator ++() {operator ++(0);};
00559 
00560    void operator ++(int)
00561    {
00562       CurItem = CurItem->Next;
00563       while (CurItem == 0 && CurQ != 0)
00564       {
00565          CurItem = CurQ->Items;
00566          CurQ = CurQ->Next;
00567       }
00568    };
00569    
00570    inline pkgAcquire::ItemDesc const *operator ->() const {return CurItem;};
00571    inline bool operator !=(UriIterator const &rhs) const {return rhs.CurQ != CurQ || rhs.CurItem != CurItem;};
00572    inline bool operator ==(UriIterator const &rhs) const {return rhs.CurQ == CurQ && rhs.CurItem == CurItem;};
00573    
00578    UriIterator(pkgAcquire::Queue *Q) : CurQ(Q), CurItem(0)
00579    {
00580       while (CurItem == 0 && CurQ != 0)
00581       {
00582          CurItem = CurQ->Items;
00583          CurQ = CurQ->Next;
00584       }
00585    }   
00586 };
00587                                                                         /*}}}*/
00589 struct pkgAcquire::MethodConfig
00590 {
00595    MethodConfig *Next;
00596    
00598    string Access;
00599 
00601    string Version;
00602 
00606    bool SingleInstance;
00607 
00609    bool Pipeline;
00610 
00615    bool SendConfig;
00616 
00620    bool LocalOnly;
00621 
00628    bool NeedsCleanup;
00629 
00631    bool Removable;
00632    
00638    MethodConfig();
00639 };
00640                                                                         /*}}}*/
00647 class pkgAcquireStatus
00648 {
00649    protected:
00650    
00652    struct timeval Time;
00653 
00655    struct timeval StartTime;
00656 
00660    double LastBytes;
00661 
00665    double CurrentCPS;
00666 
00670    double CurrentBytes;
00671 
00677    double TotalBytes;
00678 
00682    double FetchedBytes;
00683 
00687    unsigned long ElapsedTime;
00688 
00694    unsigned long TotalItems;
00695 
00697    unsigned long CurrentItems;
00698    
00699    public:
00700 
00704    bool Update;
00705 
00712    bool MorePulses;
00713       
00720    virtual void Fetched(unsigned long Size,unsigned long ResumePoint);
00721    
00739    virtual bool MediaChange(string Media,string Drive) = 0;
00740    
00746    virtual void IMSHit(pkgAcquire::ItemDesc &/*Itm*/) {};
00747 
00749    virtual void Fetch(pkgAcquire::ItemDesc &/*Itm*/) {};
00750 
00752    virtual void Done(pkgAcquire::ItemDesc &/*Itm*/) {};
00753 
00757    virtual void Fail(pkgAcquire::ItemDesc &/*Itm*/) {};
00758 
00769    virtual bool Pulse(pkgAcquire *Owner);
00770 
00772    virtual void Start();
00773 
00775    virtual void Stop();
00776    
00778    pkgAcquireStatus();
00779    virtual ~pkgAcquireStatus() {};
00780 };
00781                                                                         /*}}}*/
00784 #endif