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
33 #include <apt-pkg/mmap.h>
53 map_ptrloc LastTreeLookup
;
54 unsigned long LastLookupSize
;
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,
63 // Pointers to the arrays of items
77 Header
&Head() {return *HeaderP
;};
78 void PrintTree(map_ptrloc Base
,unsigned long Size
);
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
,
86 bool Insert
,bool Divert
);
87 Node
*HashNode(NodeIterator
const &N
);
88 void DropNode(map_ptrloc Node
);
90 inline DiverIterator
DiverBegin();
93 void BeginDiverLoad();
94 void FinishDiverLoad();
95 bool AddDiversion(PkgIterator
const &Owner
,const char *From
,
97 bool AddConfFile(const char *Name
,const char *NameEnd
,
98 PkgIterator
const &Owner
,const unsigned char *Sum
);
100 pkgFLCache(DynamicMMap
&Map
);
104 struct pkgFLCache::Header
106 // Signature information
107 unsigned long Signature
;
112 // Size of structure values
117 unsigned DiversionSz
;
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
;
133 map_ptrloc Diversions
;
135 /* Allocation pools, there should be one of these for each structure
136 excluding the header */
137 DynamicMMap::Pool Pools
[5];
139 bool CheckSizes(Header
&Against
) const;
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
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
154 enum Flags
{Diversion
= (1<<0),ConfFile
= (1<<1),
155 NewConfFile
= (1<<2),NewFile
= (1<<3),
156 Unpacked
= (1<<4),Replaced
= (1<<5)};
159 struct pkgFLCache::Directory
161 map_ptrloc Left
; // Directory
162 map_ptrloc Right
; // Directory
163 map_ptrloc Name
; // String
166 struct pkgFLCache::Package
168 map_ptrloc Left
; // Package
169 map_ptrloc Right
; // Package
170 map_ptrloc Name
; // String
171 map_ptrloc Files
; // Node
174 struct pkgFLCache::Diversion
176 map_ptrloc OwnerPkg
; // Package
177 map_ptrloc DivertFrom
; // Node
178 map_ptrloc DivertTo
; // String
180 map_ptrloc Next
; // Diversion
183 enum Flags
{Touched
= (1<<0)};
186 struct pkgFLCache::ConfFile
188 map_ptrloc OwnerPkg
; // Package
189 unsigned char MD5
[16];
192 class pkgFLCache::PkgIterator
199 inline bool end() const {return Owner
== 0 || Pkg
== Owner
->PkgP
?true:false;}
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
;};
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;
212 PkgIterator() : Pkg(0), Owner(0) {};
213 PkgIterator(pkgFLCache
&Owner
,Package
*Trg
) : Pkg(Trg
), Owner(&Owner
) {};
216 class pkgFLCache::DirIterator
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
;};
230 inline const char *Name() const {return Dir
->Name
== 0?0:Owner
->StrP
+ Dir
->Name
;};
232 DirIterator() : Dir(0), Owner(0) {};
233 DirIterator(pkgFLCache
&Owner
,Directory
*Trg
) : Dir(Trg
), Owner(&Owner
) {};
236 class pkgFLCache::DiverIterator
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
;};
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
;};
255 inline PkgIterator
OwnerPkg() const {return PkgIterator(*Owner
,Owner
->PkgP
+ Diver
->OwnerPkg
);};
256 inline NodeIterator
DivertFrom() const;
257 inline NodeIterator
DivertTo() const;
259 DiverIterator() : Diver(0), Owner(0) {};
260 DiverIterator(pkgFLCache
&Owner
,Diversion
*Trg
) : Diver(Trg
), Owner(&Owner
) {};
263 class pkgFLCache::NodeIterator
266 enum {NdePkg
, NdeHash
} Type
;
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
;};
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;
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
) {};
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
);};
303 inline pkgFLCache::NodeIterator
pkgFLCache::PkgIterator::Files() const
304 {return NodeIterator(*Owner
,Owner
->NodeP
+ Pkg
->Files
,Pkg
);};
306 inline pkgFLCache::DiverIterator
pkgFLCache::DiverBegin()
307 {return DiverIterator(*this,DiverP
+ HeaderP
->Diversions
);};
309 inline pkgFLCache::PkgIterator
pkgFLCache::GetPkg(const char *Name
,bool Insert
)
310 {return GetPkg(Name
,Name
+strlen(Name
),Insert
);};