]>
git.saurik.com Git - apt.git/blob - apt-pkg/pkgcachegen.cc
581df11f482788d59fb7fa9bc83f529e3c621fcc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: pkgcachegen.cc,v 1.51 2002/04/26 05:35:57 jgg Exp $
4 /* ######################################################################
6 Package Cache Generator - Generator for the cache structure.
8 This builds the cache structure from the abstract package list parser.
10 ##################################################################### */
12 // Include Files /*{{{*/
14 #pragma implementation "apt-pkg/pkgcachegen.h"
17 #define APT_COMPATIBILITY 986
19 #include <apt-pkg/pkgcachegen.h>
20 #include <apt-pkg/error.h>
21 #include <apt-pkg/version.h>
22 #include <apt-pkg/progress.h>
23 #include <apt-pkg/sourcelist.h>
24 #include <apt-pkg/configuration.h>
25 #include <apt-pkg/strutl.h>
26 #include <apt-pkg/sptr.h>
27 #include <apt-pkg/pkgsystem.h>
39 typedef vector
<pkgIndexFile
*>::iterator FileIterator
;
41 // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/
42 // ---------------------------------------------------------------------
43 /* We set the diry flag and make sure that is written to the disk */
44 pkgCacheGenerator::pkgCacheGenerator(DynamicMMap
*pMap
,OpProgress
*Prog
) :
45 Map(*pMap
), Cache(pMap
,false), Progress(Prog
)
48 memset(UniqHash
,0,sizeof(UniqHash
));
50 if (_error
->PendingError() == true)
55 // Setup the map interface..
56 Cache
.HeaderP
= (pkgCache::Header
*)Map
.Data();
57 Map
.RawAllocate(sizeof(pkgCache::Header
));
58 Map
.UsePools(*Cache
.HeaderP
->Pools
,sizeof(Cache
.HeaderP
->Pools
)/sizeof(Cache
.HeaderP
->Pools
[0]));
61 *Cache
.HeaderP
= pkgCache::Header();
62 Cache
.HeaderP
->VerSysName
= Map
.WriteString(_system
->VS
->Label
);
63 Cache
.HeaderP
->Architecture
= Map
.WriteString(_config
->Find("APT::Architecture"));
68 // Map directly from the existing file
70 Map
.UsePools(*Cache
.HeaderP
->Pools
,sizeof(Cache
.HeaderP
->Pools
)/sizeof(Cache
.HeaderP
->Pools
[0]));
71 if (Cache
.VS
!= _system
->VS
)
73 _error
->Error(_("Cache has an incompatible versioning system"));
78 Cache
.HeaderP
->Dirty
= true;
79 Map
.Sync(0,sizeof(pkgCache::Header
));
82 // CacheGenerator::~pkgCacheGenerator - Destructor /*{{{*/
83 // ---------------------------------------------------------------------
84 /* We sync the data then unset the dirty flag in two steps so as to
85 advoid a problem during a crash */
86 pkgCacheGenerator::~pkgCacheGenerator()
88 if (_error
->PendingError() == true)
90 if (Map
.Sync() == false)
93 Cache
.HeaderP
->Dirty
= false;
94 Map
.Sync(0,sizeof(pkgCache::Header
));
97 // CacheGenerator::MergeList - Merge the package list /*{{{*/
98 // ---------------------------------------------------------------------
99 /* This provides the generation of the entries in the cache. Each loop
100 goes through a single package record from the underlying parse engine. */
101 bool pkgCacheGenerator::MergeList(ListParser
&List
,
102 pkgCache::VerIterator
*OutVer
)
106 unsigned int Counter
= 0;
107 while (List
.Step() == true)
109 // Get a pointer to the package structure
110 string PackageName
= List
.Package();
111 if (PackageName
.empty() == true)
114 pkgCache::PkgIterator Pkg
;
115 if (NewPackage(Pkg
,PackageName
) == false)
116 return _error
->Error(_("Error occured while processing %s (NewPackage)"),PackageName
.c_str());
118 if (Counter
% 100 == 0 && Progress
!= 0)
119 Progress
->Progress(List
.Offset());
121 /* Get a pointer to the version structure. We know the list is sorted
122 so we use that fact in the search. Insertion of new versions is
123 done with correct sorting */
124 string Version
= List
.Version();
125 if (Version
.empty() == true)
127 if (List
.UsePackage(Pkg
,pkgCache::VerIterator(Cache
)) == false)
128 return _error
->Error(_("Error occured while processing %s (UsePackage1)"),
129 PackageName
.c_str());
133 pkgCache::VerIterator Ver
= Pkg
.VersionList();
134 map_ptrloc
*Last
= &Pkg
->VersionList
;
136 for (; Ver
.end() == false; Last
= &Ver
->NextVer
, Ver
++)
138 Res
= Cache
.VS
->CmpVersion(Version
,Ver
.VerStr());
143 /* We already have a version for this item, record that we
145 unsigned long Hash
= List
.VersionHash();
146 if (Res
== 0 && Ver
->Hash
== Hash
)
148 if (List
.UsePackage(Pkg
,Ver
) == false)
149 return _error
->Error(_("Error occured while processing %s (UsePackage2)"),
150 PackageName
.c_str());
152 if (NewFileVer(Ver
,List
) == false)
153 return _error
->Error(_("Error occured while processing %s (NewFileVer1)"),
154 PackageName
.c_str());
156 // Read only a single record and return
166 // Skip to the end of the same version set.
169 for (; Ver
.end() == false; Last
= &Ver
->NextVer
, Ver
++)
171 Res
= Cache
.VS
->CmpVersion(Version
,Ver
.VerStr());
178 *Last
= NewVersion(Ver
,Version
,*Last
);
179 Ver
->ParentPkg
= Pkg
.Index();
181 if (List
.NewVersion(Ver
) == false)
182 return _error
->Error(_("Error occured while processing %s (NewVersion1)"),
183 PackageName
.c_str());
185 if (List
.UsePackage(Pkg
,Ver
) == false)
186 return _error
->Error(_("Error occured while processing %s (UsePackage3)"),
187 PackageName
.c_str());
189 if (NewFileVer(Ver
,List
) == false)
190 return _error
->Error(_("Error occured while processing %s (NewVersion2)"),
191 PackageName
.c_str());
193 // Read only a single record and return
201 if (Cache
.HeaderP
->PackageCount
>= (1ULL<<sizeof(Cache
.PkgP
->ID
)*8)-1)
202 return _error
->Error(_("Wow, you exceeded the number of package "
203 "names this APT is capable of."));
204 if (Cache
.HeaderP
->VersionCount
>= (1ULL<<(sizeof(Cache
.VerP
->ID
)*8))-1)
205 return _error
->Error(_("Wow, you exceeded the number of versions "
206 "this APT is capable of."));
207 if (Cache
.HeaderP
->DependsCount
>= (1ULL<<(sizeof(Cache
.DepP
->ID
)*8))-1ULL)
208 return _error
->Error(_("Wow, you exceeded the number of dependencies "
209 "this APT is capable of."));
213 // CacheGenerator::NewPackage - Add a new package /*{{{*/
214 // ---------------------------------------------------------------------
215 /* This creates a new package structure and adds it to the hash table */
216 bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator
&Pkg
,string Name
)
218 Pkg
= Cache
.FindPkg(Name
);
219 if (Pkg
.end() == false)
223 unsigned long Package
= Map
.Allocate(sizeof(pkgCache::Package
));
227 Pkg
= pkgCache::PkgIterator(Cache
,Cache
.PkgP
+ Package
);
229 // Insert it into the hash table
230 unsigned long Hash
= Cache
.Hash(Name
);
231 Pkg
->NextPackage
= Cache
.HeaderP
->HashTable
[Hash
];
232 Cache
.HeaderP
->HashTable
[Hash
] = Package
;
234 // Set the name and the ID
235 Pkg
->Name
= Map
.WriteString(Name
);
238 Pkg
->ID
= Cache
.HeaderP
->PackageCount
++;
243 // CacheGenerator::NewFileVer - Create a new File<->Version association /*{{{*/
244 // ---------------------------------------------------------------------
246 bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator
&Ver
,
249 if (CurrentFile
== 0)
253 unsigned long VerFile
= Map
.Allocate(sizeof(pkgCache::VerFile
));
257 pkgCache::VerFileIterator
VF(Cache
,Cache
.VerFileP
+ VerFile
);
258 VF
->File
= CurrentFile
- Cache
.PkgFileP
;
260 // Link it to the end of the list
261 map_ptrloc
*Last
= &Ver
->FileList
;
262 for (pkgCache::VerFileIterator V
= Ver
.FileList(); V
.end() == false; V
++)
264 VF
->NextFile
= *Last
;
267 VF
->Offset
= List
.Offset();
268 VF
->Size
= List
.Size();
269 if (Cache
.HeaderP
->MaxVerFileSize
< VF
->Size
)
270 Cache
.HeaderP
->MaxVerFileSize
= VF
->Size
;
271 Cache
.HeaderP
->VerFileCount
++;
276 // CacheGenerator::NewVersion - Create a new Version /*{{{*/
277 // ---------------------------------------------------------------------
278 /* This puts a version structure in the linked list */
279 unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator
&Ver
,
284 unsigned long Version
= Map
.Allocate(sizeof(pkgCache::Version
));
289 Ver
= pkgCache::VerIterator(Cache
,Cache
.VerP
+ Version
);
291 Ver
->ID
= Cache
.HeaderP
->VersionCount
++;
292 Ver
->VerStr
= Map
.WriteString(VerStr
);
293 if (Ver
->VerStr
== 0)
299 // ListParser::NewDepends - Create a dependency element /*{{{*/
300 // ---------------------------------------------------------------------
301 /* This creates a dependency element in the tree. It is linked to the
302 version and to the package that it is pointing to. */
303 bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver
,
309 pkgCache
&Cache
= Owner
->Cache
;
312 unsigned long Dependency
= Owner
->Map
.Allocate(sizeof(pkgCache::Dependency
));
317 pkgCache::DepIterator
Dep(Cache
,Cache
.DepP
+ Dependency
);
318 Dep
->ParentVer
= Ver
.Index();
321 Dep
->ID
= Cache
.HeaderP
->DependsCount
++;
323 // Locate the target package
324 pkgCache::PkgIterator Pkg
;
325 if (Owner
->NewPackage(Pkg
,PackageName
) == false)
328 // Probe the reverse dependency list for a version string that matches
329 if (Version
.empty() == false)
331 /* for (pkgCache::DepIterator I = Pkg.RevDependsList(); I.end() == false; I++)
332 if (I->Version != 0 && I.TargetVer() == Version)
333 Dep->Version = I->Version;*/
334 if (Dep
->Version
== 0)
335 if ((Dep
->Version
= WriteString(Version
)) == 0)
339 // Link it to the package
340 Dep
->Package
= Pkg
.Index();
341 Dep
->NextRevDepends
= Pkg
->RevDepends
;
342 Pkg
->RevDepends
= Dep
.Index();
344 /* Link it to the version (at the end of the list)
345 Caching the old end point speeds up generation substantially */
346 if (OldDepVer
!= Ver
)
348 OldDepLast
= &Ver
->DependsList
;
349 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; D
++)
350 OldDepLast
= &D
->NextDepends
;
354 Dep
->NextDepends
= *OldDepLast
;
355 *OldDepLast
= Dep
.Index();
356 OldDepLast
= &Dep
->NextDepends
;
361 // ListParser::NewProvides - Create a Provides element /*{{{*/
362 // ---------------------------------------------------------------------
364 bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver
,
368 pkgCache
&Cache
= Owner
->Cache
;
370 // We do not add self referencing provides
371 if (Ver
.ParentPkg().Name() == PackageName
)
375 unsigned long Provides
= Owner
->Map
.Allocate(sizeof(pkgCache::Provides
));
378 Cache
.HeaderP
->ProvidesCount
++;
381 pkgCache::PrvIterator
Prv(Cache
,Cache
.ProvideP
+ Provides
,Cache
.PkgP
);
382 Prv
->Version
= Ver
.Index();
383 Prv
->NextPkgProv
= Ver
->ProvidesList
;
384 Ver
->ProvidesList
= Prv
.Index();
385 if (Version
.empty() == false && (Prv
->ProvideVersion
= WriteString(Version
)) == 0)
388 // Locate the target package
389 pkgCache::PkgIterator Pkg
;
390 if (Owner
->NewPackage(Pkg
,PackageName
) == false)
393 // Link it to the package
394 Prv
->ParentPkg
= Pkg
.Index();
395 Prv
->NextProvides
= Pkg
->ProvidesList
;
396 Pkg
->ProvidesList
= Prv
.Index();
401 // CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/
402 // ---------------------------------------------------------------------
403 /* This is used to select which file is to be associated with all newly
404 added versions. The caller is responsible for setting the IMS fields. */
405 bool pkgCacheGenerator::SelectFile(string File
,string Site
,
406 const pkgIndexFile
&Index
,
409 // Get some space for the structure
410 CurrentFile
= Cache
.PkgFileP
+ Map
.Allocate(sizeof(*CurrentFile
));
411 if (CurrentFile
== Cache
.PkgFileP
)
415 CurrentFile
->FileName
= Map
.WriteString(File
);
416 CurrentFile
->Site
= WriteUniqString(Site
);
417 CurrentFile
->NextFile
= Cache
.HeaderP
->FileList
;
418 CurrentFile
->Flags
= Flags
;
419 CurrentFile
->ID
= Cache
.HeaderP
->PackageFileCount
;
420 CurrentFile
->IndexType
= WriteUniqString(Index
.GetType()->Label
);
422 Cache
.HeaderP
->FileList
= CurrentFile
- Cache
.PkgFileP
;
423 Cache
.HeaderP
->PackageFileCount
++;
425 if (CurrentFile
->FileName
== 0)
429 Progress
->SubProgress(Index
.Size());
433 // CacheGenerator::WriteUniqueString - Insert a unique string /*{{{*/
434 // ---------------------------------------------------------------------
435 /* This is used to create handles to strings. Given the same text it
436 always returns the same number */
437 unsigned long pkgCacheGenerator::WriteUniqString(const char *S
,
440 /* We use a very small transient hash table here, this speeds up generation
441 by a fair amount on slower machines */
442 pkgCache::StringItem
*&Bucket
= UniqHash
[(S
[0]*5 + S
[1]) % _count(UniqHash
)];
444 stringcmp(S
,S
+Size
,Cache
.StrP
+ Bucket
->String
) == 0)
445 return Bucket
->String
;
447 // Search for an insertion point
448 pkgCache::StringItem
*I
= Cache
.StringItemP
+ Cache
.HeaderP
->StringList
;
450 map_ptrloc
*Last
= &Cache
.HeaderP
->StringList
;
451 for (; I
!= Cache
.StringItemP
; Last
= &I
->NextItem
,
452 I
= Cache
.StringItemP
+ I
->NextItem
)
454 Res
= stringcmp(S
,S
+Size
,Cache
.StrP
+ I
->String
);
467 unsigned long Item
= Map
.Allocate(sizeof(pkgCache::StringItem
));
471 // Fill in the structure
472 pkgCache::StringItem
*ItemP
= Cache
.StringItemP
+ Item
;
473 ItemP
->NextItem
= I
- Cache
.StringItemP
;
475 ItemP
->String
= Map
.WriteString(S
,Size
);
476 if (ItemP
->String
== 0)
480 return ItemP
->String
;
484 // CheckValidity - Check that a cache is up-to-date /*{{{*/
485 // ---------------------------------------------------------------------
486 /* This just verifies that each file in the list of index files exists,
487 has matching attributes with the cache and the cache does not have
489 static bool CheckValidity(string CacheFile
, FileIterator Start
,
490 FileIterator End
,MMap
**OutMap
= 0)
492 // No file, certainly invalid
493 if (CacheFile
.empty() == true || FileExists(CacheFile
) == false)
497 FileFd
CacheF(CacheFile
,FileFd::ReadOnly
);
498 SPtr
<MMap
> Map
= new MMap(CacheF
,MMap::Public
| MMap::ReadOnly
);
500 if (_error
->PendingError() == true || Map
->Size() == 0)
506 /* Now we check every index file, see if it is in the cache,
507 verify the IMS data and check that it is on the disk too.. */
508 SPtrArray
<bool> Visited
= new bool[Cache
.HeaderP
->PackageFileCount
];
509 memset(Visited
,0,sizeof(*Visited
)*Cache
.HeaderP
->PackageFileCount
);
510 for (; Start
!= End
; Start
++)
512 if ((*Start
)->HasPackages() == false)
515 if ((*Start
)->Exists() == false)
517 _error
->WarningE("stat",_("Couldn't stat source package list %s"),
518 (*Start
)->Describe().c_str());
522 // FindInCache is also expected to do an IMS check.
523 pkgCache::PkgFileIterator File
= (*Start
)->FindInCache(Cache
);
524 if (File
.end() == true)
527 Visited
[File
->ID
] = true;
530 for (unsigned I
= 0; I
!= Cache
.HeaderP
->PackageFileCount
; I
++)
531 if (Visited
[I
] == false)
534 if (_error
->PendingError() == true)
541 *OutMap
= Map
.UnGuard();
545 // ComputeSize - Compute the total size of a bunch of files /*{{{*/
546 // ---------------------------------------------------------------------
547 /* Size is kind of an abstract notion that is only used for the progress
549 static unsigned long ComputeSize(FileIterator Start
,FileIterator End
)
551 unsigned long TotalSize
= 0;
552 for (; Start
!= End
; Start
++)
554 if ((*Start
)->HasPackages() == false)
556 TotalSize
+= (*Start
)->Size();
561 // BuildCache - Merge the list of index files into the cache /*{{{*/
562 // ---------------------------------------------------------------------
564 static bool BuildCache(pkgCacheGenerator
&Gen
,
565 OpProgress
&Progress
,
566 unsigned long &CurrentSize
,unsigned long TotalSize
,
567 FileIterator Start
, FileIterator End
)
569 for (; Start
!= End
; Start
++)
571 if ((*Start
)->HasPackages() == false)
574 if ((*Start
)->Exists() == false)
577 if ((*Start
)->FindInCache(Gen
.GetCache()).end() == false)
579 _error
->Warning("Duplicate sources.list entry %s",
580 (*Start
)->Describe().c_str());
584 unsigned long Size
= (*Start
)->Size();
585 Progress
.OverallProgress(CurrentSize
,TotalSize
,Size
,_("Reading Package Lists"));
588 if ((*Start
)->Merge(Gen
,Progress
) == false)
595 // MakeStatusCache - Construct the status cache /*{{{*/
596 // ---------------------------------------------------------------------
597 /* This makes sure that the status cache (the cache that has all
598 index files from the sources list and all local ones) is ready
599 to be mmaped. If OutMap is not zero then a MMap object representing
600 the cache will be stored there. This is pretty much mandetory if you
601 are using AllowMem. AllowMem lets the function be run as non-root
602 where it builds the cache 'fast' into a memory buffer. */
603 bool pkgMakeStatusCache(pkgSourceList
&List
,OpProgress
&Progress
,
604 MMap
**OutMap
,bool AllowMem
)
606 unsigned long MapSize
= _config
->FindI("APT::Cache-Limit",6*1024*1024);
608 vector
<pkgIndexFile
*> Files(List
.begin(),List
.end());
609 unsigned long EndOfSource
= Files
.size();
610 if (_system
->AddStatusFiles(Files
) == false)
613 // Decide if we can write to the files..
614 string CacheFile
= _config
->FindFile("Dir::Cache::pkgcache");
615 string SrcCacheFile
= _config
->FindFile("Dir::Cache::srcpkgcache");
617 // Decide if we can write to the cache
618 bool Writeable
= false;
619 if (CacheFile
.empty() == false)
620 Writeable
= access(flNotFile(CacheFile
).c_str(),W_OK
) == 0;
622 if (SrcCacheFile
.empty() == false)
623 Writeable
= access(flNotFile(SrcCacheFile
).c_str(),W_OK
) == 0;
625 if (Writeable
== false && AllowMem
== false && CacheFile
.empty() == false)
626 return _error
->Error(_("Unable to write to %s"),flNotFile(CacheFile
).c_str());
628 Progress
.OverallProgress(0,1,1,_("Reading Package Lists"));
631 if (CheckValidity(CacheFile
,Files
.begin(),Files
.end(),OutMap
) == true)
633 Progress
.OverallProgress(1,1,1,_("Reading Package Lists"));
637 /* At this point we know we need to reconstruct the package cache,
640 SPtr
<DynamicMMap
> Map
;
641 if (Writeable
== true && CacheFile
.empty() == false)
643 unlink(CacheFile
.c_str());
644 CacheF
= new FileFd(CacheFile
,FileFd::WriteEmpty
);
645 fchmod(CacheF
->Fd(),0644);
646 Map
= new DynamicMMap(*CacheF
,MMap::Public
,MapSize
);
647 if (_error
->PendingError() == true)
652 // Just build it in memory..
653 Map
= new DynamicMMap(MMap::Public
,MapSize
);
656 // Lets try the source cache.
657 unsigned long CurrentSize
= 0;
658 unsigned long TotalSize
= 0;
659 if (CheckValidity(SrcCacheFile
,Files
.begin(),
660 Files
.begin()+EndOfSource
) == true)
662 // Preload the map with the source cache
663 FileFd
SCacheF(SrcCacheFile
,FileFd::ReadOnly
);
664 if (SCacheF
.Read((unsigned char *)Map
->Data() + Map
->RawAllocate(SCacheF
.Size()),
665 SCacheF
.Size()) == false)
668 TotalSize
= ComputeSize(Files
.begin()+EndOfSource
,Files
.end());
670 // Build the status cache
671 pkgCacheGenerator
Gen(Map
.Get(),&Progress
);
672 if (_error
->PendingError() == true)
674 if (BuildCache(Gen
,Progress
,CurrentSize
,TotalSize
,
675 Files
.begin()+EndOfSource
,Files
.end()) == false)
680 TotalSize
= ComputeSize(Files
.begin(),Files
.end());
682 // Build the source cache
683 pkgCacheGenerator
Gen(Map
.Get(),&Progress
);
684 if (_error
->PendingError() == true)
686 if (BuildCache(Gen
,Progress
,CurrentSize
,TotalSize
,
687 Files
.begin(),Files
.begin()+EndOfSource
) == false)
691 if (Writeable
== true && SrcCacheFile
.empty() == false)
693 FileFd
SCacheF(SrcCacheFile
,FileFd::WriteEmpty
);
694 if (_error
->PendingError() == true)
697 fchmod(SCacheF
.Fd(),0644);
699 // Write out the main data
700 if (SCacheF
.Write(Map
->Data(),Map
->Size()) == false)
701 return _error
->Error(_("IO Error saving source cache"));
704 // Write out the proper header
705 Gen
.GetCache().HeaderP
->Dirty
= false;
706 if (SCacheF
.Seek(0) == false ||
707 SCacheF
.Write(Map
->Data(),sizeof(*Gen
.GetCache().HeaderP
)) == false)
708 return _error
->Error(_("IO Error saving source cache"));
709 Gen
.GetCache().HeaderP
->Dirty
= true;
713 // Build the status cache
714 if (BuildCache(Gen
,Progress
,CurrentSize
,TotalSize
,
715 Files
.begin()+EndOfSource
,Files
.end()) == false)
719 if (_error
->PendingError() == true)
725 delete Map
.UnGuard();
726 *OutMap
= new MMap(*CacheF
,MMap::Public
| MMap::ReadOnly
);
730 *OutMap
= Map
.UnGuard();
737 // MakeOnlyStatusCache - Build a cache with just the status files /*{{{*/
738 // ---------------------------------------------------------------------
740 bool pkgMakeOnlyStatusCache(OpProgress
&Progress
,DynamicMMap
**OutMap
)
742 unsigned long MapSize
= _config
->FindI("APT::Cache-Limit",4*1024*1024);
743 vector
<pkgIndexFile
*> Files
;
744 unsigned long EndOfSource
= Files
.size();
745 if (_system
->AddStatusFiles(Files
) == false)
748 SPtr
<DynamicMMap
> Map
;
749 Map
= new DynamicMMap(MMap::Public
,MapSize
);
750 unsigned long CurrentSize
= 0;
751 unsigned long TotalSize
= 0;
753 TotalSize
= ComputeSize(Files
.begin()+EndOfSource
,Files
.end());
755 // Build the status cache
756 Progress
.OverallProgress(0,1,1,_("Reading Package Lists"));
757 pkgCacheGenerator
Gen(Map
.Get(),&Progress
);
758 if (_error
->PendingError() == true)
760 if (BuildCache(Gen
,Progress
,CurrentSize
,TotalSize
,
761 Files
.begin()+EndOfSource
,Files
.end()) == false)
764 if (_error
->PendingError() == true)
766 *OutMap
= Map
.UnGuard();