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
31 #include <apt-pkg/mmap.h>
52 std::string CacheFile
;
54 map_ptrloc LastTreeLookup
;
55 unsigned long LastLookupSize
;
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,
64 // Pointers to the arrays of items
78 Header
&Head() {return *HeaderP
;};
79 void PrintTree(map_ptrloc Base
,unsigned long Size
);
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
,
87 bool Insert
,bool Divert
);
88 Node
*HashNode(NodeIterator
const &N
);
89 void DropNode(map_ptrloc Node
);
91 inline DiverIterator
DiverBegin();
94 void BeginDiverLoad();
95 void FinishDiverLoad();
96 bool AddDiversion(PkgIterator
const &Owner
,const char *From
,
98 bool AddConfFile(const char *Name
,const char *NameEnd
,
99 PkgIterator
const &Owner
,const unsigned char *Sum
);
101 pkgFLCache(DynamicMMap
&Map
);
105 struct pkgFLCache::Header
107 // Signature information
108 unsigned long Signature
;
113 // Size of structure values
118 unsigned DiversionSz
;
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
;
134 map_ptrloc Diversions
;
136 /* Allocation pools, there should be one of these for each structure
137 excluding the header */
138 DynamicMMap::Pool Pools
[5];
140 bool CheckSizes(Header
&Against
) const;
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
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
155 enum Flags
{Diversion
= (1<<0),ConfFile
= (1<<1),
156 NewConfFile
= (1<<2),NewFile
= (1<<3),
157 Unpacked
= (1<<4),Replaced
= (1<<5)};
160 struct pkgFLCache::Directory
162 map_ptrloc Left
; // Directory
163 map_ptrloc Right
; // Directory
164 map_ptrloc Name
; // String
167 struct pkgFLCache::Package
169 map_ptrloc Left
; // Package
170 map_ptrloc Right
; // Package
171 map_ptrloc Name
; // String
172 map_ptrloc Files
; // Node
175 struct pkgFLCache::Diversion
177 map_ptrloc OwnerPkg
; // Package
178 map_ptrloc DivertFrom
; // Node
179 map_ptrloc DivertTo
; // String
181 map_ptrloc Next
; // Diversion
184 enum Flags
{Touched
= (1<<0)};
187 struct pkgFLCache::ConfFile
189 map_ptrloc OwnerPkg
; // Package
190 unsigned char MD5
[16];
193 class pkgFLCache::PkgIterator
200 inline bool end() const {return Owner
== 0 || Pkg
== Owner
->PkgP
?true:false;}
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
;}
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;
213 PkgIterator() : Pkg(0), Owner(0) {}
214 PkgIterator(pkgFLCache
&Owner
,Package
*Trg
) : Pkg(Trg
), Owner(&Owner
) {}
217 class pkgFLCache::DirIterator
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
;}
231 inline const char *Name() const {return Dir
->Name
== 0?0:Owner
->StrP
+ Dir
->Name
;}
233 DirIterator() : Dir(0), Owner(0) {}
234 DirIterator(pkgFLCache
&Owner
,Directory
*Trg
) : Dir(Trg
), Owner(&Owner
) {}
237 class pkgFLCache::DiverIterator
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
;}
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
;}
256 inline PkgIterator
OwnerPkg() const {return PkgIterator(*Owner
,Owner
->PkgP
+ Diver
->OwnerPkg
);}
257 inline NodeIterator
DivertFrom() const;
258 inline NodeIterator
DivertTo() const;
260 DiverIterator() : Diver(0), Owner(0) {};
261 DiverIterator(pkgFLCache
&Owner
,Diversion
*Trg
) : Diver(Trg
), Owner(&Owner
) {}
264 class pkgFLCache::NodeIterator
267 enum {NdePkg
, NdeHash
} Type
;
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
;}
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;
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
) {}
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
);}
304 inline pkgFLCache::NodeIterator
pkgFLCache::PkgIterator::Files() const
305 {return NodeIterator(*Owner
,Owner
->NodeP
+ Pkg
->Files
,Pkg
);}
307 inline pkgFLCache::DiverIterator
pkgFLCache::DiverBegin()
308 {return DiverIterator(*this,DiverP
+ HeaderP
->Diversions
);}
310 inline pkgFLCache::PkgIterator
pkgFLCache::GetPkg(const char *Name
,bool Insert
)
311 {return GetPkg(Name
,Name
+strlen(Name
),Insert
);}