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