]> git.saurik.com Git - apt.git/blob - apt-inst/filelist.h
* apt-pkg/deb/debmetaindex.cc:
[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
32 #include <cstring>
33 #include <apt-pkg/mmap.h>
34
35 class pkgFLCache
36 {
37 public:
38 struct Header;
39 struct Node;
40 struct Directory;
41 struct Package;
42 struct Diversion;
43 struct ConfFile;
44
45 class NodeIterator;
46 class DirIterator;
47 class PkgIterator;
48 class DiverIterator;
49
50 protected:
51 string CacheFile;
52 DynamicMMap &Map;
53 map_ptrloc LastTreeLookup;
54 unsigned long LastLookupSize;
55
56 // Helpers for the addition algorithms
57 map_ptrloc TreeLookup(map_ptrloc *Base,const char *Text,const char *TextEnd,
58 unsigned long Size,unsigned int *Count = 0,
59 bool Insert = false);
60
61 public:
62
63 // Pointers to the arrays of items
64 Header *HeaderP;
65 Node *NodeP;
66 Directory *DirP;
67 Package *PkgP;
68 Diversion *DiverP;
69 ConfFile *ConfP;
70 char *StrP;
71 unsigned char *AnyP;
72
73 // Quick accessors
74 Node *FileHash;
75
76 // Accessors
77 Header &Head() {return *HeaderP;};
78 void PrintTree(map_ptrloc Base,unsigned long Size);
79
80 // Add/Find things
81 PkgIterator GetPkg(const char *Name,const char *End,bool Insert);
82 inline PkgIterator GetPkg(const char *Name,bool Insert);
83 NodeIterator GetNode(const char *Name,
84 const char *NameEnd,
85 map_ptrloc Loc,
86 bool Insert,bool Divert);
87 Node *HashNode(NodeIterator const &N);
88 void DropNode(map_ptrloc Node);
89
90 inline DiverIterator DiverBegin();
91
92 // Diversion control
93 void BeginDiverLoad();
94 void FinishDiverLoad();
95 bool AddDiversion(PkgIterator const &Owner,const char *From,
96 const char *To);
97 bool AddConfFile(const char *Name,const char *NameEnd,
98 PkgIterator const &Owner,const unsigned char *Sum);
99
100 pkgFLCache(DynamicMMap &Map);
101 // ~pkgFLCache();
102 };
103
104 struct pkgFLCache::Header
105 {
106 // Signature information
107 unsigned long Signature;
108 short MajorVersion;
109 short MinorVersion;
110 bool Dirty;
111
112 // Size of structure values
113 unsigned HeaderSz;
114 unsigned NodeSz;
115 unsigned DirSz;
116 unsigned PackageSz;
117 unsigned DiversionSz;
118 unsigned ConfFileSz;
119
120 // Structure Counts;
121 unsigned int NodeCount;
122 unsigned int DirCount;
123 unsigned int PackageCount;
124 unsigned int DiversionCount;
125 unsigned int ConfFileCount;
126 unsigned int HashSize;
127 unsigned long UniqNodes;
128
129 // Offsets
130 map_ptrloc FileHash;
131 map_ptrloc DirTree;
132 map_ptrloc Packages;
133 map_ptrloc Diversions;
134
135 /* Allocation pools, there should be one of these for each structure
136 excluding the header */
137 DynamicMMap::Pool Pools[5];
138
139 bool CheckSizes(Header &Against) const;
140 Header();
141 };
142
143 /* The bit field is used to advoid incurring an extra 4 bytes x 40000,
144 Pointer is the most infrequently used member of the structure */
145 struct pkgFLCache::Node
146 {
147 map_ptrloc Dir; // Dir
148 map_ptrloc File; // String
149 unsigned Pointer:24; // Package/Diversion/ConfFile
150 unsigned Flags:8; // Package
151 map_ptrloc Next; // Node
152 map_ptrloc NextPkg; // Node
153
154 enum Flags {Diversion = (1<<0),ConfFile = (1<<1),
155 NewConfFile = (1<<2),NewFile = (1<<3),
156 Unpacked = (1<<4),Replaced = (1<<5)};
157 };
158
159 struct pkgFLCache::Directory
160 {
161 map_ptrloc Left; // Directory
162 map_ptrloc Right; // Directory
163 map_ptrloc Name; // String
164 };
165
166 struct pkgFLCache::Package
167 {
168 map_ptrloc Left; // Package
169 map_ptrloc Right; // Package
170 map_ptrloc Name; // String
171 map_ptrloc Files; // Node
172 };
173
174 struct pkgFLCache::Diversion
175 {
176 map_ptrloc OwnerPkg; // Package
177 map_ptrloc DivertFrom; // Node
178 map_ptrloc DivertTo; // String
179
180 map_ptrloc Next; // Diversion
181 unsigned long Flags;
182
183 enum Flags {Touched = (1<<0)};
184 };
185
186 struct pkgFLCache::ConfFile
187 {
188 map_ptrloc OwnerPkg; // Package
189 unsigned char MD5[16];
190 };
191
192 class pkgFLCache::PkgIterator
193 {
194 Package *Pkg;
195 pkgFLCache *Owner;
196
197 public:
198
199 inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;}
200
201 // Accessors
202 inline Package *operator ->() {return Pkg;};
203 inline Package const *operator ->() const {return Pkg;};
204 inline Package const &operator *() const {return *Pkg;};
205 inline operator Package *() {return Pkg == Owner->PkgP?0:Pkg;};
206 inline operator Package const *() const {return Pkg == Owner->PkgP?0:Pkg;};
207
208 inline unsigned long Offset() const {return Pkg - Owner->PkgP;};
209 inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;};
210 inline pkgFLCache::NodeIterator Files() const;
211
212 PkgIterator() : Pkg(0), Owner(0) {};
213 PkgIterator(pkgFLCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner) {};
214 };
215
216 class pkgFLCache::DirIterator
217 {
218 Directory *Dir;
219 pkgFLCache *Owner;
220
221 public:
222
223 // Accessors
224 inline Directory *operator ->() {return Dir;};
225 inline Directory const *operator ->() const {return Dir;};
226 inline Directory const &operator *() const {return *Dir;};
227 inline operator Directory *() {return Dir == Owner->DirP?0:Dir;};
228 inline operator Directory const *() const {return Dir == Owner->DirP?0:Dir;};
229
230 inline const char *Name() const {return Dir->Name == 0?0:Owner->StrP + Dir->Name;};
231
232 DirIterator() : Dir(0), Owner(0) {};
233 DirIterator(pkgFLCache &Owner,Directory *Trg) : Dir(Trg), Owner(&Owner) {};
234 };
235
236 class pkgFLCache::DiverIterator
237 {
238 Diversion *Diver;
239 pkgFLCache *Owner;
240
241 public:
242
243 // Iteration
244 void operator ++(int) {if (Diver != Owner->DiverP) Diver = Owner->DiverP + Diver->Next;};
245 inline void operator ++() {operator ++(0);};
246 inline bool end() const {return Owner == 0 || Diver == Owner->DiverP;};
247
248 // Accessors
249 inline Diversion *operator ->() {return Diver;};
250 inline Diversion const *operator ->() const {return Diver;};
251 inline Diversion const &operator *() const {return *Diver;};
252 inline operator Diversion *() {return Diver == Owner->DiverP?0:Diver;};
253 inline operator Diversion const *() const {return Diver == Owner->DiverP?0:Diver;};
254
255 inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Diver->OwnerPkg);};
256 inline NodeIterator DivertFrom() const;
257 inline NodeIterator DivertTo() const;
258
259 DiverIterator() : Diver(0), Owner(0) {};
260 DiverIterator(pkgFLCache &Owner,Diversion *Trg) : Diver(Trg), Owner(&Owner) {};
261 };
262
263 class pkgFLCache::NodeIterator
264 {
265 Node *Nde;
266 enum {NdePkg, NdeHash} Type;
267 pkgFLCache *Owner;
268
269 public:
270
271 // Iteration
272 void operator ++(int) {if (Nde != Owner->NodeP) Nde = Owner->NodeP +
273 (Type == NdePkg?Nde->NextPkg:Nde->Next);};
274 inline void operator ++() {operator ++(0);};
275 inline bool end() const {return Owner == 0 || Nde == Owner->NodeP;};
276
277 // Accessors
278 inline Node *operator ->() {return Nde;};
279 inline Node const *operator ->() const {return Nde;};
280 inline Node const &operator *() const {return *Nde;};
281 inline operator Node *() {return Nde == Owner->NodeP?0:Nde;};
282 inline operator Node const *() const {return Nde == Owner->NodeP?0:Nde;};
283 inline unsigned long Offset() const {return Nde - Owner->NodeP;};
284 inline DirIterator Dir() const {return DirIterator(*Owner,Owner->DirP + Nde->Dir);};
285 inline DiverIterator Diversion() const {return DiverIterator(*Owner,Owner->DiverP + Nde->Pointer);};
286 inline const char *File() const {return Nde->File == 0?0:Owner->StrP + Nde->File;};
287 inline const char *DirN() const {return Owner->StrP + Owner->DirP[Nde->Dir].Name;};
288 Package *RealPackage() const;
289
290 NodeIterator() : Nde(0), Type(NdeHash), Owner(0) {};
291 NodeIterator(pkgFLCache &Owner) : Nde(Owner.NodeP), Type(NdeHash), Owner(&Owner) {};
292 NodeIterator(pkgFLCache &Owner,Node *Trg) : Nde(Trg), Type(NdeHash), Owner(&Owner) {};
293 NodeIterator(pkgFLCache &Owner,Node *Trg,Package *) : Nde(Trg), Type(NdePkg), Owner(&Owner) {};
294 };
295
296 /* Inlines with forward references that cannot be included directly in their
297 respsective classes */
298 inline pkgFLCache::NodeIterator pkgFLCache::DiverIterator::DivertFrom() const
299 {return NodeIterator(*Owner,Owner->NodeP + Diver->DivertFrom);};
300 inline pkgFLCache::NodeIterator pkgFLCache::DiverIterator::DivertTo() const
301 {return NodeIterator(*Owner,Owner->NodeP + Diver->DivertTo);};
302
303 inline pkgFLCache::NodeIterator pkgFLCache::PkgIterator::Files() const
304 {return NodeIterator(*Owner,Owner->NodeP + Pkg->Files,Pkg);};
305
306 inline pkgFLCache::DiverIterator pkgFLCache::DiverBegin()
307 {return DiverIterator(*this,DiverP + HeaderP->Diversions);};
308
309 inline pkgFLCache::PkgIterator pkgFLCache::GetPkg(const char *Name,bool Insert)
310 {return GetPkg(Name,Name+strlen(Name),Insert);};
311
312 #endif