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    private:
00096    int LockFD;
00098    void *d;
00099 
00100    public:
00101    
00102    class Item;
00103    class Queue;
00104    class Worker;
00105    struct MethodConfig;
00106    struct ItemDesc;
00107    friend class Item;
00108    friend class Queue;
00109 
00110    typedef vector<Item *>::iterator ItemIterator;
00111    typedef vector<Item *>::const_iterator ItemCIterator;
00112 
00113    protected:
00114    
00120    vector<Item *> Items;
00121    
00127    Queue *Queues;
00128 
00134    Worker *Workers;
00135 
00146    MethodConfig *Configs;
00147 
00149    pkgAcquireStatus *Log;
00150 
00152    unsigned long ToFetch;
00153 
00154    // Configurable parameters for the scheduler
00155 
00157    enum QueueStrategy {
00161      QueueHost,
00165      QueueAccess} QueueMode;
00166 
00168    bool const Debug;
00170    bool Running;
00171 
00173    void Add(Item *Item);
00174 
00176    void Remove(Item *Item);
00177 
00179    void Add(Worker *Work);
00180 
00182    void Remove(Worker *Work);
00183    
00190    void Enqueue(ItemDesc &Item);
00191 
00193    void Dequeue(Item *Item);
00194 
00205    string QueueName(string URI,MethodConfig const *&Config);
00206 
00221    virtual void SetFds(int &Fd,fd_set *RSet,fd_set *WSet);
00222 
00233    virtual void RunFds(fd_set *RSet,fd_set *WSet);   
00234 
00241    void Bump();
00242    
00243    public:
00244 
00251    MethodConfig *GetConfig(string Access);
00252 
00254    enum RunResult {
00256      Continue,
00257 
00259      Failed,
00260 
00264      Cancelled};
00265 
00277    RunResult Run(int PulseInterval=500000);
00278 
00282    void Shutdown();
00283    
00288    inline Worker *WorkersBegin() {return Workers;};
00289 
00295    Worker *WorkerStep(Worker *I);
00296 
00298    inline ItemIterator ItemsBegin() {return Items.begin();};
00299 
00301    inline ItemIterator ItemsEnd() {return Items.end();};
00302    
00303    // Iterate over queued Item URIs
00304    class UriIterator;
00310    UriIterator UriBegin();
00312    UriIterator UriEnd();
00313    
00322    bool Clean(string Dir);
00323 
00327    unsigned long long TotalNeeded();
00328 
00332    unsigned long long FetchNeeded();
00333 
00337    unsigned long long PartialPresent();
00338 
00350    bool Setup(pkgAcquireStatus *Progress = NULL, string const &Lock = "");
00351 
00352    void SetLog(pkgAcquireStatus *Progress) { Log = Progress; }
00353 
00355    pkgAcquire(pkgAcquireStatus *Log) __deprecated;
00356    pkgAcquire();
00357 
00363    virtual ~pkgAcquire();
00364 
00365 };
00366 
00372 struct pkgAcquire::ItemDesc : public WeakPointable
00373 {
00375    string URI;
00377    string Description;
00379    string ShortDesc;
00381    Item *Owner;
00382 };
00383                                                                         /*}}}*/
00388 class pkgAcquire::Queue
00389 {
00390    friend class pkgAcquire;
00391    friend class pkgAcquire::UriIterator;
00392    friend class pkgAcquire::Worker;
00393 
00395    void *d;
00396 
00398    Queue *Next;
00399    
00400    protected:
00401 
00403    struct QItem : pkgAcquire::ItemDesc
00404    {
00406       QItem *Next;
00408       pkgAcquire::Worker *Worker;
00409 
00413       void operator =(pkgAcquire::ItemDesc const &I)
00414       {
00415          URI = I.URI;
00416          Description = I.Description;
00417          ShortDesc = I.ShortDesc;
00418          Owner = I.Owner;
00419       };
00420    };
00421    
00423    string Name;
00424 
00429    QItem *Items;
00430 
00440    pkgAcquire::Worker *Workers;
00441 
00443    pkgAcquire *Owner;
00444 
00448    signed long PipeDepth;
00449 
00453    unsigned long MaxPipeDepth;
00454    
00455    public:
00456    
00462    bool Enqueue(ItemDesc &Item);
00463 
00468    bool Dequeue(Item *Owner);
00469 
00478    QItem *FindItem(string URI,pkgAcquire::Worker *Owner);
00479 
00484    bool ItemStart(QItem *Itm,unsigned long long Size);
00485 
00496    bool ItemDone(QItem *Itm);
00497    
00505    bool Startup();
00506 
00516    bool Shutdown(bool Final);
00517 
00522    bool Cycle();
00523 
00534    void Bump();
00535    
00541    Queue(string Name,pkgAcquire *Owner);
00542 
00546    virtual ~Queue();
00547 };
00548                                                                         /*}}}*/
00550 class pkgAcquire::UriIterator
00551 {
00553    void *d;
00554 
00556    pkgAcquire::Queue *CurQ;
00558    pkgAcquire::Queue::QItem *CurItem;
00559    
00560    public:
00561    
00562    inline void operator ++() {operator ++(0);};
00563 
00564    void operator ++(int)
00565    {
00566       CurItem = CurItem->Next;
00567       while (CurItem == 0 && CurQ != 0)
00568       {
00569          CurItem = CurQ->Items;
00570          CurQ = CurQ->Next;
00571       }
00572    };
00573    
00574    inline pkgAcquire::ItemDesc const *operator ->() const {return CurItem;};
00575    inline bool operator !=(UriIterator const &rhs) const {return rhs.CurQ != CurQ || rhs.CurItem != CurItem;};
00576    inline bool operator ==(UriIterator const &rhs) const {return rhs.CurQ == CurQ && rhs.CurItem == CurItem;};
00577    
00582    UriIterator(pkgAcquire::Queue *Q) : CurQ(Q), CurItem(0)
00583    {
00584       while (CurItem == 0 && CurQ != 0)
00585       {
00586          CurItem = CurQ->Items;
00587          CurQ = CurQ->Next;
00588       }
00589    }   
00590    virtual ~UriIterator() {};
00591 };
00592                                                                         /*}}}*/
00594 struct pkgAcquire::MethodConfig
00595 {
00597    void *d;
00598    
00603    MethodConfig *Next;
00604    
00606    string Access;
00607 
00609    string Version;
00610 
00614    bool SingleInstance;
00615 
00617    bool Pipeline;
00618 
00623    bool SendConfig;
00624 
00628    bool LocalOnly;
00629 
00636    bool NeedsCleanup;
00637 
00639    bool Removable;
00640    
00646    MethodConfig();
00647 
00648    /* \brief Destructor, empty currently */
00649    virtual ~MethodConfig() {};
00650 };
00651                                                                         /*}}}*/
00656 class pkgAcquireStatus
00657 {
00659    void *d;
00660 
00661    protected:
00662    
00664    struct timeval Time;
00665 
00667    struct timeval StartTime;
00668 
00672    unsigned long long LastBytes;
00673 
00677    unsigned long long CurrentCPS;
00678 
00682    unsigned long long CurrentBytes;
00683 
00689    unsigned long long TotalBytes;
00690 
00694    unsigned long long FetchedBytes;
00695 
00699    unsigned long long ElapsedTime;
00700 
00706    unsigned long TotalItems;
00707 
00709    unsigned long CurrentItems;
00710    
00711    public:
00712 
00716    bool Update;
00717 
00724    bool MorePulses;
00725       
00732    virtual void Fetched(unsigned long long Size,unsigned long long ResumePoint);
00733    
00751    virtual bool MediaChange(string Media,string Drive) = 0;
00752    
00758    virtual void IMSHit(pkgAcquire::ItemDesc &/*Itm*/) {};
00759 
00761    virtual void Fetch(pkgAcquire::ItemDesc &/*Itm*/) {};
00762 
00764    virtual void Done(pkgAcquire::ItemDesc &/*Itm*/) {};
00765 
00769    virtual void Fail(pkgAcquire::ItemDesc &/*Itm*/) {};
00770 
00781    virtual bool Pulse(pkgAcquire *Owner);
00782 
00784    virtual void Start();
00785 
00787    virtual void Stop();
00788    
00790    pkgAcquireStatus();
00791    virtual ~pkgAcquireStatus() {};
00792 };
00793                                                                         /*}}}*/
00796 #endif