X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/88a8975f156e452d9f3ebe76822b236e8962ebba..5f1b8fadbba7108ba20bd07c7479eb5e5704308e:/apt-pkg/pkgcache.cc diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 9d3929cd9..347a0954e 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include /*}}}*/ @@ -57,7 +58,7 @@ pkgCache::Header::Header() /* Whenever the structures change the major version should be bumped, whenever the generator changes the minor version should be bumped. */ APT_HEADER_SET(MajorVersion, 10); - APT_HEADER_SET(MinorVersion, 0); + APT_HEADER_SET(MinorVersion, 3); APT_HEADER_SET(Dirty, false); APT_HEADER_SET(HeaderSz, sizeof(pkgCache::Header)); @@ -93,7 +94,7 @@ pkgCache::Header::Header() VerSysName = 0; Architecture = 0; SetArchitectures(0); - SetHashTableSize(_config->FindI("APT::Cache-HashTableSize", 10 * 1048)); + SetHashTableSize(_config->FindI("APT::Cache-HashTableSize", 15013)); memset(Pools,0,sizeof(Pools)); CacheFileSize = 0; @@ -173,9 +174,6 @@ bool pkgCache::ReMap(bool const &Errorchecks) HeaderP->CheckSizes(DefHeader) == false) return _error->Error(_("The package cache file is an incompatible version")); - if (Map.Size() < HeaderP->CacheFileSize) - return _error->Error(_("The package cache file is corrupted, it is too small")); - if (HeaderP->VerSysName == 0 || HeaderP->Architecture == 0 || HeaderP->GetArchitectures() == 0) return _error->Error(_("The package cache file is corrupted")); @@ -193,6 +191,13 @@ bool pkgCache::ReMap(bool const &Errorchecks) list != StrP + HeaderP->GetArchitectures()) return _error->Error(_("The package cache was built for different architectures: %s vs %s"), StrP + HeaderP->GetArchitectures(), list.c_str()); + + auto hash = CacheHash(); + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "Opened cache with hash " << hash << ", expecting " << HeaderP->CacheFileSize << "\n"; + if (hash != HeaderP->CacheFileSize) + return _error->Error(_("The package cache file is corrupted, it has the wrong hash")); + return true; } /*}}}*/ @@ -203,38 +208,43 @@ bool pkgCache::ReMap(bool const &Errorchecks) table (480 used items) */ map_id_t pkgCache::sHash(const string &Str) const { - unsigned long Hash = 0; + uint32_t Hash = 5381; for (string::const_iterator I = Str.begin(); I != Str.end(); ++I) - Hash = 41 * Hash + tolower_ascii(*I); + Hash = 33 * Hash + tolower_ascii(*I); return Hash % HeaderP->GetHashTableSize(); } map_id_t pkgCache::sHash(const char *Str) const { - unsigned long Hash = tolower_ascii(*Str); - for (const char *I = Str + 1; *I != 0; ++I) - Hash = 41 * Hash + tolower_ascii(*I); + uint32_t Hash = 5381; + for (const char *I = Str; *I != 0; ++I) + Hash = 33 * Hash + tolower_ascii(*I); return Hash % HeaderP->GetHashTableSize(); } - /*}}}*/ -// Cache::SingleArchFindPkg - Locate a package by name /*{{{*/ -// --------------------------------------------------------------------- -/* Returns 0 on error, pointer to the package otherwise - The multiArch enabled methods will fallback to this one as it is (a bit) - faster for single arch environments and realworld is mostly singlearch… */ -pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name) + +uint32_t pkgCache::CacheHash() { - // Look at the hash bucket - Package *Pkg = PkgP + HeaderP->PkgHashTableP()[Hash(Name)]; - for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage) - { - int const cmp = strcmp(Name.c_str(), StrP + (GrpP + Pkg->Group)->Name); - if (cmp == 0) - return PkgIterator(*this, Pkg); - else if (cmp < 0) - break; + pkgCache::Header header = {}; + uLong adler = adler32(0L, Z_NULL, 0); + + if (Map.Size() < sizeof(header)) + return adler; + memcpy(&header, GetMap().Data(), sizeof(header)); + + header.Dirty = false; + header.CacheFileSize = 0; + + adler = adler32(adler, + reinterpret_cast(&header), + sizeof(header)); + + if (Map.Size() > sizeof(header)) { + adler = adler32(adler, + static_cast(GetMap().Data()) + sizeof(header), + GetMap().Size() - sizeof(header)); } - return PkgIterator(*this,0); + + return adler; } /*}}}*/ // Cache::FindPkg - Locate a package by name /*{{{*/ @@ -245,9 +255,9 @@ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { if (found == string::npos) return FindPkg(Name, "native"); string const Arch = Name.substr(found+1); - /* Beware: This is specialcased to handle pkg:any in dependencies as - these are linked to virtual pkg:any named packages with all archs. - If you want any arch from a given pkg, use FindPkg(pkg,arch) */ + /* Beware: This is specialcased to handle pkg:any in dependencies + as these are linked to virtual pkg:any named packages. + If you want any arch from a pkg, use FindPkg(pkg,"any") */ if (Arch == "any") return FindPkg(Name, "any"); return FindPkg(Name.substr(0, found), Arch); @@ -329,7 +339,7 @@ const char *pkgCache::DepType(unsigned char Type) /* */ const char *pkgCache::Priority(unsigned char Prio) { - const char *Mapping[] = {0,_("important"),_("required"),_("standard"), + const char *Mapping[] = {0,_("required"),_("important"),_("standard"), _("optional"),_("extra")}; if (Prio < _count(Mapping)) return Mapping[Prio]; @@ -344,20 +354,11 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const { return PkgIterator(*Owner, 0); /* If we accept any package we simply return the "first" - package in this group (the last one added). */ + package in this group */ if (Arch == "any") return PkgIterator(*Owner, Owner->PkgP + S->FirstPackage); - - char const* const myArch = Owner->NativeArch(); - /* Most of the time the package for our native architecture is - the one we add at first to the cache, but this would be the - last one we check, so we do it now. */ - if (Arch == "native" || Arch == myArch || Arch == "all") { - pkgCache::Package *Pkg = Owner->PkgP + S->LastPackage; - if (strcmp(myArch, Owner->StrP + Pkg->Arch) == 0) - return PkgIterator(*Owner, Pkg); - Arch = myArch; - } + if (Arch == "native" || Arch == "all") + Arch = Owner->NativeArch(); // Iterate over the list to find the matching arch for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP; @@ -546,7 +547,7 @@ std::string pkgCache::PkgIterator::FullName(bool const &Pretty) const { string fullname = Name(); if (Pretty == false || - (strcmp(Arch(), "all") != 0 && + (strcmp(Arch(), "all") != 0 && strcmp(Arch(), "any") != 0 && strcmp(Owner->NativeArch(), Arch()) != 0)) return fullname.append(":").append(Arch()); return fullname;