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
);};