]>
git.saurik.com Git - apt.git/blob - apt-pkg/pkgcachegen.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: pkgcachegen.cc,v 1.50 2001/07/01 22:28:24 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)"),PackageName
.c_str());
132 pkgCache::VerIterator Ver
= Pkg
.VersionList();
133 map_ptrloc
*Last
= &Pkg
->VersionList
;
135 for (; Ver
.end() == false; Last
= &Ver
->NextVer
, Ver
++)
137 Res
= Cache
.VS
->CmpVersion(Version
,Ver
.VerStr());
142 /* We already have a version for this item, record that we
144 unsigned long Hash
= List
.VersionHash();
145 if (Res
== 0 && Ver
->Hash
== Hash
)
147 if (List
.UsePackage(Pkg
,Ver
) == false)
148 return _error
->Error(_("Error occured while processing %s (UsePackage2)"),PackageName
.c_str());
150 if (NewFileVer(Ver
,List
) == false)
151 return _error
->Error(_("Error occured while processing %s (NewFileVer1)"),PackageName
.c_str());
153 // Read only a single record and return
163 // Skip to the end of the same version set.
166 for (; Ver
.end() == false; Last
= &Ver
->NextVer
, Ver
++)
168 Res
= Cache
.VS
->CmpVersion(Version
,Ver
.VerStr());
175 *Last
= NewVersion(Ver
,Version
,*Last
);
176 Ver
->ParentPkg
= Pkg
.Index();
178 if (List
.NewVersion(Ver
) == false)
179 return _error
->Error(_("Error occured while processing %s (NewVersion1)"),PackageName
.c_str());
181 if (List
.UsePackage(Pkg
,Ver
) == false)
182 return _error
->Error(_("Error occured while processing %s (UsePackage3)"),PackageName
.c_str());
184 if (NewFileVer(Ver
,List
) == false)
185 return _error
->Error(_("Error occured while processing %s (NewVersion2)"),PackageName
.c_str());
187 // Read only a single record and return
195 if (Cache
.HeaderP
->PackageCount
>= (1ULL<<sizeof(Cache
.PkgP
->ID
)*8)-1)
196 return _error
->Error(_("Wow, you exceeded the number of package "
197 "names this APT is capable of."));
198 if (Cache
.HeaderP
->VersionCount
>= (1ULL<<(sizeof(Cache
.VerP
->ID
)*8))-1)
199 return _error
->Error(_("Wow, you exceeded the number of versions "
200 "this APT is capable of."));
201 if (Cache
.HeaderP
->DependsCount
>= (1ULL<<(sizeof(Cache
.DepP
->ID
)*8))-1ULL)
202 return _error
->Error(_("Wow, you exceeded the number of dependencies "
203 "this APT is capable of."));
207 // CacheGenerator::NewPackage - Add a new package /*{{{*/
208 // ---------------------------------------------------------------------
209 /* This creates a new package structure and adds it to the hash table */
210 bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator
&Pkg
,string Name
)
212 Pkg
= Cache
.FindPkg(Name
);
213 if (Pkg
.end() == false)
217 unsigned long Package
= Map
.Allocate(sizeof(pkgCache::Package
));
221 Pkg
= pkgCache::PkgIterator(Cache
,Cache
.PkgP
+ Package
);
223 // Insert it into the hash table
224 unsigned long Hash
= Cache
.Hash(Name
);
225 Pkg
->NextPackage
= Cache
.HeaderP
->HashTable
[Hash
];
226 Cache
.HeaderP
->HashTable
[Hash
] = Package
;
228 // Set the name and the ID
229 Pkg
->Name
= Map
.WriteString(Name
);
232 Pkg
->ID
= Cache
.HeaderP
->PackageCount
++;
237 // CacheGenerator::NewFileVer - Create a new File<->Version association /*{{{*/
238 // ---------------------------------------------------------------------
240 bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator
&Ver
,
243 if (CurrentFile
== 0)
247 unsigned long VerFile
= Map
.Allocate(sizeof(pkgCache::VerFile
));
251 pkgCache::VerFileIterator
VF(Cache
,Cache
.VerFileP
+ VerFile
);
252 VF
->File
= CurrentFile
- Cache
.PkgFileP
;
254 // Link it to the end of the list
255 map_ptrloc
*Last
= &Ver
->FileList
;
256 for (pkgCache::VerFileIterator V
= Ver
.FileList(); V
.end() == false; V
++)
258 VF
->NextFile
= *Last
;
261 VF
->Offset
= List
.Offset();
262 VF
->Size
= List
.Size();
263 if (Cache
.HeaderP
->MaxVerFileSize
< VF
->Size
)
264 Cache
.HeaderP
->MaxVerFileSize
= VF
->Size
;
265 Cache
.HeaderP
->VerFileCount
++;
270 // CacheGenerator::NewVersion - Create a new Version /*{{{*/
271 // ---------------------------------------------------------------------
272 /* This puts a version structure in the linked list */
273 unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator
&Ver
,
278 unsigned long Version
= Map
.Allocate(sizeof(pkgCache::Version
));
283 Ver
= pkgCache::VerIterator(Cache
,Cache
.VerP
+ Version
);
285 Ver
->ID
= Cache
.HeaderP
->VersionCount
++;
286 Ver
->VerStr
= Map
.WriteString(VerStr
);
287 if (Ver
->VerStr
== 0)
293 // ListParser::NewDepends - Create a dependency element /*{{{*/
294 // ---------------------------------------------------------------------
295 /* This creates a dependency element in the tree. It is linked to the
296 version and to the package that it is pointing to. */
297 bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver
,
303 pkgCache
&Cache
= Owner
->Cache
;
306 unsigned long Dependency
= Owner
->Map
.Allocate(sizeof(pkgCache::Dependency
));
311 pkgCache::DepIterator
Dep(Cache
,Cache
.DepP
+ Dependency
);
312 Dep
->ParentVer
= Ver
.Index();
315 Dep
->ID
= Cache
.HeaderP
->DependsCount
++;
317 // Locate the target package
318 pkgCache::PkgIterator Pkg
;
319 if (Owner
->NewPackage(Pkg
,PackageName
) == false)
322 // Probe the reverse dependency list for a version string that matches
323 if (Version
.empty() == false)
325 /* for (pkgCache::DepIterator I = Pkg.RevDependsList(); I.end() == false; I++)
326 if (I->Version != 0 && I.TargetVer() == Version)
327 Dep->Version = I->Version;*/
328 if (Dep
->Version
== 0)
329 if ((Dep
->Version
= WriteString(Version
)) == 0)
333 // Link it to the package
334 Dep
->Package
= Pkg
.Index();
335 Dep
->NextRevDepends
= Pkg
->RevDepends
;
336 Pkg
->RevDepends
= Dep
.Index();
338 /* Link it to the version (at the end of the list)
339 Caching the old end point speeds up generation substantially */
340 if (OldDepVer
!= Ver
)
342 OldDepLast
= &Ver
->DependsList
;
343 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; D
++)
344 OldDepLast
= &D
->NextDepends
;
348 Dep
->NextDepends
= *OldDepLast
;
349 *OldDepLast
= Dep
.Index();
350 OldDepLast
= &Dep
->NextDepends
;
355 // ListParser::NewProvides - Create a Provides element /*{{{*/
356 // ---------------------------------------------------------------------
358 bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver
,
362 pkgCache
&Cache
= Owner
->Cache
;
364 // We do not add self referencing provides
365 if (Ver
.ParentPkg().Name() == PackageName
)
369 unsigned long Provides
= Owner
->Map
.Allocate(sizeof(pkgCache::Provides
));
372 Cache
.HeaderP
->ProvidesCount
++;
375 pkgCache::PrvIterator
Prv(Cache
,Cache
.ProvideP
+ Provides
,Cache
.PkgP
);
376 Prv
->Version
= Ver
.Index();
377 Prv
->NextPkgProv
= Ver
->ProvidesList
;
378 Ver
->ProvidesList
= Prv
.Index();
379 if (Version
.empty() == false && (Prv
->ProvideVersion
= WriteString(Version
)) == 0)
382 // Locate the target package
383 pkgCache::PkgIterator Pkg
;
384 if (Owner
->NewPackage(Pkg
,PackageName
) == false)
387 // Link it to the package
388 Prv
->ParentPkg
= Pkg
.Index();
389 Prv
->NextProvides
= Pkg
->ProvidesList
;
390 Pkg
->ProvidesList
= Prv
.Index();
395 // CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/
396 // ---------------------------------------------------------------------
397 /* This is used to select which file is to be associated with all newly
398 added versions. The caller is responsible for setting the IMS fields. */
399 bool pkgCacheGenerator::SelectFile(string File
,string Site
,
400 const pkgIndexFile
&Index
,
403 // Get some space for the structure
404 CurrentFile
= Cache
.PkgFileP
+ Map
.Allocate(sizeof(*CurrentFile
));
405 if (CurrentFile
== Cache
.PkgFileP
)
409 CurrentFile
->FileName
= Map
.WriteString(File
);
410 CurrentFile
->Site
= WriteUniqString(Site
);
411 CurrentFile
->NextFile
= Cache
.HeaderP
->FileList
;
412 CurrentFile
->Flags
= Flags
;
413 CurrentFile
->ID
= Cache
.HeaderP
->PackageFileCount
;
414 CurrentFile
->IndexType
= WriteUniqString(Index
.GetType()->Label
);
416 Cache
.HeaderP
->FileList
= CurrentFile
- Cache
.PkgFileP
;
417 Cache
.HeaderP
->PackageFileCount
++;
419 if (CurrentFile
->FileName
== 0)
423 Progress
->SubProgress(Index
.Size());
427 // CacheGenerator::WriteUniqueString - Insert a unique string /*{{{*/
428 // ---------------------------------------------------------------------
429 /* This is used to create handles to strings. Given the same text it
430 always returns the same number */
431 unsigned long pkgCacheGenerator::WriteUniqString(const char *S
,
434 /* We use a very small transient hash table here, this speeds up generation
435 by a fair amount on slower machines */
436 pkgCache::StringItem
*&Bucket
= UniqHash
[(S
[0]*5 + S
[1]) % _count(UniqHash
)];
438 stringcmp(S
,S
+Size
,Cache
.StrP
+ Bucket
->String
) == 0)
439 return Bucket
->String
;
441 // Search for an insertion point
442 pkgCache::StringItem
*I
= Cache
.StringItemP
+ Cache
.HeaderP
->StringList
;
444 map_ptrloc
*Last
= &Cache
.HeaderP
->StringList
;
445 for (; I
!= Cache
.StringItemP
; Last
= &I
->NextItem
,
446 I
= Cache
.StringItemP
+ I
->NextItem
)
448 Res
= stringcmp(S
,S
+Size
,Cache
.StrP
+ I
->String
);
461 unsigned long Item
= Map
.Allocate(sizeof(pkgCache::StringItem
));
465 // Fill in the structure
466 pkgCache::StringItem
*ItemP
= Cache
.StringItemP
+ Item
;
467 ItemP
->NextItem
= I
- Cache
.StringItemP
;
469 ItemP
->String
= Map
.WriteString(S
,Size
);
470 if (ItemP
->String
== 0)
474 return ItemP
->String
;
478 // CheckValidity - Check that a cache is up-to-date /*{{{*/
479 // ---------------------------------------------------------------------
480 /* This just verifies that each file in the list of index files exists,
481 has matching attributes with the cache and the cache does not have
483 static bool CheckValidity(string CacheFile
, FileIterator Start
,
484 FileIterator End
,MMap
**OutMap
= 0)
486 // No file, certainly invalid
487 if (CacheFile
.empty() == true || FileExists(CacheFile
) == false)
491 FileFd
CacheF(CacheFile
,FileFd::ReadOnly
);
492 SPtr
<MMap
> Map
= new MMap(CacheF
,MMap::Public
| MMap::ReadOnly
);
494 if (_error
->PendingError() == true || Map
->Size() == 0)
500 /* Now we check every index file, see if it is in the cache,
501 verify the IMS data and check that it is on the disk too.. */
502 SPtrArray
<bool> Visited
= new bool[Cache
.HeaderP
->PackageFileCount
];
503 memset(Visited
,0,sizeof(*Visited
)*Cache
.HeaderP
->PackageFileCount
);
504 for (; Start
!= End
; Start
++)
506 if ((*Start
)->HasPackages() == false)
509 if ((*Start
)->Exists() == false)
511 _error
->WarningE("stat",_("Couldn't stat source package list %s"),
512 (*Start
)->Describe().c_str());
516 // FindInCache is also expected to do an IMS check.
517 pkgCache::PkgFileIterator File
= (*Start
)->FindInCache(Cache
);
518 if (File
.end() == true)
521 Visited
[File
->ID
] = true;
524 for (unsigned I
= 0; I
!= Cache
.HeaderP
->PackageFileCount
; I
++)
525 if (Visited
[I
] == false)
528 if (_error
->PendingError() == true)
535 *OutMap
= Map
.UnGuard();
539 // ComputeSize - Compute the total size of a bunch of files /*{{{*/
540 // ---------------------------------------------------------------------
541 /* Size is kind of an abstract notion that is only used for the progress
543 static unsigned long ComputeSize(FileIterator Start
,FileIterator End
)
545 unsigned long TotalSize
= 0;
546 for (; Start
!= End
; Start
++)
548 if ((*Start
)->HasPackages() == false)
550 TotalSize
+= (*Start
)->Size();
555 // BuildCache - Merge the list of index files into the cache /*{{{*/
556 // ---------------------------------------------------------------------
558 static bool BuildCache(pkgCacheGenerator
&Gen
,
559 OpProgress
&Progress
,
560 unsigned long &CurrentSize
,unsigned long TotalSize
,
561 FileIterator Start
, FileIterator End
)
563 for (; Start
!= End
; Start
++)
565 if ((*Start
)->HasPackages() == false)
568 if ((*Start
)->Exists() == false)
571 if ((*Start
)->FindInCache(Gen
.GetCache()).end() == false)
573 _error
->Warning("Duplicate sources.list entry %s",
574 (*Start
)->Describe().c_str());
578 unsigned long Size
= (*Start
)->Size();
579 Progress
.OverallProgress(CurrentSize
,TotalSize
,Size
,_("Reading Package Lists"));
582 if ((*Start
)->Merge(Gen
,Progress
) == false)
589 // MakeStatusCache - Construct the status cache /*{{{*/
590 // ---------------------------------------------------------------------
591 /* This makes sure that the status cache (the cache that has all
592 index files from the sources list and all local ones) is ready
593 to be mmaped. If OutMap is not zero then a MMap object representing
594 the cache will be stored there. This is pretty much mandetory if you
595 are using AllowMem. AllowMem lets the function be run as non-root
596 where it builds the cache 'fast' into a memory buffer. */
597 bool pkgMakeStatusCache(pkgSourceList
&List
,OpProgress
&Progress
,
598 MMap
**OutMap
,bool AllowMem
)
600 unsigned long MapSize
= _config
->FindI("APT::Cache-Limit",6*1024*1024);
602 vector
<pkgIndexFile
*> Files(List
.begin(),List
.end());
603 unsigned long EndOfSource
= Files
.size();
604 if (_system
->AddStatusFiles(Files
) == false)
607 // Decide if we can write to the files..
608 string CacheFile
= _config
->FindFile("Dir::Cache::pkgcache");
609 string SrcCacheFile
= _config
->FindFile("Dir::Cache::srcpkgcache");
611 // Decide if we can write to the cache
612 bool Writeable
= false;
613 if (CacheFile
.empty() == false)
614 Writeable
= access(flNotFile(CacheFile
).c_str(),W_OK
) == 0;
616 if (SrcCacheFile
.empty() == false)
617 Writeable
= access(flNotFile(SrcCacheFile
).c_str(),W_OK
) == 0;
619 if (Writeable
== false && AllowMem
== false && CacheFile
.empty() == false)
620 return _error
->Error(_("Unable to write to %s"),flNotFile(CacheFile
).c_str());
622 Progress
.OverallProgress(0,1,1,_("Reading Package Lists"));
625 if (CheckValidity(CacheFile
,Files
.begin(),Files
.end(),OutMap
) == true)
627 Progress
.OverallProgress(1,1,1,_("Reading Package Lists"));
631 /* At this point we know we need to reconstruct the package cache,
634 SPtr
<DynamicMMap
> Map
;
635 if (Writeable
== true && CacheFile
.empty() == false)
637 unlink(CacheFile
.c_str());
638 CacheF
= new FileFd(CacheFile
,FileFd::WriteEmpty
);
639 Map
= new DynamicMMap(*CacheF
,MMap::Public
,MapSize
);
640 if (_error
->PendingError() == true)
645 // Just build it in memory..
646 Map
= new DynamicMMap(MMap::Public
,MapSize
);
649 // Lets try the source cache.
650 unsigned long CurrentSize
= 0;
651 unsigned long TotalSize
= 0;
652 if (CheckValidity(SrcCacheFile
,Files
.begin(),
653 Files
.begin()+EndOfSource
) == true)
655 // Preload the map with the source cache
656 FileFd
SCacheF(SrcCacheFile
,FileFd::ReadOnly
);
657 if (SCacheF
.Read((unsigned char *)Map
->Data() + Map
->RawAllocate(SCacheF
.Size()),
658 SCacheF
.Size()) == false)
661 TotalSize
= ComputeSize(Files
.begin()+EndOfSource
,Files
.end());
663 // Build the status cache
664 pkgCacheGenerator
Gen(Map
.Get(),&Progress
);
665 if (_error
->PendingError() == true)
667 if (BuildCache(Gen
,Progress
,CurrentSize
,TotalSize
,
668 Files
.begin()+EndOfSource
,Files
.end()) == false)
673 TotalSize
= ComputeSize(Files
.begin(),Files
.end());
675 // Build the source cache
676 pkgCacheGenerator
Gen(Map
.Get(),&Progress
);
677 if (_error
->PendingError() == true)
679 if (BuildCache(Gen
,Progress
,CurrentSize
,TotalSize
,
680 Files
.begin(),Files
.begin()+EndOfSource
) == false)
684 if (Writeable
== true && SrcCacheFile
.empty() == false)
686 FileFd
SCacheF(SrcCacheFile
,FileFd::WriteEmpty
);
687 if (_error
->PendingError() == true)
689 // Write out the main data
690 if (SCacheF
.Write(Map
->Data(),Map
->Size()) == false)
691 return _error
->Error(_("IO Error saving source cache"));
694 // Write out the proper header
695 Gen
.GetCache().HeaderP
->Dirty
= false;
696 if (SCacheF
.Seek(0) == false ||
697 SCacheF
.Write(Map
->Data(),sizeof(*Gen
.GetCache().HeaderP
)) == false)
698 return _error
->Error(_("IO Error saving source cache"));
700 Gen
.GetCache().HeaderP
->Dirty
= true;
703 // Build the status cache
704 if (BuildCache(Gen
,Progress
,CurrentSize
,TotalSize
,
705 Files
.begin()+EndOfSource
,Files
.end()) == false)
709 if (_error
->PendingError() == true)
715 delete Map
.UnGuard();
716 *OutMap
= new MMap(*CacheF
,MMap::Public
| MMap::ReadOnly
);
720 *OutMap
= Map
.UnGuard();
727 // MakeOnlyStatusCache - Build a cache with just the status files /*{{{*/
728 // ---------------------------------------------------------------------
730 bool pkgMakeOnlyStatusCache(OpProgress
&Progress
,DynamicMMap
**OutMap
)
732 unsigned long MapSize
= _config
->FindI("APT::Cache-Limit",4*1024*1024);
733 vector
<pkgIndexFile
*> Files
;
734 unsigned long EndOfSource
= Files
.size();
735 if (_system
->AddStatusFiles(Files
) == false)
738 SPtr
<DynamicMMap
> Map
;
739 Map
= new DynamicMMap(MMap::Public
,MapSize
);
740 unsigned long CurrentSize
= 0;
741 unsigned long TotalSize
= 0;
743 TotalSize
= ComputeSize(Files
.begin()+EndOfSource
,Files
.end());
745 // Build the status cache
746 Progress
.OverallProgress(0,1,1,_("Reading Package Lists"));
747 pkgCacheGenerator
Gen(Map
.Get(),&Progress
);
748 if (_error
->PendingError() == true)
750 if (BuildCache(Gen
,Progress
,CurrentSize
,TotalSize
,
751 Files
.begin()+EndOfSource
,Files
.end()) == false)
754 if (_error
->PendingError() == true)
756 *OutMap
= Map
.UnGuard();