1 // -*- mode: cpp; mode: fold -*-
3 // $Id: filelist.h,v 1.2 2001/02/20 07:03:16 jgg Exp $
4 /* ######################################################################
6 File Listing - Manages a Cache of File -> Package names.
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.
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.
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.
23 Each file node has a set of associated flags that indicate the current
26 ##################################################################### */
28 #ifndef PKGLIB_FILELIST_H
29 #define PKGLIB_FILELIST_H
32 #pragma interface "apt-pkg/filelist.h"
35 #include <apt-pkg/mmap.h>
55 map_ptrloc LastTreeLookup
;
56 unsigned long LastLookupSize
;
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,
65 // Pointers to the arrays of items
79 Header
&Head() {return *HeaderP
;};
80 void PrintTree(map_ptrloc Base
,unsigned long Size
);
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
,
88 bool Insert
,bool Divert
);
89 Node
*HashNode(NodeIterator
const &N
);
90 void DropNode(map_ptrloc Node
);
92 inline DiverIterator
DiverBegin();
95 void BeginDiverLoad();
96 void FinishDiverLoad();
97 bool AddDiversion(PkgIterator
const &Owner
,const char *From
,
99 bool AddConfFile(const char *Name
,const char *NameEnd
,
100 PkgIterator
const &Owner
,const unsigned char *Sum
);
102 pkgFLCache(DynamicMMap
&Map
);
106 struct pkgFLCache::Header
108 // Signature information
109 unsigned long Signature
;
114 // Size of structure values
119 unsigned DiversionSz
;
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
;
135 map_ptrloc Diversions
;
137 /* Allocation pools, there should be one of these for each structure
138 excluding the header */
139 DynamicMMap::Pool Pools
[5];
141 bool CheckSizes(Header
&Against
) const;
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 */
147 struct pkgFLCache::Node
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
156 enum Flags
{Diversion
= (1<<0),ConfFile
= (1<<1),
157 NewConfFile
= (1<<2),NewFile
= (1<<3),
158 Unpacked
= (1<<4),Replaced
= (1<<5)};
161 struct pkgFLCache::Directory
163 map_ptrloc Left
; // Directory
164 map_ptrloc Right
; // Directory
165 map_ptrloc Name
; // String
168 struct pkgFLCache::Package
170 map_ptrloc Left
; // Package
171 map_ptrloc Right
; // Package
172 map_ptrloc Name
; // String
173 map_ptrloc Files
; // Node
176 struct pkgFLCache::Diversion
178 map_ptrloc OwnerPkg
; // Package
179 map_ptrloc DivertFrom
; // Node
180 map_ptrloc DivertTo
; // String
182 map_ptrloc Next
; // Diversion
185 enum Flags
{Touched
= (1<<0)};
188 struct pkgFLCache::ConfFile
190 map_ptrloc OwnerPkg
; // Package
191 unsigned char MD5
[16];
194 class pkgFLCache::PkgIterator
201 inline bool end() const {return Owner
== 0 || Pkg
== Owner
->PkgP
?true:false;}
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
;};
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;
214 PkgIterator() : Pkg(0), Owner(0) {};
215 PkgIterator(pkgFLCache
&Owner
,Package
*Trg
) : Pkg(Trg
), Owner(&Owner
) {};
218 class pkgFLCache::DirIterator
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
;};
232 inline const char *Name() const {return Dir
->Name
== 0?0:Owner
->StrP
+ Dir
->Name
;};
234 DirIterator() : Dir(0), Owner(0) {};
235 DirIterator(pkgFLCache
&Owner
,Directory
*Trg
) : Dir(Trg
), Owner(&Owner
) {};
238 class pkgFLCache::DiverIterator
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
;};
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
;};
257 inline PkgIterator
OwnerPkg() const {return PkgIterator(*Owner
,Owner
->PkgP
+ Diver
->OwnerPkg
);};
258 inline NodeIterator
DivertFrom() const;
259 inline NodeIterator
DivertTo() const;
261 DiverIterator() : Diver(0), Owner(0) {};
262 DiverIterator(pkgFLCache
&Owner
,Diversion
*Trg
) : Diver(Trg
), Owner(&Owner
) {};
265 class pkgFLCache::NodeIterator
268 enum {NdePkg
, NdeHash
} Type
;
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
;};
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;
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
) {};
298 /* Inlines with forward references that cannot be included directly in their
299 respsective classes */
300 inline pkgFLCache::NodeIterator
pkgFLCache::DiverIterator::DivertFrom() const
301 {return NodeIterator(*Owner
,Owner
->NodeP
+ Diver
->DivertFrom
);};
302 inline pkgFLCache::NodeIterator
pkgFLCache::DiverIterator::DivertTo() const
303 {return NodeIterator(*Owner
,Owner
->NodeP
+ Diver
->DivertTo
);};
305 inline pkgFLCache::NodeIterator
pkgFLCache::PkgIterator::Files() const
306 {return NodeIterator(*Owner
,Owner
->NodeP
+ Pkg
->Files
,Pkg
);};
308 inline pkgFLCache::DiverIterator
pkgFLCache::DiverBegin()
309 {return DiverIterator(*this,DiverP
+ HeaderP
->Diversions
);};
311 inline pkgFLCache::PkgIterator
pkgFLCache::GetPkg(const char *Name
,bool Insert
)
312 {return GetPkg(Name
,Name
+strlen(Name
),Insert
);};