// Starting header
*Cache.HeaderP = pkgCache::Header();
+
+ // make room for the hashtables for packages and groups
+ if (Map.RawAllocate(2 * (Cache.HeaderP->HashTableSize * sizeof(map_ptrloc))) == 0)
+ return;
+
map_ptrloc const idxVerSysName = WriteStringInMap(_system->VS->Label);
+ if (unlikely(idxVerSysName == 0))
+ return;
Cache.HeaderP->VerSysName = idxVerSysName;
// this pointer is set in ReMap, but we need it now for WriteUniqString
Cache.StringItemP = (pkgCache::StringItem *)Map.Data();
map_ptrloc const idxArchitecture = WriteUniqString(_config->Find("APT::Architecture"));
- Cache.HeaderP->Architecture = idxArchitecture;
- if (unlikely(idxVerSysName == 0 || idxArchitecture == 0))
+ if (unlikely(idxArchitecture == 0))
return;
+ Cache.HeaderP->Architecture = idxArchitecture;
+
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ if (archs.size() > 1)
+ {
+ std::vector<std::string>::const_iterator a = archs.begin();
+ std::string list = *a;
+ for (++a; a != archs.end(); ++a)
+ list.append(",").append(*a);
+ map_ptrloc const idxArchitectures = WriteStringInMap(list);
+ if (unlikely(idxArchitectures == 0))
+ return;
+ Cache.HeaderP->Architectures = idxArchitectures;
+ }
+ else
+ Cache.HeaderP->Architectures = idxArchitecture;
+
Cache.ReMap();
}
else
{
_error->Error(_("Cache has an incompatible versioning system"));
return;
- }
+ }
}
-
+
Cache.HeaderP->Dirty = true;
Map.Sync(0,sizeof(pkgCache::Header));
}
// Find the right version to write the description
MD5SumValue CurMd5 = List.Description_md5();
- if (CurMd5.Value().empty() == true || List.Description().empty() == true)
+ if (CurMd5.Value().empty() == true && List.Description("").empty() == true)
return true;
- std::string CurLang = List.DescriptionLanguage();
-
+ std::vector<std::string> availDesc = List.AvailableDescriptionLanguages();
for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
{
pkgCache::DescIterator VerDesc = Ver.DescriptionList();
if (VerDesc.end() == true || MD5SumValue(VerDesc.md5()) != CurMd5)
continue;
- // don't add a new description if we have one for the given
- // md5 && language
- if (IsDuplicateDescription(VerDesc, CurMd5, CurLang) == true)
- continue;
-
- pkgCache::DescIterator Desc;
- Dynamic<pkgCache::DescIterator> DynDesc(Desc);
-
- map_ptrloc const descindex = NewDescription(Desc, CurLang, CurMd5, VerDesc->md5sum);
- if (unlikely(descindex == 0 && _error->PendingError()))
- return _error->Error(_("Error occurred while processing %s (%s%d)"),
- Pkg.Name(), "NewDescription", 1);
-
- Desc->ParentPkg = Pkg.Index();
-
- // we add at the end, so that the start is constant as we need
- // that to be able to efficiently share these lists
- VerDesc = Ver.DescriptionList(); // old value might be invalid after ReMap
- for (;VerDesc.end() == false && VerDesc->NextDesc != 0; ++VerDesc);
- map_ptrloc * const LastNextDesc = (VerDesc.end() == true) ? &Ver->DescriptionList : &VerDesc->NextDesc;
- *LastNextDesc = descindex;
+ map_ptrloc md5idx = VerDesc->md5sum;
+ for (std::vector<std::string>::const_iterator CurLang = availDesc.begin(); CurLang != availDesc.end(); ++CurLang)
+ {
+ // don't add a new description if we have one for the given
+ // md5 && language
+ if (IsDuplicateDescription(VerDesc, CurMd5, *CurLang) == true)
+ continue;
- if (NewFileDesc(Desc,List) == false)
- return _error->Error(_("Error occurred while processing %s (%s%d)"),
- Pkg.Name(), "NewFileDesc", 1);
+ AddNewDescription(List, Ver, *CurLang, CurMd5, md5idx);
+ }
// we can stop here as all "same" versions will share the description
break;
map_ptrloc *LastVer = &Pkg->VersionList;
void const * oldMap = Map.Data();
- unsigned long const Hash = List.VersionHash();
+ unsigned short const Hash = List.VersionHash();
if (Ver.end() == false)
{
/* We know the list is sorted so we use that fact in the search.
if (Res > 0)
break;
// Versionstrings are equal - is hash also equal?
- if (Res == 0 && Ver->Hash == Hash)
+ if (Res == 0 && List.SameVersion(Hash, Ver) == true)
break;
// proceed with the next till we have either the right
// or we found another version (which will be lower)
return true;
}
- /* Record the Description (it is not translated) */
+ /* Record the Description(s) based on their master md5sum */
MD5SumValue CurMd5 = List.Description_md5();
- if (CurMd5.Value().empty() == true || List.Description().empty() == true)
+ if (CurMd5.Value().empty() == true && List.Description("").empty() == true)
return true;
- std::string CurLang = List.DescriptionLanguage();
/* Before we add a new description we first search in the group for
a version with a description of the same MD5 - if so we reuse this
for (pkgCache::VerIterator V = P.VersionList();
V.end() == false; ++V)
{
- if (IsDuplicateDescription(V.DescriptionList(), CurMd5, "") == false)
+ if (V->DescriptionList == 0 || MD5SumValue(V.DescriptionList().md5()) != CurMd5)
continue;
Ver->DescriptionList = V->DescriptionList;
- return true;
}
}
- // We haven't found reusable descriptions, so add the first description
- pkgCache::DescIterator Desc = Ver.DescriptionList();
+ // We haven't found reusable descriptions, so add the first description(s)
+ map_ptrloc md5idx = Ver->DescriptionList == 0 ? 0 : Ver.DescriptionList()->md5sum;
+ std::vector<std::string> availDesc = List.AvailableDescriptionLanguages();
+ for (std::vector<std::string>::const_iterator CurLang = availDesc.begin(); CurLang != availDesc.end(); ++CurLang)
+ if (AddNewDescription(List, Ver, *CurLang, CurMd5, md5idx) == false)
+ return false;
+ return true;
+}
+ /*}}}*/
+bool pkgCacheGenerator::AddNewDescription(ListParser &List, pkgCache::VerIterator &Ver, std::string const &lang, MD5SumValue const &CurMd5, map_ptrloc &md5idx) /*{{{*/
+{
+ pkgCache::DescIterator Desc;
Dynamic<pkgCache::DescIterator> DynDesc(Desc);
- map_ptrloc const descindex = NewDescription(Desc, CurLang, CurMd5, 0);
+ map_ptrloc const descindex = NewDescription(Desc, lang, CurMd5, md5idx);
if (unlikely(descindex == 0 && _error->PendingError()))
return _error->Error(_("Error occurred while processing %s (%s%d)"),
- Pkg.Name(), "NewDescription", 2);
+ Ver.ParentPkg().Name(), "NewDescription", 1);
- Desc->ParentPkg = Pkg.Index();
- Ver->DescriptionList = descindex;
+ md5idx = Desc->md5sum;
+ Desc->ParentPkg = Ver.ParentPkg().Index();
+
+ // we add at the end, so that the start is constant as we need
+ // that to be able to efficiently share these lists
+ pkgCache::DescIterator VerDesc = Ver.DescriptionList(); // old value might be invalid after ReMap
+ for (;VerDesc.end() == false && VerDesc->NextDesc != 0; ++VerDesc);
+ map_ptrloc * const LastNextDesc = (VerDesc.end() == true) ? &Ver->DescriptionList : &VerDesc->NextDesc;
+ *LastNextDesc = descindex;
if (NewFileDesc(Desc,List) == false)
return _error->Error(_("Error occurred while processing %s (%s%d)"),
- Pkg.Name(), "NewFileDesc", 2);
+ Ver.ParentPkg().Name(), "NewFileDesc", 1);
return true;
}
if (Counter % 100 == 0 && Progress != 0)
Progress->Progress(List.Offset());
- unsigned long Hash = List.VersionHash();
+ unsigned short Hash = List.VersionHash();
pkgCache::VerIterator Ver = Pkg.VersionList();
Dynamic<pkgCache::VerIterator> DynVer(Ver);
for (; Ver.end() == false; ++Ver)
{
- if (Ver->Hash == Hash && Version == Ver.VerStr())
+ if (List.SameVersion(Hash, Ver) == true && Version == Ver.VerStr())
{
if (List.CollectFileProvides(Cache,Ver) == false)
return _error->Error(_("Error occurred while processing %s (%s%d)"),
// Insert it into the hash table
unsigned long const Hash = Cache.Hash(Name);
- map_ptrloc *insertAt = &Cache.HeaderP->GrpHashTable[Hash];
+ map_ptrloc *insertAt = &Cache.HeaderP->GrpHashTable()[Hash];
while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + *insertAt)->Name) > 0)
insertAt = &(Cache.GrpP + *insertAt)->Next;
Grp->Next = *insertAt;
Grp->FirstPackage = Package;
// Insert it into the hash table
unsigned long const Hash = Cache.Hash(Name);
- map_ptrloc *insertAt = &Cache.HeaderP->PkgHashTable[Hash];
+ map_ptrloc *insertAt = &Cache.HeaderP->PkgHashTable()[Hash];
while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.PkgP + *insertAt)->Name) > 0)
- insertAt = &(Cache.PkgP + *insertAt)->NextPackage;
- Pkg->NextPackage = *insertAt;
+ insertAt = &(Cache.PkgP + *insertAt)->Next;
+ Pkg->Next = *insertAt;
*insertAt = Package;
}
else // Group the Packages together
{
// this package is the new last package
pkgCache::PkgIterator LastPkg(Cache, Cache.PkgP + Grp->LastPackage);
- Pkg->NextPackage = LastPkg->NextPackage;
- LastPkg->NextPackage = Package;
+ Pkg->Next = LastPkg->Next;
+ LastPkg->Next = Package;
}
Grp->LastPackage = Package;
return true;
}
/*}}}*/
+bool pkgCacheGenerator::ListParser::SameVersion(unsigned short const Hash,/*{{{*/
+ pkgCache::VerIterator const &Ver)
+{
+ return Hash == Ver->Hash;
+}
+ /*}}}*/
// CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/
// ---------------------------------------------------------------------
/* This is used to select which file is to be associated with all newly