|
|
@@ -300,36 +300,35 @@ bool pkgCacheGenerator::MergeListPackage(ListParser &List, pkgCache::PkgIterator
|
|
|
|
|
|
for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
|
|
|
{
|
|
|
- pkgCache::DescIterator Desc = Ver.DescriptionList();
|
|
|
+ pkgCache::DescIterator VerDesc = Ver.DescriptionList();
|
|
|
|
|
|
// a version can only have one md5 describing it
|
|
|
- if (Desc.end() == true || MD5SumValue(Desc.md5()) != CurMd5)
|
|
|
+ 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(Desc, CurMd5, CurLang) == true)
|
|
|
+ if (IsDuplicateDescription(VerDesc, CurMd5, CurLang) == true)
|
|
|
continue;
|
|
|
|
|
|
+ pkgCache::DescIterator Desc;
|
|
|
Dynamic<pkgCache::DescIterator> DynDesc(Desc);
|
|
|
- // we add at the end, so that the start is constant as we need
|
|
|
- // that to be able to efficiently share these lists
|
|
|
- map_ptrloc *LastDesc = &Ver->DescriptionList;
|
|
|
- for (;Desc.end() == false && Desc->NextDesc != 0; ++Desc);
|
|
|
- if (Desc.end() == false)
|
|
|
- LastDesc = &Desc->NextDesc;
|
|
|
|
|
|
- void const * const oldMap = Map.Data();
|
|
|
- map_ptrloc const descindex = NewDescription(Desc, CurLang, CurMd5, *LastDesc);
|
|
|
+ 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);
|
|
|
- if (oldMap != Map.Data())
|
|
|
- LastDesc += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
|
|
|
- *LastDesc = descindex;
|
|
|
+
|
|
|
Desc->ParentPkg = Pkg.Index();
|
|
|
|
|
|
- if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
|
|
|
+ // 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;
|
|
|
+
|
|
|
+ if (NewFileDesc(Desc,List) == false)
|
|
|
return _error->Error(_("Error occurred while processing %s (%s%d)"),
|
|
|
Pkg.Name(), "NewFileDesc", 1);
|
|
|
|
|
|
@@ -391,7 +390,7 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
|
|
|
}
|
|
|
|
|
|
// Add a new version
|
|
|
- map_ptrloc const verindex = NewVersion(Ver,Version,*LastVer);
|
|
|
+ map_ptrloc const verindex = NewVersion(Ver, Version, Pkg.Index(), Hash, *LastVer);
|
|
|
if (verindex == 0 && _error->PendingError())
|
|
|
return _error->Error(_("Error occurred while processing %s (%s%d)"),
|
|
|
Pkg.Name(), "NewVersion", 1);
|
|
|
@@ -399,8 +398,6 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
|
|
|
if (oldMap != Map.Data())
|
|
|
LastVer += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
|
|
|
*LastVer = verindex;
|
|
|
- Ver->ParentPkg = Pkg.Index();
|
|
|
- Ver->Hash = Hash;
|
|
|
|
|
|
if (unlikely(List.NewVersion(Ver) == false))
|
|
|
return _error->Error(_("Error occurred while processing %s (%s%d)"),
|
|
|
@@ -464,11 +461,8 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
|
|
|
pkgCache::VerIterator ConVersion = D.ParentVer();
|
|
|
Dynamic<pkgCache::VerIterator> DynV(ConVersion);
|
|
|
// duplicate the Conflicts/Breaks/Replaces for :none arch
|
|
|
- if (D->Version == 0)
|
|
|
- NewDepends(Pkg, ConVersion, "", 0, D->Type, OldDepLast);
|
|
|
- else
|
|
|
- NewDepends(Pkg, ConVersion, D.TargetVer(),
|
|
|
- D->CompareOp, D->Type, OldDepLast);
|
|
|
+ NewDepends(Pkg, ConVersion, D->Version,
|
|
|
+ D->CompareOp, D->Type, OldDepLast);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -509,19 +503,16 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
|
|
|
// We haven't found reusable descriptions, so add the first description
|
|
|
pkgCache::DescIterator Desc = Ver.DescriptionList();
|
|
|
Dynamic<pkgCache::DescIterator> DynDesc(Desc);
|
|
|
- map_ptrloc *LastDesc = &Ver->DescriptionList;
|
|
|
|
|
|
- oldMap = Map.Data();
|
|
|
- map_ptrloc const descindex = NewDescription(Desc, CurLang, CurMd5, *LastDesc);
|
|
|
+ map_ptrloc const descindex = NewDescription(Desc, CurLang, CurMd5, 0);
|
|
|
if (unlikely(descindex == 0 && _error->PendingError()))
|
|
|
return _error->Error(_("Error occurred while processing %s (%s%d)"),
|
|
|
Pkg.Name(), "NewDescription", 2);
|
|
|
- if (oldMap != Map.Data())
|
|
|
- LastDesc += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
|
|
|
- *LastDesc = descindex;
|
|
|
+
|
|
|
Desc->ParentPkg = Pkg.Index();
|
|
|
+ Ver->DescriptionList = descindex;
|
|
|
|
|
|
- if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
|
|
|
+ if (NewFileDesc(Desc,List) == false)
|
|
|
return _error->Error(_("Error occurred while processing %s (%s%d)"),
|
|
|
Pkg.Name(), "NewFileDesc", 2);
|
|
|
|
|
|
@@ -564,7 +555,7 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List)
|
|
|
Dynamic<pkgCache::VerIterator> DynVer(Ver);
|
|
|
for (; Ver.end() == false; ++Ver)
|
|
|
{
|
|
|
- if (Ver->Hash == Hash && Version.c_str() == Ver.VerStr())
|
|
|
+ if (Ver->Hash == Hash && Version == Ver.VerStr())
|
|
|
{
|
|
|
if (List.CollectFileProvides(Cache,Ver) == false)
|
|
|
return _error->Error(_("Error occurred while processing %s (%s%d)"),
|
|
|
@@ -602,8 +593,11 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name)
|
|
|
|
|
|
// Insert it into the hash table
|
|
|
unsigned long const Hash = Cache.Hash(Name);
|
|
|
- Grp->Next = Cache.HeaderP->GrpHashTable[Hash];
|
|
|
- Cache.HeaderP->GrpHashTable[Hash] = Group;
|
|
|
+ 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;
|
|
|
+ *insertAt = Group;
|
|
|
|
|
|
Grp->ID = Cache.HeaderP->GroupCount++;
|
|
|
return true;
|
|
|
@@ -632,11 +626,14 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
|
|
|
// Insert the package into our package list
|
|
|
if (Grp->FirstPackage == 0) // the group is new
|
|
|
{
|
|
|
+ Grp->FirstPackage = Package;
|
|
|
// Insert it into the hash table
|
|
|
unsigned long const Hash = Cache.Hash(Name);
|
|
|
- Pkg->NextPackage = Cache.HeaderP->PkgHashTable[Hash];
|
|
|
- Cache.HeaderP->PkgHashTable[Hash] = Package;
|
|
|
- Grp->FirstPackage = Package;
|
|
|
+ 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 = Package;
|
|
|
}
|
|
|
else // Group the Packages together
|
|
|
{
|
|
|
@@ -675,6 +672,7 @@ bool pkgCacheGenerator::AddImplicitDepends(pkgCache::GrpIterator &G,
|
|
|
bool const coInstall = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same);
|
|
|
pkgCache::PkgIterator D = G.PackageList();
|
|
|
Dynamic<pkgCache::PkgIterator> DynD(D);
|
|
|
+ map_ptrloc const VerStrIdx = V->VerStr;
|
|
|
for (; D.end() != true; D = G.NextPkg(D))
|
|
|
{
|
|
|
if (Arch == D.Arch() || D->VersionList == 0)
|
|
|
@@ -685,16 +683,16 @@ bool pkgCacheGenerator::AddImplicitDepends(pkgCache::GrpIterator &G,
|
|
|
if (coInstall == true)
|
|
|
{
|
|
|
// Replaces: ${self}:other ( << ${binary:Version})
|
|
|
- NewDepends(D, V, V.VerStr(),
|
|
|
+ NewDepends(D, V, VerStrIdx,
|
|
|
pkgCache::Dep::Less, pkgCache::Dep::Replaces,
|
|
|
OldDepLast);
|
|
|
// Breaks: ${self}:other (!= ${binary:Version})
|
|
|
- NewDepends(D, V, V.VerStr(),
|
|
|
+ NewDepends(D, V, VerStrIdx,
|
|
|
pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks,
|
|
|
OldDepLast);
|
|
|
} else {
|
|
|
// Conflicts: ${self}:other
|
|
|
- NewDepends(D, V, "",
|
|
|
+ NewDepends(D, V, 0,
|
|
|
pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
|
|
|
OldDepLast);
|
|
|
}
|
|
|
@@ -711,17 +709,18 @@ bool pkgCacheGenerator::AddImplicitDepends(pkgCache::VerIterator &V,
|
|
|
bool const coInstall = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same);
|
|
|
if (coInstall == true)
|
|
|
{
|
|
|
+ map_ptrloc const VerStrIdx = V->VerStr;
|
|
|
// Replaces: ${self}:other ( << ${binary:Version})
|
|
|
- NewDepends(D, V, V.VerStr(),
|
|
|
+ NewDepends(D, V, VerStrIdx,
|
|
|
pkgCache::Dep::Less, pkgCache::Dep::Replaces,
|
|
|
OldDepLast);
|
|
|
// Breaks: ${self}:other (!= ${binary:Version})
|
|
|
- NewDepends(D, V, V.VerStr(),
|
|
|
+ NewDepends(D, V, VerStrIdx,
|
|
|
pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks,
|
|
|
OldDepLast);
|
|
|
} else {
|
|
|
// Conflicts: ${self}:other
|
|
|
- NewDepends(D, V, "",
|
|
|
+ NewDepends(D, V, 0,
|
|
|
pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
|
|
|
OldDepLast);
|
|
|
}
|
|
|
@@ -767,6 +766,8 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver,
|
|
|
/* This puts a version structure in the linked list */
|
|
|
unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
|
|
|
const string &VerStr,
|
|
|
+ map_ptrloc const ParentPkg,
|
|
|
+ unsigned long const Hash,
|
|
|
unsigned long Next)
|
|
|
{
|
|
|
// Get a structure
|
|
|
@@ -778,12 +779,37 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
|
|
|
Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version);
|
|
|
//Dynamic<pkgCache::VerIterator> DynV(Ver); // caller MergeListVersion already takes care of it
|
|
|
Ver->NextVer = Next;
|
|
|
+ Ver->ParentPkg = ParentPkg;
|
|
|
+ Ver->Hash = Hash;
|
|
|
Ver->ID = Cache.HeaderP->VersionCount++;
|
|
|
+
|
|
|
+ // try to find the version string in the group for reuse
|
|
|
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
|
|
|
+ pkgCache::GrpIterator Grp = Pkg.Group();
|
|
|
+ if (Pkg.end() == false && Grp.end() == false)
|
|
|
+ {
|
|
|
+ for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
|
|
|
+ {
|
|
|
+ if (Pkg == P)
|
|
|
+ continue;
|
|
|
+ for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
|
|
|
+ {
|
|
|
+ int const cmp = strcmp(V.VerStr(), VerStr.c_str());
|
|
|
+ if (cmp == 0)
|
|
|
+ {
|
|
|
+ Ver->VerStr = V->VerStr;
|
|
|
+ return Version;
|
|
|
+ }
|
|
|
+ else if (cmp < 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // haven't found the version string, so create
|
|
|
map_ptrloc const idxVerStr = WriteStringInMap(VerStr);
|
|
|
if (unlikely(idxVerStr == 0))
|
|
|
return 0;
|
|
|
Ver->VerStr = idxVerStr;
|
|
|
-
|
|
|
return Version;
|
|
|
}
|
|
|
/*}}}*/
|
|
|
@@ -825,9 +851,9 @@ bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc,
|
|
|
// ---------------------------------------------------------------------
|
|
|
/* This puts a description structure in the linked list */
|
|
|
map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
|
|
|
- const string &Lang,
|
|
|
- const MD5SumValue &md5sum,
|
|
|
- map_ptrloc Next)
|
|
|
+ const string &Lang,
|
|
|
+ const MD5SumValue &md5sum,
|
|
|
+ map_ptrloc idxmd5str)
|
|
|
{
|
|
|
// Get a structure
|
|
|
map_ptrloc const Description = AllocateInMap(sizeof(pkgCache::Description));
|
|
|
@@ -836,14 +862,21 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
|
|
|
|
|
|
// Fill it in
|
|
|
Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description);
|
|
|
- Desc->NextDesc = Next;
|
|
|
Desc->ID = Cache.HeaderP->DescriptionCount++;
|
|
|
- map_ptrloc const idxlanguage_code = WriteStringInMap(Lang);
|
|
|
- map_ptrloc const idxmd5sum = WriteStringInMap(md5sum.Value());
|
|
|
- if (unlikely(idxlanguage_code == 0 || idxmd5sum == 0))
|
|
|
+ map_ptrloc const idxlanguage_code = WriteUniqString(Lang);
|
|
|
+ if (unlikely(idxlanguage_code == 0))
|
|
|
return 0;
|
|
|
Desc->language_code = idxlanguage_code;
|
|
|
- Desc->md5sum = idxmd5sum;
|
|
|
+
|
|
|
+ if (idxmd5str != 0)
|
|
|
+ Desc->md5sum = idxmd5str;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ map_ptrloc const idxmd5sum = WriteStringInMap(md5sum.Value());
|
|
|
+ if (unlikely(idxmd5sum == 0))
|
|
|
+ return 0;
|
|
|
+ Desc->md5sum = idxmd5sum;
|
|
|
+ }
|
|
|
|
|
|
return Description;
|
|
|
}
|
|
|
@@ -858,35 +891,49 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
|
|
|
unsigned int const &Op,
|
|
|
unsigned int const &Type,
|
|
|
map_ptrloc* &OldDepLast)
|
|
|
+{
|
|
|
+ map_ptrloc index = 0;
|
|
|
+ if (Version.empty() == false)
|
|
|
+ {
|
|
|
+ int const CmpOp = Op & 0x0F;
|
|
|
+ // =-deps are used (79:1) for lockstep on same-source packages (e.g. data-packages)
|
|
|
+ if (CmpOp == pkgCache::Dep::Equals && strcmp(Version.c_str(), Ver.VerStr()) == 0)
|
|
|
+ index = Ver->VerStr;
|
|
|
+
|
|
|
+ if (index == 0)
|
|
|
+ {
|
|
|
+ void const * const oldMap = Map.Data();
|
|
|
+ index = WriteStringInMap(Version);
|
|
|
+ if (unlikely(index == 0))
|
|
|
+ return false;
|
|
|
+ if (OldDepLast != 0 && oldMap != Map.Data())
|
|
|
+ OldDepLast += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return NewDepends(Pkg, Ver, index, Op, Type, OldDepLast);
|
|
|
+}
|
|
|
+bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
|
|
|
+ pkgCache::VerIterator &Ver,
|
|
|
+ map_ptrloc const Version,
|
|
|
+ unsigned int const &Op,
|
|
|
+ unsigned int const &Type,
|
|
|
+ map_ptrloc* &OldDepLast)
|
|
|
{
|
|
|
void const * const oldMap = Map.Data();
|
|
|
// Get a structure
|
|
|
map_ptrloc const Dependency = AllocateInMap(sizeof(pkgCache::Dependency));
|
|
|
if (unlikely(Dependency == 0))
|
|
|
return false;
|
|
|
-
|
|
|
+
|
|
|
// Fill it in
|
|
|
pkgCache::DepIterator Dep(Cache,Cache.DepP + Dependency);
|
|
|
Dynamic<pkgCache::DepIterator> DynDep(Dep);
|
|
|
Dep->ParentVer = Ver.Index();
|
|
|
Dep->Type = Type;
|
|
|
Dep->CompareOp = Op;
|
|
|
+ Dep->Version = Version;
|
|
|
Dep->ID = Cache.HeaderP->DependsCount++;
|
|
|
|
|
|
- // Probe the reverse dependency list for a version string that matches
|
|
|
- if (Version.empty() == false)
|
|
|
- {
|
|
|
-/* for (pkgCache::DepIterator I = Pkg.RevDependsList(); I.end() == false; I++)
|
|
|
- if (I->Version != 0 && I.TargetVer() == Version)
|
|
|
- Dep->Version = I->Version;*/
|
|
|
- if (Dep->Version == 0) {
|
|
|
- map_ptrloc const index = WriteStringInMap(Version);
|
|
|
- if (unlikely(index == 0))
|
|
|
- return false;
|
|
|
- Dep->Version = index;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// Link it to the package
|
|
|
Dep->Package = Pkg.Index();
|
|
|
Dep->NextRevDepends = Pkg->RevDepends;
|