- initial import of revision 374 from cnc
[apt.git] / apt-pkg / acquire.h
1 // -*- mode: cpp; mode: fold -*-
2 // Description                                                          /*{{{*/
3 // $Id: acquire.h,v 1.2 2003/01/29 13:04:48 niemeyer Exp $
4 /* ######################################################################
5
6    Acquire - File Acquiration
7    
8    This module contians the Acquire system. It is responsible for bringing
9    files into the local pathname space. It deals with URIs for files and
10    URI handlers responsible for downloading or finding the URIs.
11    
12    Each file to download is represented by an Acquire::Item class subclassed
13    into a specialization. The Item class can add itself to several URI
14    acquire queues each prioritized by the download scheduler. When the 
15    system is run the proper URI handlers are spawned and the the acquire 
16    queues are fed into the handlers by the schedular until the queues are
17    empty. This allows for an Item to be downloaded from an alternate source
18    if the first try turns out to fail. It also alows concurrent downloading
19    of multiple items from multiple sources as well as dynamic balancing
20    of load between the sources.
21    
22    Schedualing of downloads is done on a first ask first get basis. This
23    preserves the order of the download as much as possible. And means the
24    fastest source will tend to process the largest number of files.
25    
26    Internal methods and queues for performing gzip decompression,
27    md5sum hashing and file copying are provided to allow items to apply
28    a number of transformations to the data files they are working with.
29    
30    ##################################################################### */
31                                                                         /*}}}*/
32 #ifndef PKGLIB_ACQUIRE_H
33 #define PKGLIB_ACQUIRE_H
34
35 #include <vector>
36 #include <string>
37
38 using std::vector;
39 using std::string;
40
41 #ifdef __GNUG__
42 #pragma interface "apt-pkg/acquire.h"
43 #endif 
44
45 #include <sys/time.h>
46 #include <unistd.h>
47
48 class pkgAcquireStatus;
49 class pkgAcquire
50 {   
51    public:
52    
53    class Item;
54    class Queue;
55    class Worker;
56    struct MethodConfig;
57    struct ItemDesc;
58    friend class Item;
59    friend class Queue;
60
61    typedef vector<Item *>::iterator ItemIterator;
62    typedef vector<Item *>::const_iterator ItemCIterator;
63    
64    protected:
65    
66    // List of items to fetch
67    vector<Item *> Items;
68    
69    // List of active queues and fetched method configuration parameters
70    Queue *Queues;
71    Worker *Workers;
72    MethodConfig *Configs;
73    pkgAcquireStatus *Log;
74    unsigned long ToFetch;
75
76    // Configurable parameters for the schedular
77    enum {QueueHost,QueueAccess} QueueMode;
78    bool Debug;
79    bool Running;
80    
81    void Add(Item *Item);
82    void Remove(Item *Item);
83    void Add(Worker *Work);
84    void Remove(Worker *Work);
85    
86    void Enqueue(ItemDesc &Item);
87    void Dequeue(Item *Item);
88    string QueueName(string URI,MethodConfig const *&Config);
89
90    // FDSET managers for derived classes
91    virtual void SetFds(int &Fd,fd_set *RSet,fd_set *WSet);
92    virtual void RunFds(fd_set *RSet,fd_set *WSet);   
93
94    // A queue calls this when it dequeues an item
95    void Bump();
96    
97    public:
98
99    MethodConfig *GetConfig(string Access);
100
101    enum RunResult {Continue,Failed,Cancelled};
102
103    RunResult Run();
104    void Shutdown();
105    
106    // Simple iteration mechanism
107    inline Worker *WorkersBegin() {return Workers;};
108    Worker *WorkerStep(Worker *I);
109    inline ItemIterator ItemsBegin() {return Items.begin();};
110    inline ItemIterator ItemsEnd() {return Items.end();};
111    
112    // Iterate over queued Item URIs
113    class UriIterator;
114    UriIterator UriBegin();
115    UriIterator UriEnd();
116    
117    // Cleans out the download dir
118    bool Clean(string Dir);
119
120    // Returns the size of the total download set
121    double TotalNeeded();
122    double FetchNeeded();
123    double PartialPresent();
124    
125    pkgAcquire(pkgAcquireStatus *Log = 0);
126    virtual ~pkgAcquire();
127 };
128
129 // Description of an Item+URI
130 struct pkgAcquire::ItemDesc
131 {
132    string URI;
133    string Description;
134    string ShortDesc;
135    Item *Owner;
136 };
137
138 // List of possible items queued for download.
139 class pkgAcquire::Queue
140 {
141    friend class pkgAcquire;
142    friend class pkgAcquire::UriIterator;
143    friend class pkgAcquire::Worker;
144    Queue *Next;
145    
146    protected:
147
148 #ifndef SWIG
149    // Queued item
150    struct QItem : pkgAcquire::ItemDesc
151    {
152       QItem *Next;      
153       pkgAcquire::Worker *Worker;
154       
155       void operator =(pkgAcquire::ItemDesc const &I)
156       {
157          URI = I.URI;
158          Description = I.Description;
159          ShortDesc = I.ShortDesc;
160          Owner = I.Owner;
161       };
162    };
163 #endif
164    
165    // Name of the queue
166    string Name;
167
168    // Items queued into this queue
169    QItem *Items;
170    pkgAcquire::Worker *Workers;
171    pkgAcquire *Owner;
172    signed long PipeDepth;
173    unsigned long MaxPipeDepth;
174    
175    public:
176    
177    // Put an item into this queue
178    void Enqueue(ItemDesc &Item);
179    bool Dequeue(Item *Owner);
180
181    // Find a Queued item
182    QItem *FindItem(string URI,pkgAcquire::Worker *Owner);
183    bool ItemStart(QItem *Itm,unsigned long Size);
184    bool ItemDone(QItem *Itm);
185    
186    bool Startup();
187    bool Shutdown(bool Final);
188    bool Cycle();
189    void Bump();
190    
191    Queue(string Name,pkgAcquire *Owner);
192    ~Queue();
193 };
194
195 class pkgAcquire::UriIterator
196 {
197    pkgAcquire::Queue *CurQ;
198    pkgAcquire::Queue::QItem *CurItem;
199    
200    public:
201    
202    // Advance to the next item
203    inline void operator ++() {operator ++();};
204    void operator ++(int)
205    {
206       CurItem = CurItem->Next;
207       while (CurItem == 0 && CurQ != 0)
208       {
209          CurItem = CurQ->Items;
210          CurQ = CurQ->Next;
211       }
212    };
213    
214    // Accessors
215    inline pkgAcquire::ItemDesc const *operator ->() const {return CurItem;};
216    inline bool operator !=(UriIterator const &rhs) const {return rhs.CurQ != CurQ || rhs.CurItem != CurItem;};
217    inline bool operator ==(UriIterator const &rhs) const {return rhs.CurQ == CurQ && rhs.CurItem == CurItem;};
218    
219    UriIterator(pkgAcquire::Queue *Q) : CurQ(Q), CurItem(0)
220    {
221       while (CurItem == 0 && CurQ != 0)
222       {
223          CurItem = CurQ->Items;
224          CurQ = CurQ->Next;
225       }
226    }   
227 };
228
229 // Configuration information from each method
230 struct pkgAcquire::MethodConfig
231 {
232    MethodConfig *Next;
233    
234    string Access;
235
236    string Version;
237    bool SingleInstance;
238    bool Pipeline;
239    bool SendConfig;
240    bool LocalOnly;
241    bool NeedsCleanup;
242    bool Removable;
243    // CNC:2004-04-27
244    bool HasPreferredURI;
245    bool DonePreferredURI;
246    string PreferredURI;
247    
248    MethodConfig();
249 };
250
251 class pkgAcquireStatus
252 {
253    protected:
254    
255    struct timeval Time;
256    struct timeval StartTime;
257    double LastBytes;
258    double CurrentCPS;
259    double CurrentBytes;
260    double TotalBytes;
261    double FetchedBytes;
262    unsigned long ElapsedTime;
263    unsigned long TotalItems;
264    unsigned long CurrentItems;
265    
266    public:
267
268    bool Update;
269    bool MorePulses;
270       
271    // Called by items when they have finished a real download
272    virtual void Fetched(unsigned long Size,unsigned long ResumePoint);
273    
274    // Called to change media
275    virtual bool MediaChange(string Media,string Drive) = 0;
276    
277    // Each of these is called by the workers when an event occures
278    virtual void IMSHit(pkgAcquire::ItemDesc &/*Itm*/) {};
279    virtual void Fetch(pkgAcquire::ItemDesc &/*Itm*/) {};
280    virtual void Done(pkgAcquire::ItemDesc &/*Itm*/) {};
281    virtual void Fail(pkgAcquire::ItemDesc &/*Itm*/) {};
282    virtual bool Pulse(pkgAcquire *Owner); // returns false on user cancel
283    virtual void Start();
284    virtual void Stop();
285    
286    pkgAcquireStatus();
287    virtual ~pkgAcquireStatus() {};
288 };
289
290 #endif
291
292 // vim:sts=3:sw=3