]> git.saurik.com Git - apt.git/blob - apt-inst/filelist.h
merged from debian-sid
[apt.git] / apt-inst / filelist.h
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: filelist.h,v 1.2 2001/02/20 07:03:16 jgg Exp $
4 /* ######################################################################
5
6 File Listing - Manages a Cache of File -> Package names.
7
8 This is identical to the Package cache, except that the generator
9 (which is much simpler) is integrated directly into the main class,
10 and it has been designed to handle live updates.
11
12 The storage content of the class is maintained in a memory map and is
13 written directly to the file system. Performance is traded against
14 space to give something that performs well and remains small.
15 The average per file usage is 32 bytes which yeilds about a meg every
16 36k files. Directory paths are collected into a binary tree and stored
17 only once, this offsets the cost of the hash nodes enough to keep
18 memory usage slightly less than the sum of the filenames.
19
20 The file names are stored into a fixed size chained hash table that is
21 linked to the package name and to the directory component.
22
23 Each file node has a set of associated flags that indicate the current
24 state of the file.
25
26 ##################################################################### */
27 /*}}}*/
28 #ifndef PKGLIB_FILELIST_H
29 #define PKGLIB_FILELIST_H
30
31 #include <apt-pkg/mmap.h>
32
33 #include <cstring>
34 #include <string>
35
36 class pkgFLCache
37 {
38 public:
39 struct Header;
40 struct Node;
41 struct Directory;
42 struct Package;
43 struct Diversion;
44 struct ConfFile;
45
46 class NodeIterator;
47 class DirIterator;
48 class PkgIterator;
49 class DiverIterator;
50
51 protected:
52 std::string CacheFile;
53 DynamicMMap &Map;
54 map_ptrloc LastTreeLookup;
55 unsigned long LastLookupSize;
56
57 // Helpers for the addition algorithms
58 map_ptrloc TreeLookup(map_ptrloc *Base,const char *Text,const char *TextEnd,
59 unsigned long Size,unsigned int *Count = 0,
60 bool Insert = false);
61
62 public:
63
64 // Pointers to the arrays of items
65 Header *HeaderP;
66 Node *NodeP;
67 Directory *DirP;
68 Package *PkgP;
69 Diversion *DiverP;
70 ConfFile *ConfP;
71 char *StrP;
72 unsigned char *AnyP;
73
74 // Quick accessors
75 Node *FileHash;
76
77 // Accessors
78 Header &Head() {return *HeaderP;};
79 void PrintTree(map_ptrloc Base,unsigned long Size);
80
81 // Add/Find things
82 PkgIterator GetPkg(const char *Name,const char *End,bool Insert);
83 inline PkgIterator GetPkg(const char *Name,bool Insert);
84 NodeIterator GetNode(const char *Name,
85 const char *NameEnd,
86 map_ptrloc Loc,
87 bool Insert,bool Divert);
88 Node *HashNode(NodeIterator const &N);
89 void DropNode(map_ptrloc Node);
90
91 inline DiverIterator DiverBegin();
92
93 // Diversion control
94 void BeginDiverLoad();
95 void FinishDiverLoad();
96 bool AddDiversion(PkgIterator const &Owner,const char *From,
97 const char *To);
98 bool AddConfFile(const char *Name,const char *NameEnd,
99 PkgIterator const &Owner,const unsigned char *Sum);
100
101 pkgFLCache(DynamicMMap &Map);
102 // ~pkgFLCache();
103 };
104
105 struct pkgFLCache::Header
106 {
107 // Signature information
108 unsigned long Signature;
109 short MajorVersion;
110 short MinorVersion;
111 bool Dirty;
112
113 // Size of structure values
114 unsigned HeaderSz;
115 unsigned NodeSz;
116 unsigned DirSz;
117 unsigned PackageSz;
118 unsigned DiversionSz;
119 unsigned ConfFileSz;
120
121 // Structure Counts;
122 unsigned int NodeCount;
123 unsigned int DirCount;
124 unsigned int PackageCount;
125 unsigned int DiversionCount;
126 unsigned int ConfFileCount;
127 unsigned int HashSize;
128 unsigned long UniqNodes;
129
130 // Offsets
131 map_ptrloc FileHash;
132 map_ptrloc DirTree;
133 map_ptrloc Packages;
134 map_ptrloc Diversions;
135
136 /* Allocation pools, there should be one of these for each structure
137 excluding the header */
138 DynamicMMap::Pool Pools[5];
139
140 bool CheckSizes(Header &Against) const;
141 Header();
142 };
143
144 /* The bit field is used to advoid incurring an extra 4 bytes x 40000,
145 Pointer is the most infrequently used member of the structure */
146 struct pkgFLCache::Node
147 {
148 map_ptrloc Dir; // Dir
149 map_ptrloc File; // String
150 unsigned Pointer:24; // Package/Diversion/ConfFile
151 unsigned Flags:8; // Package
152 map_ptrloc Next; // Node
153 map_ptrloc NextPkg; // Node
154
155 enum Flags {Diversion = (1<<0),ConfFile = (1<<1),
156 NewConfFile = (1<<2),NewFile = (1<<3),
157 Unpacked = (1<<4),Replaced = (1<<5)};
158 };
159
160 struct pkgFLCache::Directory
161 {
162 map_ptrloc Left; // Directory
163 map_ptrloc Right; // Directory
164 map_ptrloc Name; // String
165 };
166
167 struct pkgFLCache::Package
168 {
169 map_ptrloc Left; // Package
170 map_ptrloc Right; // Package
171 map_ptrloc Name; // String
172 map_ptrloc Files; // Node
173 };
174
175 struct pkgFLCache::Diversion
176 {
177 map_ptrloc OwnerPkg; // Package
178 map_ptrloc DivertFrom; // Node
179 map_ptrloc DivertTo; // String
180
181 map_ptrloc Next; // Diversion
182 unsigned long Flags;
183
184 enum Flags {Touched = (1<<0)};
185 };
186
187 struct pkgFLCache::ConfFile
188 {
189 map_ptrloc OwnerPkg; // Package
190 unsigned char MD5[16];
191 };
192
193 class pkgFLCache::PkgIterator
194 {
195 Package *Pkg;
196 pkgFLCache *Owner;
197
198 public:
199
200 inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;}
201
202 // Accessors
203 inline Package *operator ->() {return Pkg;};
204 inline Package const *operator ->() const {return Pkg;};
205 inline Package const &operator *() const {return *Pkg;};
206 inline operator Package *() {return Pkg == Owner->PkgP?0:Pkg;};
207 inline operator Package const *() const {return Pkg == Owner->PkgP?0:Pkg;};
208
209 inline unsigned long Offset() const {return Pkg - Owner->PkgP;};
210 inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;};
211 inline pkgFLCache::NodeIterator Files() const;
212
213 PkgIterator() : Pkg(0), Owner(0) {};
214 PkgIterator(pkgFLCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner) {};
215 };
216
217 class pkgFLCache::DirIterator
218 {
219 Directory *Dir;
220 pkgFLCache *Owner;
221
222 public:
223
224 // Accessors
225 inline Directory *operator ->() {return Dir;};
226 inline Directory const *operator ->() const {return Dir;};
227 inline Directory const &operator *() const {return *Dir;};
228 inline operator Directory *() {return Dir == Owner->DirP?0:Dir;};
229 inline operator Directory const *() const {return Dir == Owner->DirP?0:Dir;};
230
231 inline const char *Name() const {return Dir->Name == 0?0:Owner->StrP + Dir->Name;};
232
233 DirIterator() : Dir(0), Owner(0) {};
234 DirIterator(pkgFLCache &Owner,Directory *Trg) : Dir(Trg), Owner(&Owner) {};
235 };
236
237 class pkgFLCache::DiverIterator
238 {
239 Diversion *Diver;
240 pkgFLCache *Owner;
241
242 public:
243
244 // Iteration
245 void operator ++(int) {if (Diver != Owner->DiverP) Diver = Owner->DiverP + Diver->Next;};
246 inline void operator ++() {operator ++(0);};
247 inline bool end() const {return Owner == 0 || Diver == Owner->DiverP;};
248
249 // Accessors
250 inline Diversion *operator ->() {return Diver;};
251 inline Diversion const *operator ->() const {return Diver;};
252 inline Diversion const &operator *() const {return *Diver;};
253 inline operator Diversion *() {return Diver == Owner->DiverP?0:Diver;};
254 inline operator Diversion const *() const {return Diver == Owner->DiverP?0:Diver;};
255
256 inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Diver->OwnerPkg);};
257 inline NodeIterator DivertFrom() const;
258 inline NodeIterator DivertTo() const;
259
260 DiverIterator() : Diver(0), Owner(0) {};
261 DiverIterator(pkgFLCache &Owner,Diversion *Trg) : Diver(Trg), Owner(&Owner) {};
262 };
263
264 class pkgFLCache::NodeIterator
265 {
266 Node *Nde;
267 enum {NdePkg, NdeHash} Type;
268 pkgFLCache *Owner;
269
270 public:
271
272 // Iteration
273 void operator ++(int) {if (Nde != Owner->NodeP) Nde = Owner->NodeP +
274 (Type == NdePkg?Nde->NextPkg:Nde->Next);};
275 inline void operator ++() {operator ++(0);};
276 inline bool end() const {return Owner == 0 || Nde == Owner->NodeP;};
277
278 // Accessors
279 inline Node *operator ->() {return Nde;};
280 inline Node const *operator ->() const {return Nde;};
281 inline Node const &operator *() const {return *Nde;};
282 inline operator Node *() {return Nde == Owner->NodeP?0:Nde;};
283 inline operator Node const *() const {return Nde == Owner->NodeP?0:Nde;};
284 inline unsigned long Offset() const {return Nde - Owner->NodeP;};
285 inline DirIterator Dir() const {return DirIterator(*Owner,Owner->DirP + Nde->Dir);};
286 inline DiverIterator Diversion() const {return DiverIterator(*Owner,Owner->DiverP + Nde->Pointer);};
287 inline const char *File() const {return Nde->File == 0?0:Owner->StrP + Nde->File;};
288 inline const char *DirN() const {return Owner->StrP + Owner->DirP[Nde->Dir].Name;};
289 Package *RealPackage() const;
290
291 NodeIterator() : Nde(0), Type(NdeHash), Owner(0) {};
292 NodeIterator(pkgFLCache &Owner) : Nde(Owner.NodeP), Type(NdeHash), Owner(&Owner) {};
293 NodeIterator(pkgFLCache &Owner,Node *Trg) : Nde(Trg), Type(NdeHash), Owner(&Owner) {};
294 NodeIterator(pkgFLCache &Owner,Node *Trg,Package *) : Nde(Trg), Type(NdePkg), Owner(&Owner) {};
295 };
296
297 /* Inlines with forward references that cannot be included directly in their
298 respsective classes */
299 inline pkgFLCache::NodeIterator pkgFLCache::DiverIterator::DivertFrom() const
300 {return NodeIterator(*Owner,Owner->NodeP + Diver->DivertFrom);};
301 inline pkgFLCache::NodeIterator pkgFLCache::DiverIterator::DivertTo() const
302 {return NodeIterator(*Owner,Owner->NodeP + Diver->DivertTo);};
303
304 inline pkgFLCache::NodeIterator pkgFLCache::PkgIterator::Files() const
305 {return NodeIterator(*Owner,Owner->NodeP + Pkg->Files,Pkg);};
306
307 inline pkgFLCache::DiverIterator pkgFLCache::DiverBegin()
308 {return DiverIterator(*this,DiverP + HeaderP->Diversions);};
309
310 inline pkgFLCache::PkgIterator pkgFLCache::GetPkg(const char *Name,bool Insert)
311 {return GetPkg(Name,Name+strlen(Name),Insert);};
312
313 #endif